├── .cproject ├── .dir-locals.el ├── .gitattributes ├── .github └── workflows │ └── asciidoctor-docs.yml ├── .gitignore ├── .project ├── .travis.yml ├── .vscode └── launch.json ├── CMakeLists.txt ├── CTestConfig.cmake ├── ConfigureChecks.cmake ├── DefineOptions.cmake ├── INSTALL.md ├── LICENSE ├── Makefile ├── README.md ├── cgreen-config-version.cmake.in ├── cgreen-config.cmake.in ├── cmake └── Modules │ ├── COPYING-CMAKE-SCRIPTS │ ├── CodeCoverage.cmake │ ├── DefineCMakeDefaults.cmake │ ├── DefineCPackConfig.cmake │ ├── DefineCompilerFlags.cmake │ ├── DefineRelativeFilePaths.cmake │ ├── FindAsciidoc.cmake │ ├── FindAsciidoctor.cmake │ ├── FindNm.cmake │ ├── FindValgrind.cmake │ ├── MacroAddCompileFlags.cmake │ ├── MacroAddLinkFlags.cmake │ ├── MacroAddPlugin.cmake │ ├── MacroAddTest.cmake │ ├── MacroAddUnitTest.cmake │ ├── MacroAddValgrindTest.cmake │ ├── MacroCopyFile.cmake │ ├── MacroEnsureOutOfSourceBuild.cmake │ └── UseDoxygen.cmake ├── config.h.cmake ├── contrib ├── README.contrib ├── SCons │ └── SConstruct ├── android │ └── Android.mk ├── cgreen-mocker │ ├── .gitignore │ ├── Makefile │ ├── cgreen-mocker.py │ ├── complex_types.h │ ├── complex_types.mock.expected │ ├── double.h │ ├── double.mock.expected │ ├── multiple_types.h │ ├── multiple_types.mock.expected │ ├── requirements.txt │ ├── simple_types.h │ └── simple_types.mock.expected ├── rpm │ └── cgreen.spec └── upgrade │ └── upgrade.sh ├── debian ├── README.deb ├── control └── triggers ├── doc ├── .gitignore ├── CMakeLists.txt ├── README ├── README.asciidoc ├── avtar.png ├── cgreen-guide-en-docinfo.html ├── cgreen-guide-en-docinfo.xml ├── cgreen-guide-en.asciidoc ├── cgreen_asciidoc.conf ├── cheat-sheet.md ├── doxy.config.in ├── logo.odt ├── logo.pdf ├── logo.png ├── man │ ├── man1 │ │ ├── cgreen-debug.1 │ │ └── cgreen-runner.1 │ └── man5 │ │ └── cgreen.5 └── tutorial_src │ ├── .gitignore │ ├── Makefile │ ├── README │ ├── all_tests.c │ ├── constraints.out │ ├── constraints1.out │ ├── constraints2.out │ ├── crash1.out │ ├── crash2.out │ ├── crash3.out │ ├── crash_tests.c │ ├── crash_tests1.c │ ├── crash_tests2.c │ ├── crash_tests3.c │ ├── custom_constraint1.c │ ├── custom_constraint1.out │ ├── custom_constraint2.c │ ├── custom_constraint2.out │ ├── custom_constraint3.c │ ├── custom_constraint3.out │ ├── double1.out │ ├── double_tests1.c │ ├── first0.out │ ├── first1.out │ ├── first_tests0.c │ ├── first_tests1.c │ ├── first_tests2.c │ ├── formatter0.out │ ├── formatter1.out │ ├── formatter2.out │ ├── formatter3.out │ ├── formatter4.out │ ├── formatter5.out │ ├── formatter6.out │ ├── formatter_tests0.c │ ├── formatter_tests1.c │ ├── formatter_tests2.c │ ├── formatter_tests3.c │ ├── formatter_tests4.c │ ├── formatter_tests5.c │ ├── learning_mocks.c │ ├── multiple_streams1.c │ ├── multiple_streams1.out │ ├── multiple_streams2.c │ ├── multiple_streams2.out │ ├── person.h │ ├── person_tests.c │ ├── read_paragraph1.c │ ├── read_paragraph2.c │ ├── read_paragraph3.c │ ├── roman_tests.c │ ├── runner1.out │ ├── runner2.out │ ├── runner3.out │ ├── schema1.out │ ├── schema2.out │ ├── schema_tests1.c │ ├── schema_tests2.c │ ├── set_contents.c │ ├── set_field.c │ ├── side_effect.c │ ├── stream.c │ ├── stream.h │ ├── stream0.out │ ├── stream1.c │ ├── stream1.out │ ├── stream2.c │ ├── stream2.out │ ├── stream3.out │ ├── stream4.out │ ├── stream5.out │ ├── stream6.out │ ├── stream_tests0.c │ ├── stream_tests1.c │ ├── stream_tests2.c │ ├── stream_tests3.c │ ├── stream_tests4.c │ ├── strlen1.out │ ├── strlen2.out │ ├── strlen3.out │ ├── strlen4.out │ ├── strlen5.out │ ├── strlen6.out │ ├── strlen7.out │ ├── strlen_tests1.c │ ├── strlen_tests2.c │ ├── strlen_tests3.c │ ├── strlen_tests4.c │ ├── strlen_tests5.c │ ├── strlen_tests6.c │ ├── strlen_tests7.c │ ├── struct_parameters.c │ ├── suite1.c │ ├── suite1.out │ ├── suite_person_tests.c │ ├── suite_strlen_tests.c │ ├── test_as_xml0.c │ ├── test_as_xml0.out │ ├── test_as_xml1.c │ ├── test_as_xml1.out │ ├── test_as_xml2.out │ ├── test_as_xml3.out │ ├── test_as_xml4.out │ ├── words.c │ ├── words.h │ ├── words0.out │ ├── words1.c │ ├── words1.out │ ├── words2.c │ ├── words2.out │ ├── words3.c │ ├── words3.out │ ├── words4.c │ ├── words4.out │ ├── words5.c │ ├── words5.out │ ├── words6.c │ ├── words6.out │ ├── words7.c │ ├── words7.out │ ├── words8.out │ ├── words9.out │ ├── words_tests0.c │ ├── words_tests1.c │ ├── words_tests2.c │ ├── words_tests3.c │ ├── words_tests4.c │ ├── xml_reporter.c │ ├── xml_reporter.h │ ├── xml_reporter0.c │ ├── xml_reporter1.c │ ├── xml_reporter2.c │ ├── xml_reporter3.c │ └── xml_reporter4.c ├── fatify ├── gitrevision.h.in ├── include ├── CMakeLists.txt └── cgreen │ ├── CMakeLists.txt │ ├── assertions.h │ ├── boxed_double.h │ ├── breadcrumb.h │ ├── cdash_reporter.h │ ├── cgreen.h │ ├── cgreen_value.h │ ├── constraint.h │ ├── constraint_syntax_helpers.h │ ├── cpp_assertions.h │ ├── cpp_constraint.h │ ├── cute_reporter.h │ ├── filename.h │ ├── internal │ ├── CMakeLists.txt │ ├── android_headers │ │ └── androidcompat.h │ ├── assertions_internal.h │ ├── c_assertions.h │ ├── cgreen_pipe.h │ ├── cgreen_time.h │ ├── cpp_assertions.h │ ├── function_macro.h │ ├── mock_table.h │ ├── mocks_internal.h │ ├── runner_platform.h │ ├── stringify_token.h │ ├── suite_internal.h │ ├── unit_implementation.h │ └── windows_headers │ │ ├── inttypes.h │ │ ├── stdbool.h │ │ ├── unistd.h │ │ └── wincompat.h │ ├── legacy.h │ ├── message_formatting.h │ ├── messaging.h │ ├── mocks.h │ ├── reporter.h │ ├── runner.h │ ├── string_comparison.h │ ├── suite.h │ ├── text_reporter.h │ ├── unit.h │ ├── vector.h │ └── xml_reporter.h ├── linux-setup.sh ├── samples ├── CMakeLists.txt ├── Makefile └── sample.c ├── setup.sh ├── src ├── CMakeLists.txt ├── Makefile ├── assertions.c ├── boxed_double.c ├── breadcrumb.c ├── cdash_reporter.c ├── cdash_reporter_internal.h ├── cgreen_time.c ├── cgreen_value.c ├── cgreen_value_internal.h ├── constraint.c ├── constraint_internal.h ├── cpp_assertions.cpp ├── cpp_constraint.cpp ├── cute_reporter.c ├── cute_reporter_internal.h ├── libxml_reporter.c ├── libxml_reporter_internal.h ├── local_messaging.cpp ├── memory.c ├── memory.h ├── message_formatting.c ├── messaging.c ├── mocks.c ├── parameters.c ├── parameters.h ├── posix_cgreen_pipe.c ├── posix_cgreen_time.c ├── posix_runner_platform.c ├── reporter.c ├── runner.c ├── runner.h ├── string_comparison.c ├── suite.c ├── text_reporter.c ├── text_reporter_internal.h ├── utils.c ├── utils.h ├── vector.c ├── win32_cgreen.h ├── win32_cgreen_pipe.c ├── win32_cgreen_time.c ├── win32_runner_platform.c ├── xml_reporter.c └── xml_reporter_internal.h ├── tests ├── .gitignore ├── CMakeLists.txt ├── CTestCustom.cmake ├── Makefile ├── accept_output_for ├── all_c_tests.c ├── all_cpp_tests.cpp ├── api │ ├── CMakeLists.txt │ ├── cgreen_api.expected │ ├── core_api.c │ ├── suites_with_context_api.c │ └── suites_without_context_api.c ├── assertion_messages_tests.c ├── assertion_messages_tests.expected ├── assertion_tests.c ├── assertion_tests.cpp ├── breadcrumb_tests.c ├── breadcrumb_tests.cpp ├── cdash_reporter_tests.c ├── cdash_reporter_tests.cpp ├── cgreen_value_tests.c ├── cgreen_value_tests.cpp ├── constraint_messages_tests.c ├── constraint_messages_tests.expected ├── constraint_tests.c ├── constraint_tests.cpp ├── cpp_assertion_tests.cpp ├── custom_constraint_messages_tests.c ├── custom_constraint_messages_tests.expected ├── cute_reporter_tests.c ├── cute_reporter_tests.cpp ├── double_tests.c ├── double_tests.cpp ├── environment_variables_tests.c ├── environment_variables_tests.cpp ├── failure_messages_tests.c ├── failure_messages_tests.expected ├── ignore_messages_tests.c ├── ignore_messages_tests.expected ├── libxml_output_tests.c ├── libxml_output_tests.expected ├── libxml_reporter_tests.c ├── libxml_reporter_tests.cpp ├── message_formatting_tests.c ├── message_formatting_tests.cpp ├── messaging_tests.c ├── messaging_tests.cpp ├── mock_messages_tests.c ├── mock_messages_tests.expected ├── mocks_struct_tests.c ├── mocks_struct_tests.cpp ├── mocks_tests.c ├── mocks_tests.cpp ├── multiple_suite_tests.c ├── multiple_suite_tests.cpp ├── normalize_assertion_messages_tests.sed ├── normalize_constraint_messages_tests.sed ├── normalize_custom_constraint_messages_tests.sed ├── normalize_failure_messages_tests.sed ├── normalize_ignore_messages_tests.sed ├── normalize_libxml_output_tests.sed ├── normalize_mock_messages_tests.sed ├── normalize_xml_output_tests.sed ├── parameters_tests.c ├── parameters_tests.cpp ├── reflective_runner_no_teardown_tests.c ├── reflective_runner_no_teardown_tests.cpp ├── reflective_tests.c ├── reflective_tests.cpp ├── text_reporter_tests.c ├── text_reporter_tests.cpp ├── unit_tests.c ├── unit_tests.cpp ├── utils_tests.c ├── vector_tests.c ├── vector_tests.cpp ├── xml_output_tests.c ├── xml_output_tests.expected ├── xml_reporter_tests.c └── xml_reporter_tests.cpp └── tools ├── .gitignore ├── CMakeLists.txt ├── Makefile ├── TODO ├── build_mock_table.pl ├── cgreen-debug ├── cgreen-debug.argbash ├── cgreen-runner.c ├── cgreen_completion.bash ├── cgreen_libxml_output_diff ├── cgreen_runner_output_diff ├── cgreen_xml_output_diff ├── discoverer.c ├── discoverer.h ├── discoverer.mock ├── discoverer_acceptance_tests.c ├── discoverer_unit_tests.c ├── gopt-errors.c ├── gopt.c ├── gopt.h ├── io.c ├── io.h ├── io.mock ├── runner.c ├── runner.h ├── runner_unit_test_runner.c ├── runner_unit_tests.c ├── test_item.c └── test_item.h /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((c-mode . ( 2 | (indent-tabs-mode . nil) 3 | (c-basic-offset . 4) 4 | ) 5 | ) 6 | ) 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.github/workflows/asciidoctor-docs.yml: -------------------------------------------------------------------------------- 1 | name: asciidoctor-docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | # This workflow contains a single job called "build" 10 | build: 11 | # The type of runner that the job will run on 12 | runs-on: ubuntu-latest 13 | 14 | # Steps represent a sequence of tasks that will be executed as part of the job 15 | steps: 16 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 17 | - uses: actions/checkout@v3 18 | 19 | # Includes the AsciiDoctor GitHub Pages Action to convert adoc files to html and publish to gh-pages branch 20 | - name: asciidoctor-ghpages 21 | uses: manoelcampos/asciidoctor-ghpages-action@v2.2.4 22 | with: 23 | asciidoctor_params: -r asciidoctor-diagram -a VERSION=1.6.0 24 | source_dir: doc 25 | post_build: git add -f *.png 26 | adoc_file_ext: .asciidoc 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .idea 3 | .cache 4 | CMakeCache.txt 5 | CMakeFiles 6 | Testing 7 | *.exe 8 | *.stackdump 9 | *.so 10 | build-stamp 11 | configure-stamp 12 | *~ 13 | #*# 14 | .#* 15 | bin 16 | lib 17 | valgrind.log 18 | gitrevision.h 19 | .cgreen-debug-commands -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Cgreen C tests", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/tests/test_cgreen_c", 12 | "args": [], 13 | "stopAtEntry": true, 14 | "cwd": "${workspaceFolder}", 15 | "MIMode": "lldb" 16 | //"miDebuggerPath": "/opt/clang+llvm-15.0.6-arm64-apple-darwin21.0//bin/lldb-vscode" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /CTestConfig.cmake: -------------------------------------------------------------------------------- 1 | ## This file should be placed in the root directory of your project. 2 | ## Then modify the CMakeLists.txt file in the root directory of your 3 | ## project to incorporate the testing dashboard. 4 | ## # The following are required to uses Dart and the Cdash dashboard 5 | ## ENABLE_TESTING() 6 | ## INCLUDE(CTest) 7 | set(CTEST_PROJECT_NAME "CGreen") 8 | set(CTEST_NIGHTLY_START_TIME "00:00:00 EST") 9 | 10 | set(CTEST_DROP_METHOD "http") 11 | set(CTEST_DROP_SITE "my.cdash.org") 12 | set(CTEST_DROP_LOCATION "/submit.php?project=CGreen") 13 | set(CTEST_DROP_SITE_CDASH TRUE) 14 | -------------------------------------------------------------------------------- /ConfigureChecks.cmake: -------------------------------------------------------------------------------- 1 | include(CheckIncludeFile) 2 | include(CheckSymbolExists) 3 | include(CheckFunctionExists) 4 | include(CheckLibraryExists) 5 | include(CheckTypeSize) 6 | include(CheckCXXSourceCompiles) 7 | 8 | set(PACKAGE ${APPLICATION_NAME}) 9 | set(VERSION ${APPLICATION_VERSION}) 10 | set(DATADIR ${DATA_INSTALL_DIR}) 11 | set(LIBDIR ${LIB_INSTALL_DIR}) 12 | set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}") 13 | set(SYSCONFDIR ${SYSCONF_INSTALL_DIR}) 14 | -------------------------------------------------------------------------------- /DefineOptions.cmake: -------------------------------------------------------------------------------- 1 | option(CGREEN_WITH_STATIC_LIBRARY "Build with a static library" OFF) 2 | option(CGREEN_WITH_UNIT_TESTS "Build unit tests" ON) 3 | option(CGREEN_INTERNAL_WITH_GCOV "Build with test coverage instrumentation" OFF) 4 | mark_as_advanced(CGREEN_INTERNAL_WITH_GCOV) 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) [year], [fullname] 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /cgreen-config-version.cmake.in: -------------------------------------------------------------------------------- 1 | set(PACKAGE_VERSION "@APPLICATION_VERSION_MAJOR@.@APPLICATION_VERSION_MINOR@.@APPLICATION_VERSION_PATCH@") 2 | 3 | # Check whether the requested PACKAGE_FIND_VERSION is compatible 4 | if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") 5 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 6 | else() 7 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 8 | if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") 9 | set(PACKAGE_VERSION_EXACT TRUE) 10 | endif() 11 | endif() 12 | -------------------------------------------------------------------------------- /cgreen-config.cmake.in: -------------------------------------------------------------------------------- 1 | # - Config file for the cgreen package 2 | # It defines the following variables 3 | # CGREEN_CMAKE_DIR - include directories for cgreen 4 | # CGREEN_INCLUDE_DIRS - include directories for cgreen 5 | # CGREEN_LIBRARIES - libraries to link against 6 | # CGREEN_EXECUTABLE - the cgreen executable 7 | 8 | get_filename_component( CGREEN_CMAKE_DIRS "${CMAKE_CURRENT_LIST_FILE}" PATH ) 9 | 10 | # leave this up to cmake 11 | find_path(CGREEN_INCLUDE_DIRS NAMES cgreen/cgreen.h) 12 | 13 | set( CGREEN_LIBRARIES cgreen ) 14 | set( CGREEN_EXECUTABLE cgreen-runner ) 15 | 16 | -------------------------------------------------------------------------------- /cmake/Modules/COPYING-CMAKE-SCRIPTS: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions 3 | are met: 4 | 5 | 1. Redistributions of source code must retain the copyright 6 | notice, this list of conditions and the following disclaimer. 7 | 2. Redistributions in binary form must reproduce the copyright 8 | notice, this list of conditions and the following disclaimer in the 9 | documentation and/or other materials provided with the distribution. 10 | 3. The name of the author may not be used to endorse or promote products 11 | derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /cmake/Modules/DefineCMakeDefaults.cmake: -------------------------------------------------------------------------------- 1 | # Always include srcdir and builddir in include path 2 | # This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in 3 | # about every subdir 4 | # since cmake 2.4.0 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | 7 | # Put the include dirs which are in the source or build tree 8 | # before all other include dirs, so the headers in the sources 9 | # are prefered over the already installed ones 10 | # since cmake 2.4.1 11 | set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) 12 | 13 | # Use colored output 14 | # since cmake 2.4.0 15 | set(CMAKE_COLOR_MAKEFILE ON) 16 | 17 | # Define the generic version of the libraries here 18 | set(GENERIC_LIB_VERSION "0.1.0") 19 | set(GENERIC_LIB_SOVERSION "0") 20 | 21 | # Set the default build type to release with debug info 22 | if (NOT CMAKE_BUILD_TYPE) 23 | set(CMAKE_BUILD_TYPE RelWithDebInfo 24 | CACHE STRING 25 | "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." 26 | ) 27 | endif (NOT CMAKE_BUILD_TYPE) 28 | -------------------------------------------------------------------------------- /cmake/Modules/DefineRelativeFilePaths.cmake: -------------------------------------------------------------------------------- 1 | # Source: https://stackoverflow.com/questions/237542/getting-base-name-of-the-source-file-at-compile-time 2 | 3 | function (cmake_define_relative_file_paths SOURCES) 4 | foreach (SOURCE IN LISTS SOURCES) 5 | file ( 6 | RELATIVE_PATH RELATIVE_SOURCE_PATH 7 | ${PROJECT_SOURCE_DIR} ${SOURCE} 8 | ) 9 | 10 | set_source_files_properties ( 11 | ${SOURCE} PROPERTIES 12 | COMPILE_DEFINITIONS FILENAME="${RELATIVE_SOURCE_PATH}" 13 | ) 14 | endforeach () 15 | endfunction () 16 | -------------------------------------------------------------------------------- /cmake/Modules/FindAsciidoc.cmake: -------------------------------------------------------------------------------- 1 | # - Find Asciidoc 2 | # this module looks for asciidoc and a2x 3 | # 4 | # ASCIIDOC_EXECUTABLE - the full path to asciidoc 5 | # ASCIIDOC_FOUND - If false, don't attempt to use asciidoc. 6 | # A2X_EXECUTABLE - the full path to a2x 7 | # A2X_FOUND - If false, don't attempt to use a2x. 8 | 9 | 10 | FIND_PROGRAM(ASCIIDOC_EXECUTABLE 11 | asciidoc 12 | ) 13 | 14 | MARK_AS_ADVANCED( 15 | ASCIIDOC_EXECUTABLE 16 | ) 17 | 18 | IF (NOT ASCIIDOC_EXECUTABLE) 19 | SET(ASCIIDOC_FOUND "NO") 20 | ELSE (NOT ASCIIDOC_EXECUTABLE) 21 | SET(ASCIIDOC_FOUND "YES") 22 | ENDIF (NOT ASCIIDOC_EXECUTABLE) 23 | 24 | 25 | IF (NOT ASCIIDOC_FOUND AND Asciidoc_FIND_REQUIRED) 26 | MESSAGE(FATAL_ERROR "Could not find asciidoc") 27 | ENDIF (NOT ASCIIDOC_FOUND AND Asciidoc_FIND_REQUIRED) 28 | 29 | FIND_PROGRAM(A2X_EXECUTABLE 30 | a2x 31 | ) 32 | 33 | MARK_AS_ADVANCED( 34 | A2X_EXECUTABLE 35 | ) 36 | 37 | IF (NOT A2X_EXECUTABLE) 38 | SET(A2X_FOUND "NO") 39 | ELSE (NOT A2X_EXECUTABLE) 40 | SET(A2X_FOUND "YES") 41 | ENDIF (NOT A2X_EXECUTABLE) 42 | 43 | 44 | IF (NOT A2X_FOUND AND A2x_FIND_REQUIRED) 45 | MESSAGE(FATAL_ERROR "Could not find a2x") 46 | ENDIF (NOT A2X_FOUND AND A2x_FIND_REQUIRED) 47 | -------------------------------------------------------------------------------- /cmake/Modules/FindAsciidoctor.cmake: -------------------------------------------------------------------------------- 1 | # Find Asciidoctor - a better AsciiDoc 2 | # 3 | # ASCIIDOCTOR_FOUND 4 | # ASCIIDOCTORPDF_FOUND 5 | # ASCIIDOCTOR_EXECUTABLE 6 | # ASCIIDOCTORPDF_EXECUTABLE 7 | 8 | FIND_PROGRAM(ASCIIDOCTOR_EXECUTABLE asciidoctor) 9 | FIND_PROGRAM(ASCIIDOCTORPDF_EXECUTABLE asciidoctor-pdf) 10 | 11 | MARK_AS_ADVANCED(ASCIIDOCTOR_EXECUTABLE) 12 | MARK_AS_ADVANCED(ASCIIDOCTORPDF_EXECUTABLE) 13 | 14 | IF (NOT ASCIIDOCTOR_EXECUTABLE) 15 | SET(ASCIIDOCTOR_FOUND "NO") 16 | ELSE (NOT ASCIIDOCTOR_EXECUTABLE) 17 | SET(ASCIIDOCTOR_FOUND "YES") 18 | ENDIF (NOT ASCIIDOCTOR_EXECUTABLE) 19 | 20 | IF (NOT ASCIIDOCTORPDF_EXECUTABLE) 21 | SET(ASCIIDOCTORPDF_FOUND "NO") 22 | ELSE (NOT ASCIIDOCTORPDF_EXECUTABLE) 23 | SET(ASCIIDOCTORPDF_FOUND "YES") 24 | ENDIF (NOT ASCIIDOCTORPDF_EXECUTABLE) 25 | 26 | IF (NOT ASCIIDOCTOR_FOUND AND ASCIIDOCTOR_FIND_REQUIRED) 27 | MESSAGE(FATAL_ERROR "Could not find asciidoctor") 28 | ENDIF (NOT ASCIIDOCTOR_FOUND AND ASCIIDOCTOR_FIND_REQUIRED) 29 | 30 | IF (NOT ASCIIDOCTORPDF_FOUND AND ASCIIDOCTOR_FIND_REQUIRED) 31 | MESSAGE(FATAL_ERROR "Could not find asciidoctor-pdf") 32 | ENDIF (NOT ASCIIDOCTORPDF_FOUND AND ASCIIDOCTOR_FIND_REQUIRED) 33 | 34 | -------------------------------------------------------------------------------- /cmake/Modules/FindNm.cmake: -------------------------------------------------------------------------------- 1 | find_program(NM_EXECUTABLE nm) 2 | 3 | if (NM_EXECUTABLE) 4 | set(NM_FOUND TRUE) 5 | endif() 6 | -------------------------------------------------------------------------------- /cmake/Modules/FindValgrind.cmake: -------------------------------------------------------------------------------- 1 | if (NOT Valgrind_FOUND) 2 | 3 | find_program(Valgrind_EXECUTABLE valgrind) 4 | 5 | include(FindPackageHandleStandardArgs) 6 | find_package_handle_standard_args(Valgrind DEFAULT_MSG Valgrind_EXECUTABLE) 7 | 8 | set(Valgrind_FOUND ${Valgrind_FOUND} CACHE BOOL "Flag whether Valgrind package was found") 9 | mark_as_advanced(Valgrind_FOUND Valgrind_EXECUTABLE) 10 | 11 | endif() 12 | -------------------------------------------------------------------------------- /cmake/Modules/MacroAddCompileFlags.cmake: -------------------------------------------------------------------------------- 1 | # - MACRO_ADD_COMPILE_FLAGS(target_name flag1 ... flagN) 2 | 3 | # Copyright (c) 2006, Oswald Buddenhagen, 4 | # Copyright (c) 2006, Andreas Schneider, 5 | # 6 | # Redistribution and use is allowed according to the terms of the BSD license. 7 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 8 | 9 | 10 | macro (MACRO_ADD_COMPILE_FLAGS _target) 11 | 12 | get_target_property(_flags ${_target} COMPILE_FLAGS) 13 | if (_flags) 14 | set(_flags ${_flags} ${ARGN}) 15 | else (_flags) 16 | set(_flags ${ARGN}) 17 | endif (_flags) 18 | 19 | set_target_properties(${_target} PROPERTIES COMPILE_FLAGS ${_flags}) 20 | 21 | endmacro (MACRO_ADD_COMPILE_FLAGS) 22 | -------------------------------------------------------------------------------- /cmake/Modules/MacroAddLinkFlags.cmake: -------------------------------------------------------------------------------- 1 | # - MACRO_ADD_LINK_FLAGS(target_name flag1 ... flagN) 2 | 3 | # Copyright (c) 2006, Oswald Buddenhagen, 4 | # Copyright (c) 2006, Andreas Schneider, 5 | # 6 | # Redistribution and use is allowed according to the terms of the BSD license. 7 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 8 | 9 | macro (MACRO_ADD_LINK_FLAGS _target) 10 | 11 | get_target_property(_flags ${_target} LINK_FLAGS) 12 | if (_flags) 13 | set(_flags "${_flags} ${ARGN}") 14 | else (_flags) 15 | set(_flags "${ARGN}") 16 | endif (_flags) 17 | 18 | set_target_properties(${_target} PROPERTIES LINK_FLAGS "${_flags}") 19 | 20 | endmacro (MACRO_ADD_LINK_FLAGS) 21 | -------------------------------------------------------------------------------- /cmake/Modules/MacroAddPlugin.cmake: -------------------------------------------------------------------------------- 1 | # - MACRO_ADD_PLUGIN(name [WITH_PREFIX] file1 .. fileN) 2 | # 3 | # Create a plugin from the given source files. 4 | # If WITH_PREFIX is given, the resulting plugin will have the 5 | # prefix "lib", otherwise it won't. 6 | # 7 | # Copyright (c) 2006, Alexander Neundorf, 8 | # Copyright (c) 2006, Laurent Montel, 9 | # Copyright (c) 2006, Andreas Schneider, 10 | # 11 | # Redistribution and use is allowed according to the terms of the BSD license. 12 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 13 | 14 | 15 | macro (MACRO_ADD_PLUGIN _target_NAME _with_PREFIX) 16 | 17 | if (${_with_PREFIX} STREQUAL "WITH_PREFIX") 18 | set(_first_SRC) 19 | else (${_with_PREFIX} STREQUAL "WITH_PREFIX") 20 | set(_first_SRC ${_with_PREFIX}) 21 | endif (${_with_PREFIX} STREQUAL "WITH_PREFIX") 22 | 23 | add_library(${_target_NAME} MODULE ${_first_SRC} ${ARGN}) 24 | 25 | if (_first_SRC) 26 | set_target_properties(${_target_NAME} PROPERTIES PREFIX "") 27 | endif (_first_SRC) 28 | 29 | endmacro (MACRO_ADD_PLUGIN _name _sources) 30 | 31 | -------------------------------------------------------------------------------- /cmake/Modules/MacroAddTest.cmake: -------------------------------------------------------------------------------- 1 | # - MACRO_ADD_TEST() 2 | # 3 | # Calls add_test() with all the but if on Win32 or Cygwin also adds the 4 | # directory where the Cgreen library is generated to the path so that it will 5 | # be used when running the test 6 | # 7 | # @thoni56/Thomas Nilefalk 2015-09-13 8 | 9 | macro (macro_add_test) 10 | add_test(${ARGN}) 11 | if (CYGWIN OR WIN32) 12 | set_tests_properties(${ARGV1} PROPERTIES ENVIRONMENT PATH=${PROJECT_BINARY_DIR}/src:$ENV{PATH}) 13 | endif () 14 | endmacro(macro_add_test) 15 | -------------------------------------------------------------------------------- /cmake/Modules/MacroAddUnitTest.cmake: -------------------------------------------------------------------------------- 1 | # - MACRO_ADD_UNIT_TEST(test_name test_source linklib1 ... linklibN) 2 | 3 | # Copyright (c) 2007, Daniel Gollub, 4 | # Copyright (c) 2007, Andreas Schneider, 5 | # 6 | # Redistribution and use is allowed according to the terms of the BSD license. 7 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 8 | 9 | enable_testing() 10 | include(CTest) 11 | 12 | #set(CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags") 13 | #set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags") 14 | #set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags") 15 | #set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags") 16 | 17 | # custom options 18 | configure_file(tests/CTestCustom.cmake ${PROJECT_BINARY_DIR}/CTestCustom.cmake COPYONLY) 19 | 20 | macro (MACRO_ADD_UNIT_TEST _testName _testSource) 21 | add_executable(${_testName} ${_testSource}) 22 | target_link_libraries(${_testName} ${ARGN}) 23 | macro_add_test(NAME ${_testName} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${_testName}) 24 | endmacro (MACRO_ADD_UNIT_TEST) 25 | -------------------------------------------------------------------------------- /cmake/Modules/MacroAddValgrindTest.cmake: -------------------------------------------------------------------------------- 1 | # - MACRO_ADD_VALGRIND_TEST() 2 | # 3 | # Calls add_test() with all the but if on Win32 or Cygwin also adds the 4 | # directory where the Cgreen library is generated to the path so that it will 5 | # be used when running the test 6 | # 7 | # @thoni56/Thomas Nilefalk 2015-09-13 8 | 9 | macro (macro_add_valgrind_test) 10 | if (Valgrind_FOUND) 11 | set( 12 | libname 13 | ${CMAKE_FIND_LIBRARY_PREFIXES}${ARGN}${CMAKE_SHARED_LIBRARY_SUFFIX} 14 | ) 15 | add_test( 16 | NAME valgrind_${libname} 17 | COMMAND sh -c "LD_LIBRARY_PATH=build/src valgrind --leak-check=full tools/cgreen-runner ${CMAKE_CURRENT_BINARY_DIR}/${libname} 2>1&" 18 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 19 | ) 20 | set_tests_properties( 21 | valgrind_${libname} PROPERTIES 22 | FAIL_REGULAR_EXPRESSION "(definitely|indirectly|possibly) lost: [1-9]" 23 | ) 24 | if (CYGWIN OR WIN32) 25 | set_tests_properties(${ARGV1} PROPERTIES ENVIRONMENT PATH=${PROJECT_BINARY_DIR}/src:$ENV{PATH}) 26 | endif () 27 | endif () 28 | endmacro(macro_add_valgrind_test) 29 | -------------------------------------------------------------------------------- /cmake/Modules/MacroCopyFile.cmake: -------------------------------------------------------------------------------- 1 | # - macro_copy_file(_src _dst) 2 | # Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst} 3 | # 4 | # Example: 5 | # macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/icon.png ${CMAKE_CURRENT_BINARY_DIR}/.) 6 | # Copies file icon.png to ${CMAKE_CURRENT_BINARY_DIR} directory 7 | # 8 | # Copyright (c) 2006-2007 Wengo 9 | # Copyright (c) 2006-2008 Andreas Schneider 10 | # 11 | # Redistribution and use is allowed according to the terms of the BSD license. 12 | # For details see the accompanying COPYING file. 13 | 14 | 15 | macro (macro_copy_file _src _dst) 16 | # Removes all path containing .svn or CVS or CMakeLists.txt during the copy 17 | if (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*") 18 | 19 | if (CMAKE_VERBOSE_MAKEFILE) 20 | message(STATUS "Copy file from ${_src} to ${_dst}") 21 | endif (CMAKE_VERBOSE_MAKEFILE) 22 | 23 | # Creates directory if necessary 24 | get_filename_component(_path ${_dst} PATH) 25 | file(MAKE_DIRECTORY ${_path}) 26 | 27 | execute_process( 28 | COMMAND 29 | ${CMAKE_COMMAND} -E copy_if_different ${_src} ${_dst} 30 | OUTPUT_QUIET 31 | ) 32 | endif (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*") 33 | endmacro (macro_copy_file) 34 | -------------------------------------------------------------------------------- /cmake/Modules/MacroEnsureOutOfSourceBuild.cmake: -------------------------------------------------------------------------------- 1 | # - MACRO_ENSURE_OUT_OF_SOURCE_BUILD() 2 | # MACRO_ENSURE_OUT_OF_SOURCE_BUILD() 3 | 4 | # Copyright (c) 2006, Alexander Neundorf, 5 | # 6 | # Redistribution and use is allowed according to the terms of the BSD license. 7 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 8 | 9 | macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage) 10 | 11 | string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}" _insource) 12 | if (_insource) 13 | message(SEND_ERROR "${_errorMessage}") 14 | message(FATAL_ERROR "Remove the file CMakeCache.txt in ${PROJECT_SOURCE_DIR} first.") 15 | endif (_insource) 16 | 17 | endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD) 18 | -------------------------------------------------------------------------------- /config.h.cmake: -------------------------------------------------------------------------------- 1 | /* Name of package */ 2 | #cmakedefine PACKAGE "${APPLICATION_NAME}" 3 | 4 | /* Version number of package */ 5 | #cmakedefine VERSION "${APPLICATION_VERSION}" 6 | 7 | #cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}" 8 | #cmakedefine DATADIR "${DATADIR}" 9 | #cmakedefine LIBDIR "${LIBDIR}" 10 | #cmakedefine PLUGINDIR "${PLUGINDIR}" 11 | #cmakedefine SYSCONFDIR "${SYSCONFDIR}" 12 | 13 | /************************** HEADER FILES *************************/ 14 | 15 | 16 | /*************************** FUNCTIONS ***************************/ 17 | 18 | 19 | /*************************** LIBRARIES ***************************/ 20 | 21 | 22 | /**************************** OPTIONS ****************************/ 23 | 24 | /* Define if building with gcov instrumentation */ 25 | #cmakedefine CGREEN_INTERNAL_WITH_GCOV 26 | 27 | -------------------------------------------------------------------------------- /contrib/README.contrib: -------------------------------------------------------------------------------- 1 | All files under this contrib directory are UNSUPPORTED. There were 2 | provided by users of Cgreen and were not tested by the authors of Cgreen. 3 | Use at your own risk. 4 | 5 | SCons/ by Kevin Fitch 6 | Add a sample demonstrating using cgreen with SCons 7 | http://www.scons.org/ 8 | 9 | upgrade/ by Thomas Nilsson and Colm Dougan 10 | Will upgrade a pre-beta version of tests to newer API 11 | -------------------------------------------------------------------------------- /contrib/SCons/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment() 2 | 3 | # Add the cgreen headers to the include path 4 | env.Append(CPPPATH=['../../include', ]) 5 | 6 | # Build the cgreen library 7 | cgreendir = '../../src/' 8 | cgreenfiles = """unit.c messaging.c breadcrumb.c reporter.c 9 | assertions.c vector.c mocks.c constraint.c 10 | parameters.c text_reporter.c""".split() 11 | cgreensources = ['../../src/'+f for f in cgreenfiles] 12 | cgreenlib = env.StaticLibrary('cgreen', cgreensources) 13 | 14 | #Build our code to be tested 15 | env.Append(CPPPATH=['include']) 16 | mainlib = env.StaticLibrary('main', env.Glob('src/*.c')) 17 | 18 | for test in env.Glob('tests/*.c'): 19 | testprog = env.Program(test, LIBS=[cgreenlib, mainlib]) 20 | 21 | # This is a nasty little hack here. 22 | # We run the test twice, the first time is so we can see the output on the 23 | # console, and get the results logged. Unfortunately it will not cause the 24 | # build to stop on test failures since the result of the command is the 25 | # return value of tee, not the tests. So we run it again to catch the 26 | # possibly failed return value ... those tests better be repeatable! 27 | env.Command(testprog[0].path+'.results', testprog, 28 | '$SOURCE 2>&1 | tee $TARGET') 29 | env.Command(testprog[0].path+'.results_', testprog, 30 | '$SOURCE > $TARGET 2>&1 ') 31 | 32 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/.gitignore: -------------------------------------------------------------------------------- 1 | double.mock 2 | complex_types.mock 3 | pycparser 4 | .vscode 5 | *.mock 6 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @echo "Testing..." 3 | @echo -n "double... " 4 | @./cgreen-mocker.py double.h > double.mock 5 | @diff double.mock double.mock.expected 6 | @if [ "$$?" -eq 0 ] ; then echo "Ok" ; fi 7 | @echo -n "complex_types... " 8 | @./cgreen-mocker.py complex_types.h > complex_types.mock 9 | @diff complex_types.mock complex_types.mock.expected 10 | @if [ "$$?" -eq 0 ] ; then echo "Ok" ; fi 11 | @echo -n "simple_types... " 12 | @./cgreen-mocker.py simple_types.h > simple_types.mock 13 | @diff simple_types.mock simple_types.mock.expected 14 | @if [ "$$?" -eq 0 ] ; then echo "Ok" ; fi 15 | @echo -n "multiple_types... " 16 | @./cgreen-mocker.py multiple_types.h > multiple_types.mock 17 | @diff multiple_types.mock multiple_types.mock.expected 18 | @if [ "$$?" -eq 0 ] ; then echo "Ok" ; fi 19 | @echo -n "multiple_args... " 20 | @./cgreen-mocker.py -Da=b -Dc=d multiple_types.h > multiple_args.mock 21 | @diff multiple_args.mock multiple_types.mock.expected 22 | @if [ "$$?" -eq 0 ] ; then echo "Ok" ; fi 23 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/complex_types.h: -------------------------------------------------------------------------------- 1 | typedef struct BasicStruct { 2 | int someValue; 3 | } BasicStruct; 4 | 5 | typedef BasicStruct* BasicStructPtr; 6 | 7 | BasicStruct return_struct_by_value(int i); 8 | BasicStructPtr return_pointer_to_struct(char string[]); 9 | BasicStruct* direct_return_pointer_to_struct(void); 10 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/complex_types.mock.expected: -------------------------------------------------------------------------------- 1 | /* -*- c -*-*/ 2 | #include "complex_types.h" 3 | #include 4 | 5 | BasicStruct return_struct_by_value(int i) { 6 | return *(BasicStruct *) mock(i); 7 | } 8 | 9 | BasicStructPtr return_pointer_to_struct(char string[]) { 10 | return (BasicStructPtr) mock(string); 11 | } 12 | 13 | BasicStruct *direct_return_pointer_to_struct(void) { 14 | return (BasicStruct *) mock(); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/double.h: -------------------------------------------------------------------------------- 1 | double return_double(double d, int i); 2 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/double.mock.expected: -------------------------------------------------------------------------------- 1 | /* -*- c -*-*/ 2 | #include "double.h" 3 | #include 4 | 5 | double return_double(double d, int i) { 6 | return unbox_double(mock(box_double(d), i); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/multiple_types.h: -------------------------------------------------------------------------------- 1 | typedef struct Struct1 { 2 | int someValue; 3 | } Struct1; 4 | 5 | typedef Struct1* Struct1Ptr; 6 | 7 | Struct1 return_struct1_by_value(int i); 8 | Struct1Ptr return_pointer_to_struct1(char string[]); 9 | Struct1* direct_return_pointer_to_struct1(void); 10 | 11 | typedef struct Struct2 { 12 | int someValue; 13 | } Struct2; 14 | 15 | typedef Struct2* Struct2Ptr; 16 | 17 | Struct2 return_struct2_by_value(int i); 18 | Struct2Ptr return_pointer_to_struct2(char string[]); 19 | Struct2* direct_return_pointer_to_struct2(void); 20 | 21 | extern void return_nothing(void); 22 | extern int return_int(int ints[]); 23 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/multiple_types.mock.expected: -------------------------------------------------------------------------------- 1 | /* -*- c -*-*/ 2 | #include "multiple_types.h" 3 | #include 4 | 5 | Struct1 return_struct1_by_value(int i) { 6 | return *(Struct1 *) mock(i); 7 | } 8 | 9 | Struct1Ptr return_pointer_to_struct1(char string[]) { 10 | return (Struct1Ptr) mock(string); 11 | } 12 | 13 | Struct1 *direct_return_pointer_to_struct1(void) { 14 | return (Struct1 *) mock(); 15 | } 16 | 17 | Struct2 return_struct2_by_value(int i) { 18 | return *(Struct2 *) mock(i); 19 | } 20 | 21 | Struct2Ptr return_pointer_to_struct2(char string[]) { 22 | return (Struct2Ptr) mock(string); 23 | } 24 | 25 | Struct2 *direct_return_pointer_to_struct2(void) { 26 | return (Struct2 *) mock(); 27 | } 28 | 29 | void return_nothing(void) { 30 | mock(); 31 | } 32 | 33 | int return_int(int ints[]) { 34 | return (int) mock(ints); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/requirements.txt: -------------------------------------------------------------------------------- 1 | pycparser 2 | packaging 3 | 4 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/simple_types.h: -------------------------------------------------------------------------------- 1 | int return_int(void); 2 | char return_char(char c); 3 | char* return_pointer_to_char(char *string); 4 | -------------------------------------------------------------------------------- /contrib/cgreen-mocker/simple_types.mock.expected: -------------------------------------------------------------------------------- 1 | /* -*- c -*-*/ 2 | #include "simple_types.h" 3 | #include 4 | 5 | int return_int(void) { 6 | return (int) mock(); 7 | } 8 | 9 | char return_char(char c) { 10 | return (char) mock(c); 11 | } 12 | 13 | char *return_pointer_to_char(char *string) { 14 | return (char *) mock(string); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /contrib/upgrade/upgrade.sh: -------------------------------------------------------------------------------- 1 | # Perl-script to upgrade from pre-beta versions 2 | # Initial version by Colm Dougan, contributed by Thomas Nilsson 3 | perl -pi -e 's/\bEnsure\s+(\w+)\s*\(\)/Ensure($1)/' $@ 4 | perl -pi -e 's/\bEnsure\s+(\w+)\s*\(void\)/Ensure($1)/' $@ 5 | perl -pi -e 's/\bfail\(\)/fail("expected exception")/' $@ 6 | perl -pi -e 's/\bexpect_call/expect/' $@ 7 | perl -pi -e 's/\bwant\((\w+), ([^)]+)/when($1, is_equal_to($2)/' $@ 8 | perl -pi -e 's/\bwill_respond\((\w+),\ ([^,\)]+)/expect($1, will_return($2)/' $@ 9 | perl -pi -e 's/\bwill_return\((\w+),\ ([^,\)]+)/expect($1, will_return($2)/' $@ 10 | perl -pi -e 's/\bwant_non_null_?\(\"(\w+)\"\)/when($1, is_non_null)/' $@ 11 | perl -pi -e 's/\bsetup\(/set_setup(/g' $@ 12 | perl -pi -e 's/\bteardown\(/set_teardown(/g' $@ 13 | perl -pi -e 's/\bexpect_never\(/never_expect(/g' $@ 14 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: cgreen 2 | Section: devel 3 | Priority: optional 4 | Maintainer: Thomas Nilefalk 5 | Depends: libc6 6 | Homepage: https://github.com/cgreen-devs/cgreen 7 | Package: cgreen1 8 | Version: 1.6.2 9 | Architecture: amd64 10 | Description: Unit tests and mocking framework for C and C++ 11 | A modern unit test and mocking framework for C and C++. Cgreen features 12 | - fast build, clean code, highly portable 13 | - simple auto-discovery of tests 14 | - fluent, expressive and readable API 15 | - each test runs in isolation to prevent cross-test dependencies 16 | - built-in mocking for C, compatible other C++ mocking libraries 17 | -------------------------------------------------------------------------------- /debian/triggers: -------------------------------------------------------------------------------- 1 | activate-noawait ldconfig 2 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | cgreen-guide-en.html 2 | html_chunks 3 | -------------------------------------------------------------------------------- /doc/README.asciidoc: -------------------------------------------------------------------------------- 1 | // Converted to index.html by asciidoctor-ghpages GitHub Action 2 | = Cgreen documentation 3 | 4 | - link:cgreen-guide-en.html[The Guide] 5 | - link:cheat-sheet.html[Cheat Sheet] 6 | 7 | 8 | -------------------------------------------------------------------------------- /doc/avtar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/doc/avtar.png -------------------------------------------------------------------------------- /doc/cgreen-guide-en-docinfo.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | Thomas 9 | Nilefalk 10 | thomas@junovagen.se 11 | 12 | 13 | 14 | Marcus 15 | Baker 16 | lastcraft 17 | marcus@lastcraft.com 18 | 19 | 20 | 21 | João 22 | Freitas 23 | joaohf 24 | joaohf@gmail.com 25 | 26 | 27 | 28 | 29 | Cgreen Unit Test for C/C++ language 30 | 31 | 32 | 2009-2012 33 | Cgreen Team 34 | 35 | 36 | 37 | Permission to use, copy, modify and distribute. 38 | 39 | 40 | 41 | The copyright holders make no representation about the suitability of 42 | this document for any purpose. It is provided 43 | as is without expressed or implied warranty. 44 | 45 | -------------------------------------------------------------------------------- /doc/cgreen-guide-en-docinfo.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | Marcus 9 | Baker 10 | lastcraft 11 | marcus@lastcraft.com 12 | 13 | 14 | 15 | João 16 | Freitas 17 | joaohf 18 | joaohf@gmail.com 19 | 20 | 21 | 22 | Thomas 23 | Nilefalk 24 | thoni56 25 | thomas@junovagen.se 26 | 27 | 28 | 29 | 30 | Cgreen Unit Test for C language 31 | 32 | 33 | 2012 34 | Cgreen Team 35 | 36 | 37 | 38 | Permission to use, copy, modify and distribute. 39 | 40 | 41 | 42 | The copyright holders make no representation about the suitability of 43 | this document for any purpose. It is provided 44 | as is without expressed or implied warranty. 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /doc/cgreen_asciidoc.conf: -------------------------------------------------------------------------------- 1 | [attributes] 2 | toclevels=3 3 | numbered= 4 | -------------------------------------------------------------------------------- /doc/logo.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/doc/logo.odt -------------------------------------------------------------------------------- /doc/logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/doc/logo.pdf -------------------------------------------------------------------------------- /doc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/doc/logo.png -------------------------------------------------------------------------------- /doc/man/man1/cgreen-debug.1: -------------------------------------------------------------------------------- 1 | .TH CGREEN-DEBUG 1 2 | 3 | .SH NAME 4 | cgreen-debug \- start cgreen-runner under a debugger and break at a specific test 5 | 6 | .SH SYNOPSIS 7 | .B cgreen\-debug 8 | [\fI\,OPTION\/\fR...] 9 | \fILIBRARY\fR \fITEST\fR 10 | 11 | 12 | .SH DESCRIPTION 13 | .B cgreen-debug 14 | is a script to start cgreen-runner under a debugger (primarily gdb), load a \fILIBRARY\fR 15 | and break on a named \fITEST\fR. Where \fILIBRARY\fR is a filename of the shared library of 16 | Cgreen tests, usually .so, .dll or .dylib, depending on your platform. \fITEST\fR is the 17 | name of a test in that library in the format :. 18 | 19 | .SS OPTIONS 20 | .TP 21 | .B "\-h, \-\-help" 22 | Print some usage information and exit. 23 | 24 | .TP 25 | .B "\-d, \-\-debugger" debugger 26 | Instead of default (gdb) use 27 | .I debugger 28 | as the debugger. Allowed values are "gdb", "cgdb", "lldb". 29 | 30 | .SH "SEE ALSO" 31 | cgreen(5) 32 | cgreen-runner(1) 33 | 34 | .PP 35 | The full documentation for 36 | .B cgreen-debug 37 | and 38 | .B the Cgreen framework 39 | is in the 40 | .B Cgreen 41 | manual available at 42 | .UR https://cgreen-devs.github.io/ 43 | GitHub 44 | .UE . 45 | -------------------------------------------------------------------------------- /doc/man/man5/cgreen.5: -------------------------------------------------------------------------------- 1 | .mso www.tmac 2 | .TH CGREEN 5 3 | .SH NAME 4 | cgreen \- a framework for C and C++ unit tests and mocking 5 | .SH DESCRIPTION 6 | .B Cgreen 7 | is a framework for creating and running compact and easy-to-read 8 | unittests for C and/or C++. 9 | 10 | Here are some of its features: 11 | 12 | .IP \[bu] 2 13 | Fluent API resulting in very readable tests 14 | .IP \[bu] 15 | Expressive and clear output using the default reporter 16 | .IP \[bu] 17 | Fully functional mocks, both strict and loose 18 | .IP \[bu] 19 | Each test runs in its own process for test suite robustness 20 | .IP \[bu] 21 | Automatic discovery and running of tests using dynamic library inspection 22 | .IP \[bu] 23 | Extensive and expressive constraints for many datatypes 24 | .IP \[bu] 25 | BDD-flavoured test declarations with Before and After declarations 26 | .IP \[bu] 27 | Extensible reporting mechanism 28 | .IP \[bu] 29 | Fully composable test suites 30 | .IP \[bu] 31 | An isolated test can be run in a single process for debugging 32 | 33 | 34 | .SH "SEE ALSO" 35 | cgreen-runner(1) 36 | .PP 37 | The full documentation for 38 | .B cgreen-runner 39 | and 40 | .B the Cgreen framework 41 | is in the 42 | .B Cgreen 43 | manual available at 44 | .URL https://github.com/cgreen-devs/cgreen GitHub . 45 | -------------------------------------------------------------------------------- /doc/tutorial_src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.exe 4 | *.stackdump 5 | *.out 6 | constraints 7 | constraints1 8 | constraints2 9 | crash1 10 | crash2 11 | crash3 12 | double1 13 | first0 14 | first1 15 | schema1 16 | schema2 17 | strlen1 18 | strlen2 19 | strlen3 20 | strlen4 21 | strlen5 22 | strlen6 23 | strlen7 24 | side_effect 25 | suite1 26 | test_as_xml0 27 | test_as_xml1 28 | test_as_xml2 29 | test_as_xml3 30 | test_as_xml4 31 | words0 32 | words1 33 | words2 34 | words3 35 | words4 36 | words5 37 | words6 38 | words7 39 | words8 40 | words9 41 | formatter3 42 | formatter4 43 | formatter5 44 | stream_test4 45 | formatter6 46 | custom_constraint1 47 | custom_constraint2 48 | custom_constraint3 49 | -------------------------------------------------------------------------------- /doc/tutorial_src/README: -------------------------------------------------------------------------------- 1 | This directory contains source files and output for the examples in 2 | the tutorial documentataion. You should run these now and then and 3 | make sure that they compile and work. 4 | 5 | Note however that the guide includes specific lines from certain of 6 | these files, so if you change anything you need to be certain that the 7 | guide is still correct. 8 | 9 | On the other hand we will always know that the code in the guide 10 | actually works and is correct. 11 | 12 | You need mysql client header files to make some sources to compile. 13 | -------------------------------------------------------------------------------- /doc/tutorial_src/all_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | TestSuite *words_tests(); 4 | 5 | int main(int argc, char **argv) { 6 | TestSuite *suite = create_test_suite(); 7 | add_suite(suite, words_tests()); 8 | if (argc > 1) { 9 | return run_single_test(suite, argv[1], create_text_reporter()); 10 | } 11 | return run_test_suite(suite, create_text_reporter()); 12 | } 13 | -------------------------------------------------------------------------------- /doc/tutorial_src/constraints.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 tests)... 2 | "main": 1 pass in 42ms. 3 | Completed "main": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/constraints1.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 tests)... 2 | "main": 1 pass in 42ms. 3 | Completed "main": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/constraints2.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 tests)... 2 | constraints.c:57: Failure: more_complex_custom_constraint_function 3 | Expected [&piece99] to [fit in box] [&box1] 4 | at offset: [0] 5 | actual value: [0x63] 6 | expected value: [0x01] 7 | 8 | "main": 1 failure in 42ms. 9 | Completed "main": 1 failure in 42ms. 10 | -------------------------------------------------------------------------------- /doc/tutorial_src/crash1.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 test)... 2 | crash_tests.c:8: Exception: seg_faults_for_null_dereference 3 | Test terminated with signal: Segmentation fault 4 | 5 | "main": 1 exception in 42ms. 6 | Completed "main": 1 exception in 42ms. 7 | -------------------------------------------------------------------------------- /doc/tutorial_src/crash2.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 test)... 2 | -------------------------------------------------------------------------------- /doc/tutorial_src/crash3.out: -------------------------------------------------------------------------------- 1 | Running "main" (2 tests)... 2 | crash_tests.c:8: Exception: seg_faults_for_null_dereference 3 | Test terminated with signal: Segmentation fault 4 | 5 | crash_tests.c:13: Exception: will_loop_forever 6 | Test terminated unexpectedly, likely from a non-standard exception or Posix signal 7 | 8 | "main": 2 exceptions in 42ms. 9 | Completed "main": 2 exceptions in 42ms. 10 | -------------------------------------------------------------------------------- /doc/tutorial_src/crash_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Ensure(will_seg_fault) { 5 | int *p = NULL; 6 | (*p)++; 7 | } 8 | 9 | Ensure(will_stall) { 10 | die_in(1); 11 | while(1) { } 12 | } 13 | 14 | int main(int argc, char **argv) { 15 | TestSuite *suite = create_test_suite(); 16 | add_test(suite, will_seg_fault); 17 | add_test(suite, will_stall); 18 | run_test_suite(suite, create_text_reporter()); 19 | } 20 | -------------------------------------------------------------------------------- /doc/tutorial_src/crash_tests1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(CrashExample); 5 | BeforeEach(CrashExample) {} 6 | AfterEach(CrashExample) {} 7 | 8 | Ensure(CrashExample, seg_faults_for_null_dereference) { 9 | int *p = NULL; 10 | (*p)++; 11 | } 12 | 13 | int main(int argc, char **argv) { 14 | TestSuite *suite = create_test_suite(); 15 | add_test_with_context(suite, CrashExample, seg_faults_for_null_dereference); 16 | return run_test_suite(suite, create_text_reporter()); 17 | } 18 | -------------------------------------------------------------------------------- /doc/tutorial_src/crash_tests2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(CrashExample); 5 | BeforeEach(CrashExample) {} 6 | AfterEach(CrashExample) {} 7 | 8 | Ensure(CrashExample, seg_faults_for_null_dereference) { 9 | int *p = NULL; 10 | (*p)++; 11 | } 12 | 13 | int main(int argc, char **argv) { 14 | TestSuite *suite = create_test_suite(); 15 | add_test_with_context(suite, CrashExample, seg_faults_for_null_dereference); 16 | return run_single_test(suite, "seg_faults_for_null_dereference", create_text_reporter()); 17 | } 18 | -------------------------------------------------------------------------------- /doc/tutorial_src/crash_tests3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(CrashExample); 5 | BeforeEach(CrashExample) {} 6 | AfterEach(CrashExample) {} 7 | 8 | Ensure(CrashExample, seg_faults_for_null_dereference) { 9 | int *p = NULL; 10 | (*p)++; 11 | } 12 | 13 | Ensure(CrashExample, will_loop_forever) { 14 | die_in(1); 15 | while(0 == 0) { } 16 | } 17 | 18 | int main(int argc, char **argv) { 19 | TestSuite *suite = create_test_suite(); 20 | add_test_with_context(suite, CrashExample, seg_faults_for_null_dereference); 21 | add_test_with_context(suite, CrashExample, will_loop_forever); 22 | return run_test_suite(suite, create_text_reporter()); 23 | } 24 | -------------------------------------------------------------------------------- /doc/tutorial_src/custom_constraint1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "constraint_internal.h" 4 | 5 | Describe(TestConstraint); 6 | BeforeEach(TestConstraint) {} 7 | AfterEach(TestConstraint) {} 8 | 9 | bool compare_want_greater_than_5(Constraint *constraint, CgreenValue actual) { 10 | return actual.value.integer_value > 5; 11 | } 12 | 13 | Constraint static_is_bigger_than_5 = { 14 | /* .type */ CGREEN_VALUE_COMPARER_CONSTRAINT, 15 | /* .name */ "be bigger than 5", 16 | /* .destroy */ destroy_static_constraint, 17 | /* .compare */ compare_want_greater_than_5, 18 | /* .test */ test_want, 19 | /* .format_failure_message_for */ failure_message_for, 20 | /* .actual_value_message */ "", 21 | /* .expected_value_message */ "", 22 | /* .expected_value */ {CGREEN_INTEGER, {5}}, 23 | /* .stored_value_name */ "null", 24 | /* .parameter_name */ NULL, 25 | /* .size_of_stored_value */ 0 26 | }; 27 | 28 | Ensure(TestConstraint, custom_constraint_using_static_function) { 29 | Constraint * is_bigger_than_5 = &static_is_bigger_than_5; 30 | assert_that(10, is_bigger_than_5); 31 | } 32 | 33 | int main(int argc, char **argv) { 34 | TestSuite *suite = create_test_suite(); 35 | add_test_with_context(suite, TestConstraint, custom_constraint_using_static_function); 36 | run_test_suite(suite, create_text_reporter()); 37 | } 38 | -------------------------------------------------------------------------------- /doc/tutorial_src/custom_constraint1.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 test)... 2 | "main": 1 pass in 42ms. 3 | Completed "main": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/custom_constraint2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "cgreen_value_internal.h" 4 | #include "utils.h" 5 | 6 | Describe(TestConstraint); 7 | BeforeEach(TestConstraint) {} 8 | AfterEach(TestConstraint) {} 9 | 10 | bool compare_want_smaller_value(Constraint *constraint, CgreenValue actual) { 11 | return actual.value.integer_value < constraint->expected_value.value.integer_value ; 12 | } 13 | 14 | Constraint *create_smaller_than_constraint(intptr_t expected_value, const char *expected_value_name) { 15 | Constraint *constraint = create_constraint(); 16 | 17 | constraint->expected_value = make_cgreen_integer_value(expected_value); 18 | constraint->expected_value_name = string_dup(expected_value_name); 19 | constraint->type = CGREEN_VALUE_COMPARER_CONSTRAINT; 20 | 21 | constraint->compare = &compare_want_smaller_value; 22 | constraint->execute = &test_want; 23 | constraint->name = "be smaller than"; 24 | constraint->size_of_expected_value = sizeof(intptr_t); 25 | 26 | return constraint; 27 | } 28 | #define is_smaller_than(value) create_smaller_than_constraint(value, #value) 29 | 30 | 31 | Ensure(TestConstraint, custom_constraint_using_a_function_with_arguments_function) { 32 | assert_that(9, is_smaller_than(10)); 33 | } 34 | 35 | int main(int argc, char **argv) { 36 | TestSuite *suite = create_test_suite(); 37 | add_test_with_context(suite, TestConstraint, custom_constraint_using_a_function_with_arguments_function); 38 | run_test_suite(suite, create_text_reporter()); 39 | } 40 | -------------------------------------------------------------------------------- /doc/tutorial_src/custom_constraint2.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 test)... 2 | "main": 1 pass in 42ms. 3 | Completed "main": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/custom_constraint3.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 test)... 2 | custom_constraint.c:57: Failure: more_complex_custom_constraint_function 3 | Expected [&piece99] to [fit in box] [&box1] 4 | at offset: [0] 5 | actual value: [0x63] 6 | expected value: [0x01] 7 | 8 | "main": 1 failure in 42ms. 9 | Completed "main": 1 failure in 42ms. 10 | -------------------------------------------------------------------------------- /doc/tutorial_src/double1.out: -------------------------------------------------------------------------------- 1 | Running "main" (2 tests)... 2 | double_tests.c:13: Failure: can_assert_double_values 3 | Expected [3.14] to [equal double] [5.0] within [3] significant figures 4 | actual value: [3.140000] 5 | expected value: [5.000000] 6 | 7 | "main": 3 passes, 1 failure in 42ms. 8 | Completed "main": 3 passes, 1 failure in 42ms. 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/double_tests1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define PI 3.1415926 6 | 7 | Describe(Doubles); 8 | BeforeEach(Doubles) {} 9 | AfterEach(Doubles) {} 10 | 11 | Ensure(Doubles, can_assert_double_values) { 12 | significant_figures_for_assert_double_are(3); 13 | assert_that_double(3.14, is_equal_to_double(5.0)); 14 | } 15 | 16 | static double double_out(int i, double d) { 17 | return unbox_double(mock(i, box_double(d))); // <1> 18 | } 19 | 20 | Ensure(Doubles, can_be_arguments_to_mock_and_returned) { 21 | expect(double_out, 22 | when(i, is_equal_to(15)), 23 | when(d, is_equal_to_double(31.32)), // <2> 24 | will_return_double(3.1415926)); // <3> 25 | assert_that_double(double_out(15, 31.32), is_equal_to_double(3.1415926)); 26 | } 27 | 28 | int main(int argc, char **argv) { 29 | TestSuite *suite = create_test_suite(); 30 | add_test_with_context(suite, Doubles, can_assert_double_values); 31 | add_test_with_context(suite, Doubles, can_be_arguments_to_mock_and_returned); 32 | return run_test_suite(suite, create_text_reporter()); 33 | } 34 | -------------------------------------------------------------------------------- /doc/tutorial_src/first0.out: -------------------------------------------------------------------------------- 1 | Running "main" (0 tests)... 2 | Completed "main": No assertions. 3 | -------------------------------------------------------------------------------- /doc/tutorial_src/first1.out: -------------------------------------------------------------------------------- 1 | Running "main" (2 tests)... 2 | first_tests.c:12: Failure: fails_this_test 3 | Expected [0 == 1] to [be true] 4 | 5 | "main": 1 pass, 1 failure in 42ms. 6 | Completed "main": 1 pass, 1 failure in 42ms. 7 | -------------------------------------------------------------------------------- /doc/tutorial_src/first_tests0.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Describe(Cgreen); 4 | BeforeEach(Cgreen) {} 5 | AfterEach(Cgreen) {} 6 | 7 | int main(int argc, char **argv) { 8 | TestSuite *suite = create_test_suite(); 9 | return run_test_suite(suite, create_text_reporter()); 10 | } 11 | -------------------------------------------------------------------------------- /doc/tutorial_src/first_tests1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Describe(Cgreen); 4 | BeforeEach(Cgreen) {} 5 | AfterEach(Cgreen) {} 6 | 7 | Ensure(Cgreen, passes_this_test) { 8 | assert_that(1 == 1); 9 | } 10 | 11 | Ensure(Cgreen, fails_this_test) { 12 | assert_that(0 == 1); 13 | } 14 | 15 | int main(int argc, char **argv) { 16 | TestSuite *suite = create_test_suite(); 17 | add_test_with_context(suite, Cgreen, passes_this_test); 18 | add_test_with_context(suite, Cgreen, fails_this_test); 19 | return run_test_suite(suite, create_text_reporter()); 20 | } 21 | -------------------------------------------------------------------------------- /doc/tutorial_src/first_tests2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Describe(Cgreen); 4 | BeforeEach(Cgreen) {} 5 | AfterEach(Cgreen) {} 6 | 7 | Ensure(Cgreen, passes_this_test) { 8 | assert_that(1 == 1); 9 | } 10 | 11 | Ensure(Cgreen, fails_this_test) { 12 | assert_that(0 == 1); 13 | } 14 | 15 | int main(int argc, char **argv) { 16 | TestSuite *suite = create_test_suite(); 17 | add_test_with_context(suite, Cgreen, passes_this_test); 18 | add_test_with_context(suite, Cgreen, fails_this_test); 19 | return run_test_suite(suite, create_text_reporter()); 20 | } 21 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter0.out: -------------------------------------------------------------------------------- 1 | Couldn't find library: formatter0.so 2 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter1.out: -------------------------------------------------------------------------------- 1 | Running "formatter" (1 test)... 2 | "Formatter": 1 pass in 42ms. 3 | Completed "formatter": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter2.out: -------------------------------------------------------------------------------- 1 | Running "formatter" (2 tests)... 2 | "Formatter": 2 passes in 42ms. 3 | Completed "formatter": 2 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter3.out: -------------------------------------------------------------------------------- 1 | Running "formatter" (3 tests)... 2 | "Formatter": 5 passes in 42ms. 3 | Completed "formatter": 5 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter4.out: -------------------------------------------------------------------------------- 1 | Running "formatter" (4 tests)... 2 | "Formatter": 9 passes in 42ms. 3 | Completed "formatter": 9 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter5.out: -------------------------------------------------------------------------------- 1 | Running "formatter" (5 tests)... 2 | formatter_tests.c:59: Failure: Formatter -> ignores_empty_paragraphs 3 | Mocked function [writer] has an expectation that it will never be called, but it was 4 | 5 | "Formatter": 9 passes, 1 failure in 42ms. 6 | Completed "formatter": 9 passes, 1 failure in 42ms. 7 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter6.out: -------------------------------------------------------------------------------- 1 | Running "formatter" (5 tests)... 2 | "Formatter": 10 passes in 42ms. 3 | Completed "formatter": 10 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter_tests0.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "stream.h" 5 | 6 | Describe(Formatter); 7 | BeforeEach(Formatter) {} 8 | AfterEach(Formatter) {} 9 | 10 | int one_character_stream(void *stream) { return 'a'; } 11 | 12 | void expect_one_letter_paragraph(void *stream, char *paragraph) { 13 | assert_that(paragraph, is_equal_to_string("a")); 14 | } 15 | 16 | Ensure(Formatter, makes_one_letter_paragraph_from_one_character_input) { 17 | by_paragraph( 18 | &one_character_stream, 19 | NULL, 20 | &expect_one_letter_paragraph, 21 | NULL); 22 | } 23 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter_tests1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "stream.h" 5 | 6 | Describe(Formatter); 7 | BeforeEach(Formatter) {} 8 | AfterEach(Formatter) {} 9 | 10 | static int reader(void *stream) { 11 | return (int)mock(stream); 12 | } 13 | 14 | static void writer(void *stream, char *paragraph) { 15 | mock(stream, paragraph); 16 | } 17 | 18 | Ensure(Formatter, makes_one_letter_paragraph_from_one_character_input) { 19 | expect(reader, will_return('a')); 20 | always_expect(reader, will_return(EOF)); 21 | expect(writer, when(paragraph, is_equal_to_string("a"))); 22 | by_paragraph(&reader, NULL, &writer, NULL); 23 | } 24 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter_tests2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "stream.h" 5 | 6 | Describe(Formatter); 7 | BeforeEach(Formatter) {} 8 | AfterEach(Formatter) {} 9 | 10 | static int reader(void *stream) { 11 | return (int)mock(stream); 12 | } 13 | 14 | static void writer(void *stream, char *paragraph) { 15 | mock(stream, paragraph); 16 | } 17 | 18 | Ensure(Formatter, makes_one_letter_paragraph_from_one_character_input) { 19 | expect(reader, will_return('a')); 20 | always_expect(reader, will_return(EOF)); 21 | expect(writer, when(paragraph, is_equal_to_string("a"))); 22 | by_paragraph(&reader, NULL, &writer, NULL); 23 | } 24 | 25 | Ensure(Formatter, makes_one_paragraph_if_no_line_endings) { 26 | expect(reader, will_return('a')); 27 | expect(reader, will_return(' ')); 28 | expect(reader, will_return('b')); 29 | expect(reader, will_return(' ')); 30 | expect(reader, will_return('c')); 31 | always_expect(reader, will_return(EOF)); 32 | expect(writer, when(paragraph, is_equal_to_string("a b c"))); 33 | by_paragraph(&reader, NULL, &writer, NULL); 34 | } 35 | -------------------------------------------------------------------------------- /doc/tutorial_src/formatter_tests3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "stream.h" 5 | 6 | Describe(Formatter); 7 | BeforeEach(Formatter) {} 8 | AfterEach(Formatter) {} 9 | 10 | static int reader(void *stream) { 11 | return (int)mock(stream); 12 | } 13 | 14 | static void writer(void *stream, char *paragraph) { 15 | mock(stream, paragraph); 16 | } 17 | 18 | Ensure(Formatter, makes_one_letter_paragraph_from_one_character_input) { 19 | expect(reader, will_return('a')); 20 | always_expect(reader, will_return(EOF)); 21 | expect(writer, when(paragraph, is_equal_to_string("a"))); 22 | by_paragraph(&reader, NULL, &writer, NULL); 23 | } 24 | 25 | Ensure(Formatter, makes_one_paragraph_if_no_line_endings) { 26 | expect(reader, will_return('a')); 27 | expect(reader, will_return(' ')); 28 | expect(reader, will_return('b')); 29 | expect(reader, will_return(' ')); 30 | expect(reader, will_return('c')); 31 | always_expect(reader, will_return(EOF)); 32 | expect(writer, when(paragraph, is_equal_to_string("a b c"))); 33 | by_paragraph(&reader, NULL, &writer, NULL); 34 | } 35 | 36 | Ensure(Formatter, generates_separate_paragraphs_for_line_endings) { 37 | expect(reader, will_return('a')); 38 | expect(reader, will_return('\n')); 39 | expect(reader, will_return('b')); 40 | expect(reader, will_return('\n')); 41 | expect(reader, will_return('c')); 42 | always_expect(reader, will_return(EOF)); 43 | expect(writer, when(paragraph, is_equal_to_string("a"))); 44 | expect(writer, when(paragraph, is_equal_to_string("b"))); 45 | expect(writer, when(paragraph, is_equal_to_string("c"))); 46 | by_paragraph(&reader, NULL, &writer, NULL); 47 | } 48 | -------------------------------------------------------------------------------- /doc/tutorial_src/learning_mocks.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(LearningMocks); 5 | BeforeEach(LearningMocks) {} 6 | AfterEach(LearningMocks) {} 7 | 8 | static int integer_out() { 9 | return (int)mock(); 10 | } 11 | 12 | static char *string_out(int p1) { 13 | return (char *)mock(p1); 14 | } 15 | 16 | Ensure(LearningMocks, emit_pastable_code) { 17 | cgreen_mocks_are(learning_mocks); 18 | string_out(1); 19 | string_out(2); 20 | integer_out(); 21 | integer_out(); 22 | string_out(3); 23 | integer_out(); 24 | } 25 | -------------------------------------------------------------------------------- /doc/tutorial_src/multiple_streams1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void do_stuff(void *stream1, void *stream2) {} 5 | 6 | Describe(Streams); 7 | BeforeEach(Streams) {} 8 | AfterEach(Streams) {} 9 | 10 | static int stream_stub(void *stream) { 11 | return (int)mock(stream); 12 | } 13 | 14 | Ensure(Streams, bad_test) { 15 | expect(stream_stub, will_return('a')); 16 | do_stuff(&stream_stub, &stream_stub); 17 | } 18 | -------------------------------------------------------------------------------- /doc/tutorial_src/multiple_streams1.out: -------------------------------------------------------------------------------- 1 | Running "multiple_streams" (1 test)... 2 | multiple_streams.c:15: Failure: Streams -> bad_test 3 | Expected call was not made to mocked function [stream_stub] 4 | 5 | "Streams": 1 failure in 42ms. 6 | Completed "multiple_streams": 1 failure in 42ms. 7 | -------------------------------------------------------------------------------- /doc/tutorial_src/multiple_streams2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void do_stuff(void *stream1, void *stream2) {} 5 | 6 | Describe(Streams); 7 | BeforeEach(Streams) {} 8 | AfterEach(Streams) {} 9 | 10 | static int first_stream_stub(void *stream) { 11 | return (int)mock(stream); 12 | } 13 | 14 | static int second_stream_stub(void *stream) { 15 | return (int)mock(stream); 16 | } 17 | 18 | Ensure(Streams, good_test) { 19 | expect(first_stream_stub, will_return('a')); 20 | expect(second_stream_stub, will_return('a')); 21 | do_stuff(&first_stream_stub, &second_stream_stub); 22 | } 23 | -------------------------------------------------------------------------------- /doc/tutorial_src/multiple_streams2.out: -------------------------------------------------------------------------------- 1 | Running "multiple_streams" (1 test)... 2 | multiple_streams.c:19: Failure: Streams -> good_test 3 | Expected call was not made to mocked function [first_stream_stub] 4 | 5 | multiple_streams.c:20: Failure: Streams -> good_test 6 | Expected call was not made to mocked function [second_stream_stub] 7 | 8 | "Streams": 2 failures in 42ms. 9 | Completed "multiple_streams": 2 failures in 42ms. 10 | -------------------------------------------------------------------------------- /doc/tutorial_src/person.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct _Person { 4 | char *name; 5 | } Person; 6 | 7 | Person *create_person() {return NULL;} 8 | Person *find_person_by_name(const char *name) {return NULL;} 9 | void set_person_name(Person *person, const char *name) {} 10 | char *get_person_name(Person *person) {return NULL;} 11 | int save_person(Person *person) { return 1;} 12 | -------------------------------------------------------------------------------- /doc/tutorial_src/person_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "person.h" 5 | 6 | static MYSQL *connection; 7 | 8 | static void create_schema() { 9 | mysql_query(connection, "create table people (name, varchar(255) unique)"); 10 | } 11 | 12 | static void drop_schema() { 13 | mysql_query(connection, "drop table people"); 14 | } 15 | 16 | Ensure(can_add_person_to_database) { 17 | Person *person = create_person(); 18 | set_person_name(person, "Fred"); 19 | save_person(person); 20 | Person *found = find_person_by_name("Fred"); 21 | assert_that(get_person_name(person), is_equal_to_string("Fred")); 22 | } 23 | 24 | Ensure(cannot_add_duplicate_person) { 25 | Person *person = create_person(); 26 | set_person_name(person, "Fred"); 27 | assert_that(save_person(person), is_null); 28 | Person *duplicate = create_person(); 29 | set_person_name(duplicate, "Fred"); 30 | assert_that(save_person(duplicate), is_null); 31 | } 32 | 33 | void open_connection() { 34 | connection = mysql_init(NULL); 35 | mysql_real_connect(connection, "localhost", "me", "secret", "test", 0, NULL, 0); 36 | } 37 | 38 | void close_connection() { 39 | mysql_close(connection); 40 | } 41 | 42 | TestSuite *person_tests() { 43 | TestSuite *suite = create_test_suite(); 44 | set_setup(suite, create_schema); 45 | set_teardown(suite, drop_schema); 46 | add_test(suite, can_add_person_to_database); 47 | add_test(suite, cannot_add_duplicate_person); 48 | 49 | TestSuite *fixture = create_named_test_suite("Mysql"); 50 | add_suite(fixture, suite); 51 | set_setup(fixture, open_connection); 52 | set_teardown(fixture, close_connection); 53 | return fixture; 54 | } 55 | 56 | int main(int argc, char **argv) { 57 | return run_test_suite(person_tests(), create_text_reporter()); 58 | } 59 | -------------------------------------------------------------------------------- /doc/tutorial_src/read_paragraph1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *read_paragraph(int (*read)(void *), void *stream) { 5 | int buffer_size = 0, length = 0; 6 | char *buffer = NULL; 7 | int ch; 8 | while ((ch = (*read)(stream)) != EOF) { 9 | if (++length > buffer_size) { 10 | buffer_size += 100; 11 | buffer = (char *)realloc(buffer, buffer_size + 1); 12 | } 13 | if ((buffer[length] = ch) == '\n') { 14 | break; 15 | } 16 | buffer[length + 1] = '\0'; 17 | } 18 | return buffer; 19 | } 20 | -------------------------------------------------------------------------------- /doc/tutorial_src/read_paragraph2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *read_paragraph(int (*read)(void *), void *stream) { 5 | int buffer_size = 0, length = 0; 6 | char *buffer = NULL; 7 | int ch; 8 | while ((ch = (*read)(stream)) != EOF) { 9 | if (++length > buffer_size) { 10 | buffer_size += 100; 11 | buffer = (char *)realloc(buffer, buffer_size + 1); 12 | } 13 | if ((buffer[length - 1] = ch) == '\n') { // <1> 14 | break; 15 | } 16 | buffer[length] = '\0'; // <2> 17 | } 18 | return buffer; 19 | } 20 | -------------------------------------------------------------------------------- /doc/tutorial_src/read_paragraph3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *read_paragraph(int (*read)(void *), void *stream) { 5 | int buffer_size = 0, length = 0; 6 | char *buffer = NULL; 7 | int ch; 8 | while ((ch = (*read)(stream)) != EOF) { 9 | if (++length > buffer_size) { 10 | buffer_size += 100; 11 | buffer = (char *)realloc(buffer, buffer_size + 1); 12 | } 13 | if ((buffer[length - 1] = ch) == '\n') { 14 | buffer[--length] = '\0'; 15 | break; 16 | } 17 | buffer[length] = '\0'; 18 | } 19 | return buffer; 20 | } 21 | -------------------------------------------------------------------------------- /doc/tutorial_src/roman_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static int convert_roman_to_decimal(char *roman) { 4 | return 0; 5 | } 6 | 7 | Describe(Converter); 8 | BeforeEach(Converter) {} 9 | AfterEach(Converter) {} 10 | 11 | Ensure(Converter, converts_XIV_to_14) { 12 | assert_that(convert_roman_to_decimal("XIV"), is_equal_to(14)); 13 | } 14 | -------------------------------------------------------------------------------- /doc/tutorial_src/runner1.out: -------------------------------------------------------------------------------- 1 | Running "first_tests" (2 tests)... 2 | first_tests.c:12: Failure: Cgreen -> fails_this_test 3 | Expected [0 == 1] to [be true] 4 | 5 | "Cgreen": 1 pass, 1 failure in 42ms. 6 | Completed "first_tests": 1 pass, 1 failure in 42ms. 7 | -------------------------------------------------------------------------------- /doc/tutorial_src/runner2.out: -------------------------------------------------------------------------------- 1 | Running "first_tests" (1 test)... 2 | first_tests.c:12: Failure: Cgreen -> fails_this_test 3 | Expected [0 == 1] to [be true] 4 | 5 | "Cgreen": 1 failure in 42ms. 6 | Completed "first_tests": 1 failure in 42ms. 7 | -------------------------------------------------------------------------------- /doc/tutorial_src/runner3.out: -------------------------------------------------------------------------------- 1 | Discovered Cgreen:fails_this_test (CgreenSpec__Cgreen__fails_this_test__) 2 | Discovered Cgreen:passes_this_test (CgreenSpec__Cgreen__passes_this_test__) 3 | Discovered 2 test(s) 4 | Opening [first_tests.so] to only run one test: 'Cgreen:fails_this_test' ... 5 | Running "first_tests" (1 test)... 6 | first_tests.c:12: Failure: Cgreen -> fails_this_test 7 | Expected [0 == 1] to [be true] 8 | 9 | "Cgreen": 1 failure in 42ms. 10 | Completed "first_tests": 1 failure in 42ms. 11 | -------------------------------------------------------------------------------- /doc/tutorial_src/schema1.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/doc/tutorial_src/schema1.out -------------------------------------------------------------------------------- /doc/tutorial_src/schema2.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/doc/tutorial_src/schema2.out -------------------------------------------------------------------------------- /doc/tutorial_src/schema_tests1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "person.h" 5 | 6 | Describe(Person); 7 | BeforeEach(Person) {} 8 | AfterEach(Person) {} 9 | 10 | static void create_schema() { 11 | MYSQL *connection = mysql_init(NULL); 12 | mysql_real_connect(connection, "localhost", "me", "secret", "test", 0, NULL, 0); 13 | mysql_query(connection, "create table people (name, varchar(255) unique)"); 14 | mysql_close(connection); 15 | } 16 | 17 | static void drop_schema() { 18 | MYSQL *connection = mysql_init(NULL); 19 | mysql_real_connect(connection, "localhost", "me", "secret", "test", 0, NULL, 0); 20 | mysql_query(connection, "drop table people"); 21 | mysql_close(connection); 22 | } 23 | 24 | Ensure(Person, can_add_person_to_database) { 25 | create_schema(); 26 | Person *person = create_person(); 27 | set_person_name(person, "Fred"); 28 | save_person(person); 29 | Person *found = find_person_by_name("Fred"); 30 | assert_that(get_person_name(found), is_equal_to_string("Fred")); 31 | drop_schema(); 32 | } 33 | 34 | Ensure(Person, cannot_add_duplicate_person) { 35 | create_schema(); 36 | Person *person = create_person(); 37 | set_person_name(person, "Fred"); 38 | assert_that(save_person(person), is_true); 39 | Person *duplicate = create_person(); 40 | set_person_name(duplicate, "Fred"); 41 | assert_that(save_person(duplicate), is_false); 42 | drop_schema(); 43 | } 44 | 45 | TestSuite *person_tests() { 46 | TestSuite *suite = create_test_suite(); 47 | add_test_with_context(suite, Person, can_add_person_to_database); 48 | add_test_with_context(suite, Person, cannot_add_duplicate_person); 49 | return suite; 50 | } 51 | 52 | int main(int argc, char **argv) { 53 | return run_test_suite(person_tests(), create_text_reporter()); 54 | } 55 | -------------------------------------------------------------------------------- /doc/tutorial_src/schema_tests2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "person.h" 5 | 6 | static void create_schema() { 7 | MYSQL *connection = mysql_init(NULL); 8 | mysql_real_connect(connection, "localhost", "me", "secret", "test", 0, NULL, 0); 9 | mysql_query(connection, "create table people (name, varchar(255) unique)"); 10 | mysql_close(connection); 11 | } 12 | 13 | static void drop_schema() { 14 | MYSQL *connection = mysql_init(NULL); 15 | mysql_real_connect(connection, "localhost", "me", "secret", "test", 0, NULL, 0); 16 | mysql_query(connection, "drop table people"); 17 | mysql_close(connection); 18 | } 19 | 20 | Describe(Person); 21 | BeforeEach(Person) { create_schema(); } 22 | AfterEach(Person) { drop_schema(); } 23 | 24 | Ensure(Person, can_add_person_to_database) { 25 | Person *person = create_person(); 26 | set_person_name(person, "Fred"); 27 | save_person(person); 28 | Person *found = find_person_by_name("Fred"); 29 | assert_that(get_person_name(found), is_equal_to_string("Fred")); 30 | } 31 | 32 | Ensure(Person, cannot_add_duplicate_person) { 33 | Person *person = create_person(); 34 | set_person_name(person, "Fred"); 35 | assert_that(save_person(person), is_true); 36 | Person *duplicate = create_person(); 37 | set_person_name(duplicate, "Fred"); 38 | assert_that(save_person(duplicate), is_false); 39 | } 40 | 41 | TestSuite *person_tests() { 42 | TestSuite *suite = create_test_suite(); 43 | add_test_with_context(suite, Person, can_add_person_to_database); 44 | add_test_with_context(suite, Person, cannot_add_duplicate_person); 45 | return suite; 46 | } 47 | 48 | int main(int argc, char **argv) { 49 | return run_test_suite(person_tests(), create_text_reporter()); 50 | } 51 | -------------------------------------------------------------------------------- /doc/tutorial_src/set_contents.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void convert_to_uppercase(char *converted_string, const char *original_string) { 5 | mock(converted_string, original_string); 6 | } 7 | 8 | Ensure(setting_content_of_out_parameter) { 9 | expect(convert_to_uppercase, 10 | when(original_string, is_equal_to_string("upper case")), 11 | will_set_contents_of_output_parameter(converted_string, 12 | "UPPER CASE", 11)); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /doc/tutorial_src/set_field.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct structure { 5 | int field; 6 | char *string; 7 | }; 8 | 9 | void update_field(struct structure *struct_to_update) { 10 | int *field = &struct_to_update->field; 11 | mock(struct_to_update, field); 12 | } 13 | 14 | Ensure(setting_field_of_parameter) { 15 | int fourty_two = 42; 16 | expect(update_field, 17 | will_set_contents_of_output_parameter(field, &fourty_two, sizeof(int))); 18 | } 19 | -------------------------------------------------------------------------------- /doc/tutorial_src/side_effect.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int reader(void *stream) { 5 | return (int)mock(stream); 6 | } 7 | 8 | static void writer(void *stream, char *paragraph) { 9 | mock(stream, paragraph); 10 | } 11 | 12 | char *read_paragraph(int (*read)(void *), void *stream); 13 | 14 | void by_paragraph(int (*read)(void *), void *in, void (*write)(void *, char *), void *out) { 15 | while (1) { 16 | char *line = read_paragraph(read, in); 17 | if ((line == NULL) || (strlen(line) == 0)) { 18 | return; 19 | } 20 | (*write)(out, line); 21 | free(line); 22 | } 23 | } 24 | 25 | static int stub_stream(void *stream) { 26 | return (int)mock(stream); 27 | } 28 | 29 | static void update_counter(void * counter) { 30 | *(int*)counter = *(int*)counter + 1; 31 | } 32 | 33 | Ensure(using_side_effect) { 34 | int number_of_times_reader_was_called = 0; 35 | expect(reader, will_return('\n')); 36 | always_expect(reader, 37 | will_return(EOF), 38 | with_side_effect(&update_counter, 39 | &number_of_times_reader_was_called)); 40 | never_expect(writer); 41 | by_paragraph(&reader, NULL, &writer, NULL); 42 | 43 | assert_that(number_of_times_reader_was_called, is_equal_to(1)); 44 | } 45 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *read_paragraph(int (*read)(void *), void *stream) { 6 | int buffer_size = 0, length = 0; 7 | char *buffer = NULL; 8 | int ch; 9 | while ((ch = (*read)(stream)) != EOF) { 10 | if (++length > buffer_size) { 11 | buffer_size += 100; 12 | buffer = realloc(buffer, buffer_size + 1); 13 | } 14 | if ((buffer[length - 1] = ch) == '\n') { 15 | buffer[--length] = '\0'; 16 | break; 17 | } 18 | buffer[length] = '\0'; 19 | } 20 | return buffer; 21 | } 22 | 23 | void by_paragraph(int (*read)(void *), void *in, void (*write)(void *, char *), void *out) { 24 | while (1) { 25 | char *line = read_paragraph(read, in); 26 | if ((line == NULL) || (strlen(line) == 0)) { 27 | return; 28 | } 29 | (*write)(out, line); 30 | free(line); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream.h: -------------------------------------------------------------------------------- 1 | char *read_paragraph(int (*read)(void *), void *stream); 2 | void by_paragraph(int (*read)(void *), void *in, void (*write)(void *, char *), void *out); 3 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream0.out: -------------------------------------------------------------------------------- 1 | Running "stream" (1 test)... 2 | "ParagraphReader": 1 pass in 42ms. 3 | Completed "stream": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *read_paragraph(int (*read)(void *), void *stream) { 6 | int buffer_size = 0, length = 0; 7 | char *buffer = NULL; 8 | int ch; 9 | while ((ch = (*read)(stream)) != EOF) { 10 | if (++length > buffer_size) { 11 | buffer_size += 100; 12 | buffer = realloc(buffer, buffer_size + 1); 13 | } 14 | if ((buffer[length - 1] = ch) == '\n') { 15 | buffer[--length] = '\0'; 16 | break; 17 | } 18 | buffer[length] = '\0'; 19 | } 20 | return buffer; 21 | } 22 | 23 | void by_paragraph(int (*read)(void *), void *in, void (*write)(void *, char *), void *out) { 24 | while (1) { 25 | char *line = read_paragraph(read, in); 26 | if (line == NULL) { 27 | return; 28 | } 29 | (*write)(out, line); 30 | free(line); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream1.out: -------------------------------------------------------------------------------- 1 | Running "stream" (1 test)... 2 | "ParagraphReader": 1 pass in 42ms. 3 | Completed "stream": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *read_paragraph(int (*read)(void *), void *stream) { 6 | int buffer_size = 0, length = 0; 7 | char *buffer = NULL; 8 | int ch; 9 | while ((ch = (*read)(stream)) != EOF) { 10 | if (++length > buffer_size) { 11 | buffer_size += 100; 12 | buffer = realloc(buffer, buffer_size + 1); 13 | } 14 | if ((buffer[length - 1] = ch) == '\n') { 15 | buffer[--length] = '\0'; 16 | break; 17 | } 18 | buffer[length] = '\0'; 19 | } 20 | return buffer; 21 | } 22 | 23 | void by_paragraph(int (*read)(void *), void *in, void (*write)(void *, char *), void *out) { 24 | while (1) { 25 | char *line = read_paragraph(read, in); 26 | if ((line == NULL) || (strlen(line) == 0)) { 27 | return; 28 | } 29 | (*write)(out, line); 30 | free(line); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream2.out: -------------------------------------------------------------------------------- 1 | Running "stream" (2 tests)... 2 | stream_tests.c:23: Failure: ParagraphReader -> gives_one_character_line_for_one_character_stream 3 | Expected [line] to [equal string] ["a"] 4 | actual value: [""] 5 | expected to equal: ["a"] 6 | 7 | "ParagraphReader": 1 pass, 1 failure in 42ms. 8 | Completed "stream": 1 pass, 1 failure in 42ms. 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream3.out: -------------------------------------------------------------------------------- 1 | Running "stream" (2 tests)... 2 | "ParagraphReader": 2 passes in 42ms. 3 | Completed "stream": 2 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream4.out: -------------------------------------------------------------------------------- 1 | Running "stream" (3 tests)... 2 | "ParagraphReader": 3 passes in 42ms. 3 | Completed "stream": 3 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream5.out: -------------------------------------------------------------------------------- 1 | Running "stream" (5 tests)... 2 | stream_tests.c:40: Failure: ParagraphReader -> drops_line_ending_from_word_and_stops 3 | Expected [read_paragraph(&stream_stub, ((void *)0))] to [equal string] ["the"] 4 | actual value: ["the 5 | "] 6 | expected to equal: ["the"] 7 | 8 | stream_tests.c:45: Failure: ParagraphReader -> gives_empty_line_for_single_line_ending 9 | Expected [read_paragraph(&stream_stub, ((void *)0))] to [equal string] [""] 10 | actual value: [" 11 | "] 12 | expected to equal: [""] 13 | 14 | "ParagraphReader": 3 passes, 2 failures in 42ms. 15 | Completed "stream": 3 passes, 2 failures in 42ms. 16 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream6.out: -------------------------------------------------------------------------------- 1 | Running "stream" (5 tests)... 2 | "ParagraphReader": 5 passes in 42ms. 3 | Completed "stream": 5 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream_tests0.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *read_paragraph(int (*read)(void *), void *stream); 5 | 6 | static int empty_stream(void *stream) { 7 | return EOF; 8 | } 9 | 10 | Describe(ParagraphReader); 11 | BeforeEach(ParagraphReader) {} 12 | AfterEach(ParagraphReader) {} 13 | 14 | Ensure(ParagraphReader, gives_null_when_reading_empty_stream) { 15 | assert_that(read_paragraph(&empty_stream, NULL), is_null); 16 | } 17 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream_tests1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *read_paragraph(int (*read)(void *), void *stream); 5 | 6 | static int stream_stub(void *stream) { 7 | return (int)mock(stream); 8 | } 9 | 10 | Describe(ParagraphReader); 11 | BeforeEach(ParagraphReader) {} 12 | AfterEach(ParagraphReader) {} 13 | 14 | Ensure(ParagraphReader, gives_null_when_reading_empty_stream) { 15 | always_expect(stream_stub, will_return(EOF)); // <1> 16 | assert_that(read_paragraph(&stream_stub, NULL), is_null); 17 | } 18 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream_tests2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *read_paragraph(int (*read)(void *), void *stream); 5 | 6 | static int stream_stub(void *stream) { 7 | return (int)mock(stream); 8 | } 9 | 10 | Describe(ParagraphReader); 11 | BeforeEach(ParagraphReader) {} 12 | AfterEach(ParagraphReader) {} 13 | 14 | Ensure(ParagraphReader, gives_null_when_reading_empty_stream) { 15 | always_expect(stream_stub, will_return(EOF)); // <1> 16 | assert_that(read_paragraph(&stream_stub, NULL), is_null); 17 | } 18 | 19 | Ensure(ParagraphReader, gives_one_character_line_for_one_character_stream) { 20 | expect(stream_stub, will_return('a')); 21 | expect(stream_stub, will_return(EOF)); 22 | char *line = read_paragraph(&stream_stub, NULL); 23 | assert_that(line, is_equal_to_string("a")); 24 | free(line); 25 | } 26 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream_tests3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *read_paragraph(int (*read)(void *), void *stream); 5 | 6 | static int stream_stub(void *stream) { 7 | return (int)mock(stream); 8 | } 9 | 10 | Describe(ParagraphReader); 11 | BeforeEach(ParagraphReader) {} 12 | AfterEach(ParagraphReader) {} 13 | 14 | Ensure(ParagraphReader, gives_null_when_reading_empty_stream) { 15 | always_expect(stream_stub, will_return(EOF)); // <1> 16 | assert_that(read_paragraph(&stream_stub, NULL), is_null); 17 | } 18 | 19 | Ensure(ParagraphReader, gives_one_character_line_for_one_character_stream) { 20 | expect(stream_stub, will_return('a')); 21 | expect(stream_stub, will_return(EOF)); 22 | char *line = read_paragraph(&stream_stub, NULL); 23 | assert_that(line, is_equal_to_string("a")); 24 | free(line); 25 | } 26 | 27 | Ensure(ParagraphReader, gives_one_word_line_for_one_word_stream) { 28 | expect(stream_stub, will_return('t')); 29 | expect(stream_stub, will_return('h')); 30 | expect(stream_stub, will_return('e')); 31 | always_expect(stream_stub, will_return(EOF)); 32 | assert_that(read_paragraph(&stream_stub, NULL), is_equal_to_string("the")); 33 | } 34 | -------------------------------------------------------------------------------- /doc/tutorial_src/stream_tests4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *read_paragraph(int (*read)(void *), void *stream); 5 | 6 | static int stream_stub(void *stream) { 7 | return (int)mock(stream); 8 | } 9 | 10 | Describe(ParagraphReader); 11 | BeforeEach(ParagraphReader) {} 12 | AfterEach(ParagraphReader) {} 13 | 14 | Ensure(ParagraphReader, gives_null_when_reading_empty_stream) { 15 | always_expect(stream_stub, will_return(EOF)); // <1> 16 | assert_that(read_paragraph(&stream_stub, NULL), is_null); 17 | } 18 | 19 | Ensure(ParagraphReader, gives_one_character_line_for_one_character_stream) { 20 | expect(stream_stub, will_return('a')); 21 | expect(stream_stub, will_return(EOF)); 22 | char *line = read_paragraph(&stream_stub, NULL); 23 | assert_that(line, is_equal_to_string("a")); 24 | free(line); 25 | } 26 | 27 | Ensure(ParagraphReader, gives_one_word_line_for_one_word_stream) { 28 | expect(stream_stub, will_return('t')); 29 | expect(stream_stub, will_return('h')); 30 | expect(stream_stub, will_return('e')); 31 | always_expect(stream_stub, will_return(EOF)); 32 | assert_that(read_paragraph(&stream_stub, NULL), is_equal_to_string("the")); 33 | } 34 | 35 | Ensure(ParagraphReader, drops_line_ending_from_word_and_stops) { 36 | expect(stream_stub, will_return('t')); 37 | expect(stream_stub, will_return('h')); 38 | expect(stream_stub, will_return('e')); 39 | expect(stream_stub, will_return('\n')); 40 | assert_that(read_paragraph(&stream_stub, NULL), is_equal_to_string("the")); 41 | } 42 | 43 | Ensure(ParagraphReader, gives_empty_line_for_single_line_ending) { 44 | expect(stream_stub, will_return('\n')); 45 | assert_that(read_paragraph(&stream_stub, NULL), is_equal_to_string("")); 46 | } 47 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen1.out: -------------------------------------------------------------------------------- 1 | Running "our_tests" (1 test)... 2 | "our_tests": 1 pass in 42ms. 3 | Completed "our_tests": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen2.out: -------------------------------------------------------------------------------- 1 | Running "our_tests" (1 test)... 2 | "our_tests": 1 pass in 42ms. 3 | Completed "our_tests": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen3.out: -------------------------------------------------------------------------------- 1 | Running "our_tests" (1 test)... 2 | "our_tests": 1 pass in 42ms. 3 | Completed "our_tests": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen4.out: -------------------------------------------------------------------------------- 1 | Running "our_tests" (1 test)... 2 | "our_tests": 1 pass in 42ms. 3 | Completed "our_tests": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen5.out: -------------------------------------------------------------------------------- 1 | Running "our_tests" (1 test)... 2 | "our_tests": 1 pass in 42ms. 3 | Completed "our_tests": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen6.out: -------------------------------------------------------------------------------- 1 | Running "our_tests" (1 test)... 2 | strlen_tests.c:9: Failure: returns_five_for_hello 3 | Expected [strlen("Hiya")] to [equal] [5] 4 | actual value: [4] 5 | expected value: [5] 6 | 7 | "our_tests": 1 failure in 42ms. 8 | Completed "our_tests": 1 failure in 42ms. 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen7.out: -------------------------------------------------------------------------------- 1 | Running "our_tests" (2 tests)... 2 | strlen_tests.c:9: Failure: returns_five_for_hello 3 | Expected [strlen("Hiya")] to [equal] [5] 4 | actual value: [4] 5 | expected value: [5] 6 | 7 | "our_tests": 1 pass, 1 failure in 42ms. 8 | Completed "our_tests": 1 pass, 1 failure in 42ms. 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen_tests1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(Strlen); 5 | BeforeEach(Strlen) {} 6 | AfterEach(Strlen) {} 7 | 8 | Ensure(Strlen, returns_five_for_hello) { 9 | assert_that(strlen("Hello"), is_equal_to(5)); 10 | } 11 | 12 | TestSuite *our_tests() { 13 | TestSuite *suite = create_test_suite(); 14 | add_test_with_context(suite, Strlen, returns_five_for_hello); 15 | return suite; 16 | } 17 | 18 | int main(int argc, char **argv) { 19 | return run_test_suite(our_tests(), create_text_reporter()); 20 | } 21 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen_tests2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(Strlen); // <1> 5 | BeforeEach(Strlen) {} // <2> 6 | AfterEach(Strlen) {} // <3> 7 | 8 | Ensure(Strlen, returns_five_for_hello) { // <4> 9 | assert_that(strlen("Hello"), is_equal_to(5)); 10 | } 11 | 12 | TestSuite *our_tests() { 13 | TestSuite *suite = create_test_suite(); 14 | add_test_with_context(suite, Strlen, returns_five_for_hello); // <5> 15 | return suite; 16 | } 17 | 18 | int main(int argc, char **argv) { 19 | return run_test_suite(our_tests(), create_text_reporter()); 20 | } 21 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen_tests3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | // <1> 4 | Ensure(strlen_returns_five_for_hello) { // <2> 5 | assert_that(strlen("Hello"), is_equal_to(5)); 6 | } 7 | 8 | TestSuite *our_tests() { 9 | TestSuite *suite = create_test_suite(); 10 | add_test(suite, strlen_returns_five_for_hello); // <3> 11 | return suite; 12 | } 13 | 14 | int main(int argc, char **argv) { 15 | return run_test_suite(our_tests(), create_text_reporter()); 16 | } 17 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen_tests4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Ensure(strlen_of_hello_is_five) { 5 | const char *greeting = "Hello"; 6 | int length = strlen(greeting); 7 | assert_equal_with_message(length, 5, "[%s] should be 5, but was %d", greeting, length); 8 | } 9 | 10 | TestSuite *our_tests() { 11 | TestSuite *suite = create_test_suite(); 12 | add_test(suite, strlen_of_hello_is_five); 13 | return suite; 14 | } 15 | 16 | int main(int argc, char **argv) { 17 | return run_test_suite(our_tests(), create_text_reporter()); 18 | } 19 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen_tests5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(Strlen); 5 | BeforeEach(Strlen) {} 6 | AfterEach(Strlen) {} 7 | 8 | Ensure(Strlen, returns_five_for_hello) { 9 | assert_that(strlen("Hello"), is_equal_to(5)); 10 | } 11 | 12 | TestSuite *our_tests() { 13 | TestSuite *suite = create_test_suite(); 14 | add_test_with_context(suite, Strlen, returns_five_for_hello); 15 | return suite; 16 | } 17 | 18 | int main(int argc, char **argv) { 19 | return run_test_suite(our_tests(), create_text_reporter()); 20 | } 21 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen_tests6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(Strlen); 5 | BeforeEach(Strlen) {} 6 | AfterEach(Strlen) {} 7 | 8 | Ensure(Strlen, returns_five_for_hello) { 9 | assert_that(strlen("Hiya"), is_equal_to(5)); 10 | } 11 | 12 | TestSuite *our_tests() { 13 | TestSuite *suite = create_test_suite(); 14 | add_test_with_context(suite, Strlen, returns_five_for_hello); 15 | return suite; 16 | } 17 | 18 | int main(int argc, char **argv) { 19 | return run_test_suite(our_tests(), create_text_reporter()); 20 | } 21 | -------------------------------------------------------------------------------- /doc/tutorial_src/strlen_tests7.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(Strlen); 5 | BeforeEach(Strlen) {} 6 | AfterEach(Strlen) {} 7 | 8 | Ensure(Strlen, returns_five_for_hello) { 9 | assert_that(strlen("Hiya"), is_equal_to(5)); 10 | } 11 | 12 | Ensure(Strlen, returns_zero_for_empty_string) { 13 | assert_equal(strlen("\0"), 0); 14 | } 15 | 16 | TestSuite *our_tests() { 17 | TestSuite *suite = create_test_suite(); 18 | add_test_with_context(suite, Strlen, returns_five_for_hello); 19 | add_test_with_context(suite, Strlen, returns_zero_for_empty_string); 20 | return suite; 21 | } 22 | 23 | int main(int argc, char **argv) { 24 | return run_test_suite(our_tests(), create_text_reporter()); 25 | } 26 | -------------------------------------------------------------------------------- /doc/tutorial_src/struct_parameters.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | Describe(StructParameters); 6 | BeforeEach(StructParameters) {} 7 | AfterEach(StructParameters) {} 8 | 9 | /* 10 | This is uncompilable code that is inserted as a non-example 11 | 12 | typedef struct { 13 | int i; 14 | char *string; 15 | } Struct; 16 | 17 | int function_taking_struct(Struct s) { 18 | return (int)mock(?); 19 | } 20 | */ 21 | 22 | typedef struct { 23 | int i; 24 | char *string; 25 | } Struct; 26 | 27 | int function_checking_a_field(Struct s) { 28 | return (int)mock(s.i); 29 | } 30 | 31 | 32 | Ensure(StructParameters, can_mock_field_in_parameter) { 33 | Struct struct_to_send = { .i = 12, .string = "hello" }; 34 | 35 | expect(function_checking_a_field, when(s.i, is_equal_to(12)), 36 | will_return(12)); 37 | 38 | assert_that(function_checking_a_field(struct_to_send), is_equal_to(12)); 39 | 40 | } 41 | 42 | int function_checking_multiple_fields(Struct s) { 43 | return (int)mock(s.i, s.string); 44 | } 45 | 46 | Ensure(StructParameters, can_mock_muultiple_fields_in_parameter) { 47 | Struct struct_to_send = { .i = 13, .string = "hello world!" }; 48 | 49 | expect(function_checking_multiple_fields, 50 | when(s.i, is_equal_to(13)), 51 | when(s.string, begins_with_string("hello")), 52 | will_return(13)); 53 | 54 | assert_that(function_checking_multiple_fields(struct_to_send), is_equal_to(13)); 55 | } 56 | -------------------------------------------------------------------------------- /doc/tutorial_src/suite1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | TestSuite *our_tests(); 4 | TestSuite *person_tests(); 5 | 6 | int main(int argc, char **argv) { 7 | TestSuite *suite = create_test_suite(); 8 | add_suite(suite, our_tests()); 9 | add_suite(suite, person_tests()); 10 | if (argc > 1) { 11 | return run_single_test(suite, argv[1], create_text_reporter()); 12 | } 13 | return run_test_suite(suite, create_text_reporter()); 14 | } 15 | -------------------------------------------------------------------------------- /doc/tutorial_src/suite1.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/doc/tutorial_src/suite1.out -------------------------------------------------------------------------------- /doc/tutorial_src/suite_person_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "person.h" 5 | 6 | static void create_schema() { 7 | MYSQL *connection = mysql_init(NULL); 8 | mysql_real_connect(connection, "localhost", "me", "secret", "test", 0, NULL, 0); 9 | mysql_query(connection, "create table people (name, varchar(255) unique)"); 10 | mysql_close(connection); 11 | } 12 | 13 | static void drop_schema() { 14 | MYSQL *connection = mysql_init(NULL); 15 | mysql_real_connect(connection, "localhost", "me", "secret", "test", 0, NULL, 0); 16 | mysql_query(connection, "drop table people"); 17 | mysql_close(connection); 18 | } 19 | 20 | Describe(Person); 21 | BeforeEach(Person) { create_schema(); } 22 | AfterEach(Person) { drop_schema(); } 23 | 24 | Ensure(Person, can_add_person_to_database) { 25 | Person *person = create_person(); 26 | set_person_name(person, "Fred"); 27 | save_person(person); 28 | Person *found = find_person_by_name("Fred"); 29 | assert_that(get_person_name(found), is_equal_to_string("Fred")); 30 | } 31 | 32 | Ensure(Person, cannot_add_duplicate_person) { 33 | Person *person = create_person(); 34 | set_person_name(person, "Fred"); 35 | assert_that(save_person(person), is_true); 36 | Person *duplicate = create_person(); 37 | set_person_name(duplicate, "Fred"); 38 | assert_that(save_person(duplicate), is_false); 39 | } 40 | 41 | TestSuite *person_tests() { 42 | TestSuite *suite = create_test_suite(); 43 | add_test_with_context(suite, Person, can_add_person_to_database); 44 | add_test_with_context(suite, Person, cannot_add_duplicate_person); 45 | return suite; 46 | } 47 | -------------------------------------------------------------------------------- /doc/tutorial_src/suite_strlen_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Describe(Strlen); 5 | BeforeEach(Strlen) {} 6 | AfterEach(Strlen) {} 7 | 8 | Ensure(Strlen, returns_five_for_hello) { 9 | assert_that(strlen("Hiya"), is_equal_to(5)); 10 | } 11 | 12 | Ensure(Strlen, returns_zero_for_empty_string) { 13 | assert_equal(strlen("\0"), 0); 14 | } 15 | 16 | TestSuite *our_tests() { 17 | TestSuite *suite = create_test_suite(); 18 | add_test_with_context(suite, Strlen, returns_five_for_hello); 19 | add_test_with_context(suite, Strlen, returns_zero_for_empty_string); 20 | return suite; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /doc/tutorial_src/test_as_xml0.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Describe(XML_reporter); 4 | BeforeEach(XML_reporter) {} 5 | AfterEach(XML_reporter) {} 6 | 7 | Ensure(XML_reporter, reports_a_test_that_passes) { 8 | assert_that(1 == 1); 9 | } 10 | 11 | Ensure(XML_reporter, reports_a_test_that_fails) { 12 | fail_test("A failure"); 13 | } 14 | 15 | TestSuite *create_test_group() { 16 | TestSuite *suite = create_named_test_suite("A Group"); 17 | add_test_with_context(suite, XML_reporter, reports_a_test_that_passes); 18 | add_test_with_context(suite, XML_reporter, reports_a_test_that_fails); 19 | return suite; 20 | } 21 | 22 | int main(int argc, char **argv) { 23 | TestSuite *suite = create_named_test_suite("Top Level"); 24 | add_suite(suite, create_test_group()); 25 | return run_test_suite(suite, create_text_reporter()); 26 | } 27 | -------------------------------------------------------------------------------- /doc/tutorial_src/test_as_xml0.out: -------------------------------------------------------------------------------- 1 | Running "Top Level" (2 tests)... 2 | test_as_xml.c:12: Failure: A Group -> reports_a_test_that_fails 3 | A failure 4 | 5 | "A Group": 1 pass, 1 failure in 42ms. 6 | Completed "Top Level": 1 pass, 1 failure in 42ms. 7 | -------------------------------------------------------------------------------- /doc/tutorial_src/test_as_xml1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include "xml_reporter.h" 5 | 6 | Describe(XML_reporter); 7 | BeforeEach(XML_reporter) {} 8 | AfterEach(XML_reporter) {} 9 | 10 | Ensure(XML_reporter, reports_a_test_that_passes) { 11 | assert_that(1 == 1); 12 | } 13 | 14 | Ensure(XML_reporter, reports_a_test_that_fails) { 15 | fail_test("A failure"); 16 | } 17 | 18 | TestSuite *create_test_group() { 19 | TestSuite *suite = create_named_test_suite("A Group"); 20 | add_test_with_context(suite, XML_reporter, reports_a_test_that_passes); 21 | add_test_with_context(suite, XML_reporter, reports_a_test_that_fails); 22 | return suite; 23 | } 24 | 25 | int main(int argc, char **argv) { 26 | TestSuite *suite = create_named_test_suite("Top Level"); 27 | add_suite(suite, create_test_group()); 28 | return run_test_suite(suite, create_xml_reporter()); 29 | } 30 | -------------------------------------------------------------------------------- /doc/tutorial_src/test_as_xml1.out: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/test_as_xml2.out: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | A failure 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /doc/tutorial_src/test_as_xml3.out: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | A failure 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /doc/tutorial_src/test_as_xml4.out: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | A failure 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /doc/tutorial_src/words.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int split_words(char *sentence) { 4 | int i, count = 1, length = strlen(sentence); 5 | for (i = 0; i < length; i++) { 6 | if (sentence[i] == ' ') { 7 | sentence[i] = '\0'; 8 | count++; 9 | } 10 | } 11 | return count; 12 | } 13 | 14 | void words(const char *sentence, void (*walker)(const char *, void *), void *memo) { 15 | char *words = strdup(sentence); 16 | int word_count = split_words(words); 17 | char *word = words; 18 | while (word_count-- > 0) { 19 | (*walker)(word, memo); 20 | word = word + strlen(word) + 1; 21 | } 22 | free(words); 23 | } 24 | -------------------------------------------------------------------------------- /doc/tutorial_src/words.h: -------------------------------------------------------------------------------- 1 | int split_words(char *sentence); 2 | void words(const char *sentence, void (*callback)(const char *, void *), void *memo); 3 | -------------------------------------------------------------------------------- /doc/tutorial_src/words0.out: -------------------------------------------------------------------------------- 1 | Running "main" (0 tests)... 2 | "words_tests": No assertions. 3 | Completed "main": No assertions. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/words1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int split_words(char *sentence) { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /doc/tutorial_src/words1.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 test)... 2 | words_tests.c:13: Failure: words_tests -> returns_word_count 3 | Expected [word_count] to [equal] [4] 4 | actual value: [0] 5 | expected value: [4] 6 | 7 | "words_tests": 1 failure in 42ms. 8 | Completed "main": 1 failure in 42ms. 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/words2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int split_words(char *sentence) { 4 | int i, count = 1; 5 | for (i = 0; i < strlen(sentence); i++) { 6 | if (sentence[i] == ' ') { 7 | count++; 8 | } 9 | } 10 | return count; 11 | } 12 | -------------------------------------------------------------------------------- /doc/tutorial_src/words2.out: -------------------------------------------------------------------------------- 1 | Running "main" (1 test)... 2 | "words_tests": 1 pass in 42ms. 3 | Completed "main": 1 pass in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/words3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int split_words(char *sentence) { 4 | int i, count = 1; 5 | for (i = 0; i < strlen(sentence); i++) { 6 | if (sentence[i] == ' ') { 7 | sentence[i] = '\0'; 8 | count++; 9 | } 10 | } 11 | return count; 12 | } 13 | -------------------------------------------------------------------------------- /doc/tutorial_src/words3.out: -------------------------------------------------------------------------------- 1 | Running "main" (2 tests)... 2 | words_tests.c:21: Failure: words_tests -> converts_spaces_to_zeroes 3 | Expected [comparison] to [equal] [0] 4 | actual value: [-32] 5 | expected value: [0] 6 | 7 | "words_tests": 1 pass, 1 failure in 42ms. 8 | Completed "main": 1 pass, 1 failure in 42ms. 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/words4.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int split_words(char *sentence) { 4 | int i, count = 1, length = strlen(sentence); 5 | for (i = 0; i < length; i++) { 6 | if (sentence[i] == ' ') { 7 | sentence[i] = '\0'; 8 | count++; 9 | } 10 | } 11 | return count; 12 | } 13 | -------------------------------------------------------------------------------- /doc/tutorial_src/words4.out: -------------------------------------------------------------------------------- 1 | Running "main" (2 tests)... 2 | words_tests.c:13: Failure: words_tests -> returns_word_count 3 | Expected [word_count] to [equal] [4] 4 | actual value: [2] 5 | expected value: [4] 6 | 7 | "words_tests": 1 pass, 1 failure in 42ms. 8 | Completed "main": 1 pass, 1 failure in 42ms. 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/words5.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int split_words(char *sentence) { 4 | int i, count = 1, length = strlen(sentence); 5 | for (i = 0; i < length; i++) { 6 | if (sentence[i] == ' ') { 7 | sentence[i] = '\0'; 8 | count++; 9 | } 10 | } 11 | return count; 12 | } 13 | 14 | void words(const char *sentence, void (*callback)(const char *, void *), void *memo) { 15 | } 16 | -------------------------------------------------------------------------------- /doc/tutorial_src/words5.out: -------------------------------------------------------------------------------- 1 | Running "main" (2 tests)... 2 | "words_tests": 2 passes in 42ms. 3 | Completed "main": 2 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/words6.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int split_words(char *sentence) { 4 | int i, count = 1, length = strlen(sentence); 5 | for (i = 0; i < length; i++) { 6 | if (sentence[i] == ' ') { 7 | sentence[i] = '\0'; 8 | count++; 9 | } 10 | } 11 | return count; 12 | } 13 | 14 | void words(const char *sentence, void (*callback)(const char *, void *), void *memo) { 15 | (*callback)(sentence, memo); 16 | } 17 | -------------------------------------------------------------------------------- /doc/tutorial_src/words6.out: -------------------------------------------------------------------------------- 1 | Running "main" (3 tests)... 2 | words_tests.c:32: Failure: words_tests -> invokes_callback_once_for_single_word_sentence 3 | Expected call was not made to mocked function [mocked_callback] 4 | 5 | "words_tests": 2 passes, 1 failure in 42ms. 6 | Completed "main": 2 passes, 1 failure in 42ms. 7 | -------------------------------------------------------------------------------- /doc/tutorial_src/words7.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int split_words(char *sentence) { 5 | int i, count = 1, length = strlen(sentence); 6 | for (i = 0; i < length; i++) { 7 | if (sentence[i] == ' ') { 8 | sentence[i] = '\0'; 9 | count++; 10 | } 11 | } 12 | return count; 13 | } 14 | 15 | void words(const char *sentence, void (*callback)(const char *, void *), void *memo) { 16 | char *words = strdup(sentence); 17 | int word_count = split_words(words); 18 | char *word = words; 19 | while (word_count-- > 0) { 20 | (*callback)(word, memo); 21 | word = word + strlen(word) + 1; 22 | } 23 | free(words); 24 | } 25 | -------------------------------------------------------------------------------- /doc/tutorial_src/words7.out: -------------------------------------------------------------------------------- 1 | Running "main" (3 tests)... 2 | "words_tests": 4 passes in 42ms. 3 | Completed "main": 4 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/words8.out: -------------------------------------------------------------------------------- 1 | Running "main" (4 tests)... 2 | words_tests.c:38: Failure: words_tests -> invokes_callback_for_each_word_in_a_phrase 3 | Expected [[word] parameter in [mocked_callback]] to [equal string] ["Birds"] 4 | actual value: ["Birds of a feather"] 5 | expected to equal: ["Birds"] 6 | 7 | words_tests.c:39: Failure: words_tests -> invokes_callback_for_each_word_in_a_phrase 8 | Expected call was not made to mocked function [mocked_callback] 9 | 10 | words_tests.c:40: Failure: words_tests -> invokes_callback_for_each_word_in_a_phrase 11 | Expected call was not made to mocked function [mocked_callback] 12 | 13 | words_tests.c:41: Failure: words_tests -> invokes_callback_for_each_word_in_a_phrase 14 | Expected call was not made to mocked function [mocked_callback] 15 | 16 | "words_tests": 4 passes, 4 failures in 42ms. 17 | Completed "main": 4 passes, 4 failures in 42ms. 18 | -------------------------------------------------------------------------------- /doc/tutorial_src/words9.out: -------------------------------------------------------------------------------- 1 | Running "main" (4 tests)... 2 | "words_tests": 8 passes in 42ms. 3 | Completed "main": 8 passes in 42ms. 4 | -------------------------------------------------------------------------------- /doc/tutorial_src/words_tests0.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "words.h" 5 | #include 6 | 7 | Describe(Words); 8 | BeforeEach(Words) {} 9 | AfterEach(Words) {} 10 | 11 | TestSuite *words_tests() { 12 | TestSuite *suite = create_test_suite(); 13 | return suite; 14 | } 15 | -------------------------------------------------------------------------------- /doc/tutorial_src/words_tests1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "words.h" 4 | #include 5 | 6 | Describe(Words); 7 | BeforeEach(Words) {} 8 | AfterEach(Words) {} 9 | 10 | Ensure(Words, returns_word_count) { 11 | char *sentence = strdup("Birds of a feather"); 12 | int word_count = split_words(sentence); 13 | assert_that(word_count, is_equal_to(4)); 14 | free(sentence); 15 | } 16 | 17 | TestSuite *words_tests() { 18 | TestSuite *suite = create_test_suite(); 19 | add_test_with_context(suite, Words, returns_word_count); 20 | return suite; 21 | } 22 | -------------------------------------------------------------------------------- /doc/tutorial_src/words_tests2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "words.h" 4 | #include 5 | 6 | Describe(Words); 7 | BeforeEach(Words) {} 8 | AfterEach(Words) {} 9 | 10 | Ensure(Words, returns_word_count) { 11 | char *sentence = strdup("Birds of a feather"); 12 | int word_count = split_words(sentence); 13 | assert_that(word_count, is_equal_to(4)); 14 | free(sentence); 15 | } 16 | 17 | Ensure(Words, converts_spaces_to_zeroes) { 18 | char *sentence = strdup("Birds of a feather"); 19 | split_words(sentence); 20 | int comparison = memcmp("Birds\0of\0a\0feather", sentence, strlen(sentence)); 21 | assert_that(comparison, is_equal_to(0)); 22 | free(sentence); 23 | } 24 | 25 | TestSuite *words_tests() { 26 | TestSuite *suite = create_test_suite(); 27 | add_test_with_context(suite, Words, returns_word_count); 28 | add_test_with_context(suite, Words, converts_spaces_to_zeroes); 29 | return suite; 30 | } 31 | -------------------------------------------------------------------------------- /doc/tutorial_src/words_tests3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "words.h" 5 | #include 6 | 7 | Describe(Words); 8 | BeforeEach(Words) {} 9 | AfterEach(Words) {} 10 | 11 | Ensure(Words, returns_word_count) { 12 | char *sentence = strdup("Birds of a feather"); 13 | int word_count = split_words(sentence); 14 | assert_that(word_count, is_equal_to(4)); 15 | free(sentence); 16 | } 17 | 18 | Ensure(Words, converts_spaces_to_zeroes) { 19 | char *sentence = strdup("Birds of a feather"); 20 | split_words(sentence); 21 | int comparison = memcmp("Birds\0of\0a\0feather", sentence, strlen(sentence)); 22 | assert_that(comparison, is_equal_to(0)); 23 | free(sentence); 24 | } 25 | 26 | 27 | void mocked_callback(const char *word, void *memo) { 28 | mock(word, memo); 29 | } 30 | 31 | Ensure(Words, invokes_callback_once_for_single_word_sentence) { 32 | expect(mocked_callback, 33 | when(word, is_equal_to_string("Word")), when(memo, is_null)); 34 | words("Word", &mocked_callback, NULL); 35 | } 36 | 37 | TestSuite *words_tests() { 38 | TestSuite *suite = create_test_suite(); 39 | add_test_with_context(suite, Words, returns_word_count); 40 | add_test_with_context(suite, Words, converts_spaces_to_zeroes); 41 | add_test_with_context(suite, Words, invokes_callback_once_for_single_word_sentence); 42 | return suite; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /doc/tutorial_src/words_tests4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "words.h" 5 | #include 6 | 7 | Describe(Words); 8 | BeforeEach(Words) {} 9 | AfterEach(Words) {} 10 | 11 | Ensure(Words, returns_word_count) { 12 | char *sentence = strdup("Birds of a feather"); 13 | int word_count = split_words(sentence); 14 | assert_that(word_count, is_equal_to(4)); 15 | free(sentence); 16 | } 17 | 18 | Ensure(Words, converts_spaces_to_zeroes) { 19 | char *sentence = strdup("Birds of a feather"); 20 | split_words(sentence); 21 | int comparison = memcmp("Birds\0of\0a\0feather", sentence, strlen(sentence)); 22 | assert_that(comparison, is_equal_to(0)); 23 | free(sentence); 24 | } 25 | 26 | 27 | void mocked_callback(const char *word, void *memo) { 28 | mock(word, memo); 29 | } 30 | 31 | Ensure(Words, invokes_callback_once_for_single_word_sentence) { 32 | expect(mocked_callback, 33 | when(word, is_equal_to_string("Word")), when(memo, is_null)); 34 | words("Word", &mocked_callback, NULL); 35 | } 36 | 37 | Ensure(Words, invokes_callback_for_each_word_in_a_phrase) { 38 | expect(mocked_callback, when(word, is_equal_to_string("Birds"))); 39 | expect(mocked_callback, when(word, is_equal_to_string("of"))); 40 | expect(mocked_callback, when(word, is_equal_to_string("a"))); 41 | expect(mocked_callback, when(word, is_equal_to_string("feather"))); 42 | words("Birds of a feather", &mocked_callback, NULL); 43 | } 44 | 45 | TestSuite *words_tests() { 46 | TestSuite *suite = create_test_suite(); 47 | add_test_with_context(suite, Words, returns_word_count); 48 | add_test_with_context(suite, Words, converts_spaces_to_zeroes); 49 | add_test_with_context(suite, Words, invokes_callback_once_for_single_word_sentence); 50 | add_test_with_context(suite, Words, invokes_callback_for_each_word_in_a_phrase); 51 | return suite; 52 | } 53 | -------------------------------------------------------------------------------- /doc/tutorial_src/xml_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef _XML_REPORTER_HEADER_ 2 | #define _XML_REPORTER_HEADER_ 3 | 4 | #include 5 | 6 | TestReporter *create_xml_reporter(); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/xml_reporter0.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "xml_reporter.h" 4 | 5 | TestReporter *create_xml_reporter() { 6 | TestReporter *reporter = create_reporter(); 7 | return reporter; 8 | } 9 | -------------------------------------------------------------------------------- /doc/tutorial_src/xml_reporter1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include "xml_reporter.h" 6 | 7 | 8 | static void xml_reporter_start_suite(TestReporter *reporter, const char *name, int count) { 9 | printf("\n", name); 10 | reporter_start_suite(reporter, name, count); 11 | } 12 | 13 | static void xml_reporter_start_test(TestReporter *reporter, const char *name) { 14 | printf("\n", name); 15 | reporter_start_test(reporter, name); 16 | } 17 | 18 | static void xml_reporter_finish_test(TestReporter *reporter, const char *filename, int line, const char *message) { 19 | reporter_finish_test(reporter, filename, line, message); 20 | printf("\n"); 21 | } 22 | 23 | static void xml_reporter_finish_suite(TestReporter *reporter, const char *filename, int line) { 24 | reporter_finish_suite(reporter, filename, line); 25 | printf("\n"); 26 | } 27 | 28 | TestReporter *create_xml_reporter() { 29 | TestReporter *reporter = create_reporter(); 30 | reporter->start_suite = &xml_reporter_start_suite; 31 | reporter->start_test = &xml_reporter_start_test; 32 | reporter->finish_test = &xml_reporter_finish_test; 33 | reporter->finish_suite = &xml_reporter_finish_suite; 34 | return reporter; 35 | } 36 | -------------------------------------------------------------------------------- /doc/tutorial_src/xml_reporter2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include "xml_reporter.h" 7 | 8 | 9 | static void xml_reporter_start_suite(TestReporter *reporter, const char *name, int count) { 10 | printf("\n", name); 11 | reporter_start_suite(reporter, name, count); 12 | } 13 | 14 | static void xml_reporter_start_test(TestReporter *reporter, const char *name) { 15 | printf("\n", name); 16 | reporter_start_test(reporter, name); 17 | } 18 | 19 | static void xml_show_fail(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments) { 20 | printf("\n"); 21 | printf("\t"); 22 | vprintf(message, arguments); 23 | printf("\n"); 24 | printf("\t\n", file, line); 25 | printf("\n"); 26 | } 27 | 28 | static void xml_reporter_finish_test(TestReporter *reporter, const char *filename, int line, const char *message) { 29 | reporter_finish_test(reporter, filename, line, message); 30 | printf("\n"); 31 | } 32 | 33 | static void xml_reporter_finish_suite(TestReporter *reporter, const char *filename, int line) { 34 | reporter_finish_suite(reporter, filename, line); 35 | printf("\n"); 36 | } 37 | 38 | TestReporter *create_xml_reporter() { 39 | TestReporter *reporter = create_reporter(); 40 | reporter->start_suite = &xml_reporter_start_suite; 41 | reporter->start_test = &xml_reporter_start_test; 42 | reporter->show_fail = &xml_show_fail; 43 | reporter->finish_test = &xml_reporter_finish_test; 44 | reporter->finish_suite = &xml_reporter_finish_suite; 45 | return reporter; 46 | } 47 | -------------------------------------------------------------------------------- /gitrevision.h.in: -------------------------------------------------------------------------------- 1 | /* This file was autogenerated based from cmake */ 2 | #cmakedefine GITREVISION "@GITREVISION@" 3 | 4 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(cgreen) 2 | -------------------------------------------------------------------------------- /include/cgreen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(cgreen_HDRS 2 | assertions.h 3 | boxed_double.h 4 | breadcrumb.h 5 | cdash_reporter.h 6 | cgreen.h 7 | cgreen_value.h 8 | constraint.h 9 | constraint_syntax_helpers.h 10 | cpp_assertions.h 11 | cpp_constraint.h 12 | cute_reporter.h 13 | filename.h 14 | legacy.h 15 | mocks.h 16 | string_comparison.h 17 | reporter.h 18 | runner.h 19 | suite.h 20 | text_reporter.h 21 | unit.h 22 | vector.h 23 | xml_reporter.h 24 | ) 25 | 26 | install( 27 | FILES 28 | ${cgreen_HDRS} 29 | DESTINATION 30 | ${CMAKE_INSTALL_INCLUDEDIR}/${APPLICATION_NAME} 31 | COMPONENT 32 | headers 33 | ) 34 | 35 | add_subdirectory(internal) 36 | -------------------------------------------------------------------------------- /include/cgreen/assertions.h: -------------------------------------------------------------------------------- 1 | #ifndef ASSERTIONS_HEADER 2 | #define ASSERTIONS_HEADER 3 | 4 | #include "internal/assertions_internal.h" 5 | #include "internal/stringify_token.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #ifndef __cplusplus 13 | #include 14 | #endif 15 | 16 | #ifdef __cplusplus 17 | #include 18 | 19 | namespace cgreen { 20 | extern "C" { 21 | #endif 22 | 23 | /* 24 | Modern style asserts using constraints: 25 | 26 | assert_that(actual, (expected)); 27 | assert_that(); 28 | 29 | */ 30 | #define assert_that(...) assert_that_NARG(__VA_ARGS__)(__VA_ARGS__) 31 | #define assert_that_double(actual, constraint) assert_that_double_(FILENAME, __LINE__, STRINGIFY_TOKEN(actual), (double)(actual), (constraint)) 32 | 33 | #define pass_test() assert_true(true) 34 | #define fail_test(...) assert_true_with_message(false, __VA_ARGS__) 35 | #define skip_test() send_reporter_skipped_notification(get_test_reporter()) 36 | 37 | 38 | /* Utility: */ 39 | int get_significant_figures(void); 40 | void significant_figures_for_assert_double_are(int figures); 41 | 42 | #include 43 | 44 | #ifdef __cplusplus 45 | } 46 | } 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/cgreen/boxed_double.h: -------------------------------------------------------------------------------- 1 | #ifndef BOXED_DOUBLE_HEADER 2 | #define BOXED_DOUBLE_HEADER 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | namespace cgreen { 8 | extern "C" { 9 | #endif 10 | 11 | intptr_t box_double(double d); 12 | double as_double(intptr_t boxed_double); 13 | double unbox_double(intptr_t boxed_double); 14 | 15 | typedef union { 16 | double value; 17 | } BoxedDouble; 18 | 19 | #ifdef __cplusplus 20 | } 21 | } 22 | #endif 23 | 24 | #endif /* BOXED_DOUBLE_HEADER */ 25 | -------------------------------------------------------------------------------- /include/cgreen/breadcrumb.h: -------------------------------------------------------------------------------- 1 | #ifndef BREADCRUMB_HEADER 2 | #define BREADCRUMB_HEADER 3 | 4 | struct CgreenBreadcrumb_ { 5 | const char **trail; 6 | int depth; 7 | int space; 8 | }; 9 | 10 | typedef struct CgreenBreadcrumb_ CgreenBreadcrumb; 11 | 12 | #ifdef __cplusplus 13 | namespace cgreen { 14 | extern "C" { 15 | #endif 16 | 17 | CgreenBreadcrumb *create_breadcrumb(void); 18 | void destroy_breadcrumb(CgreenBreadcrumb *breadcrumb); 19 | void push_breadcrumb(CgreenBreadcrumb *breadcrumb, const char *name); 20 | void pop_breadcrumb(CgreenBreadcrumb *breadcrumb); 21 | const char *get_current_from_breadcrumb(CgreenBreadcrumb *breadcrumb); 22 | int get_breadcrumb_depth(CgreenBreadcrumb *breadcrumb); 23 | void walk_breadcrumb(CgreenBreadcrumb *breadcrumb, void (*walker)(const char *, void *), void *memo); 24 | 25 | #ifdef __cplusplus 26 | } 27 | } 28 | #endif 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/cgreen/cdash_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef CDASH_REPORTER_HEADER 2 | #define CDASH_REPORTER_HEADER 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | namespace cgreen { 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct CDashInfo_ CDashInfo; 13 | struct CDashInfo_ { 14 | char *name; 15 | char *build; 16 | char *type; 17 | char *hostname; 18 | char *os_name; 19 | char *os_platform; 20 | char *os_release; 21 | char *os_version; 22 | }; 23 | 24 | extern TestReporter *create_cdash_reporter(CDashInfo *cdash); 25 | 26 | #ifdef __cplusplus 27 | } 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/cgreen/cgreen.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define CGREEN_VERSION "1.6.4" 13 | #define CGREEN_VERSION_MAJOR 1 14 | #define CGREEN_VERSION_MINOR 6 15 | #define CGREEN_VERSION_PATCH 4 16 | 17 | extern char *cgreen_library_version; 18 | extern char *cgreen_library_revision; 19 | -------------------------------------------------------------------------------- /include/cgreen/cgreen_value.h: -------------------------------------------------------------------------------- 1 | #ifndef CGREEN_VALUE_HEADER 2 | #define CGREEN_VALUE_HEADER 3 | 4 | #include 5 | #include 6 | 7 | typedef enum { 8 | CGREEN_INTEGER, 9 | CGREEN_STRING, 10 | CGREEN_DOUBLE, 11 | CGREEN_POINTER, 12 | CGREEN_BYVALUE 13 | } CgreenValueType; 14 | 15 | typedef struct { 16 | CgreenValueType type; 17 | union { 18 | intptr_t integer_value; 19 | double double_value; 20 | void *pointer_value; 21 | const char *string_value; 22 | } value; 23 | size_t value_size; 24 | } CgreenValue; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/cgreen/cpp_assertions.h: -------------------------------------------------------------------------------- 1 | #ifndef CGREEN_CPP_ASSERTIONS_H 2 | #define CGREEN_CPP_ASSERTIONS_H 3 | 4 | #include "internal/stringify_token.h" 5 | 6 | #define assert_throws(exceptionType, expr) \ 7 | try { \ 8 | expr; \ 9 | fail_test("Expected [" STRINGIFY_TOKEN(expr) "] " \ 10 | "to throw [" STRINGIFY_TOKEN(exceptionType) "]"); \ 11 | } catch (const exceptionType& ex) { \ 12 | pass_test(); \ 13 | } catch (const exceptionType* ex) { \ 14 | pass_test(); \ 15 | } 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/cgreen/cute_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef CUTE_REPORTER_HEADER 2 | #define CUTE_REPORTER_HEADER 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | extern TestReporter *create_cute_reporter(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/cgreen/filename.h: -------------------------------------------------------------------------------- 1 | #ifndef FILENAME_HEADER 2 | #define FILENAME_HEADER 3 | 4 | #ifdef __cplusplus 5 | namespace cgreen { 6 | extern "C" { 7 | #endif 8 | 9 | #ifndef FILENAME 10 | #define FILENAME __FILE__ 11 | #endif 12 | 13 | #ifdef __cplusplus 14 | } 15 | } 16 | #endif 17 | 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/cgreen/internal/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(cgreen_internal_HDRS 2 | unit_implementation.h 3 | mock_table.h 4 | mocks_internal.h 5 | suite_internal.h 6 | assertions_internal.h 7 | c_assertions.h 8 | cpp_assertions.h 9 | cgreen_pipe.h 10 | cgreen_time.h 11 | runner_platform.h 12 | function_macro.h 13 | stringify_token.h 14 | ) 15 | 16 | install( 17 | FILES 18 | ${cgreen_internal_HDRS} 19 | DESTINATION 20 | ${CMAKE_INSTALL_INCLUDEDIR}/${APPLICATION_NAME}/internal 21 | COMPONENT 22 | headers 23 | ) 24 | -------------------------------------------------------------------------------- /include/cgreen/internal/android_headers/androidcompat.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert *printf family for display via Android Studio/Eclipse logcat 3 | * 4 | * Usage 5 | * Simply include in cgreen .c/.cpp files containing *printf statements e.g. 6 | * ------------------------------------------------------------ 7 | * #ifdef __ANDROID__ 8 | * #include "cgreen/internal/android_headers/androidcompat.h" 9 | * #endif // #ifdef __ANDROID__ 10 | * ------------------------------------------------------------ 11 | * 12 | * Created 9 Aug 2016, Steve Madsen, London UK 13 | */ 14 | #pragma once 15 | 16 | #ifdef __ANDROID__ 17 | #include 18 | #define ANDROID_MODULE_LOG_TAG "CGreenUnitTests" 19 | #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, ANDROID_MODULE_LOG_TAG, __VA_ARGS__) 20 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, ANDROID_MODULE_LOG_TAG, __VA_ARGS__) 21 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, ANDROID_MODULE_LOG_TAG, __VA_ARGS__) 22 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, ANDROID_MODULE_LOG_TAG, __VA_ARGS__) 23 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, ANDROID_MODULE_LOG_TAG, __VA_ARGS__) 24 | #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, ANDROID_MODULE_LOG_TAG, __VA_ARGS__) 25 | 26 | // Note: "##" ensures preceding comma will be deleted if "..." empty 27 | #define printf(fmt, ...) LOGE(fmt, ##__VA_ARGS__) 28 | #define fprintf(stderr, ...) LOGE(__VA_ARGS__) 29 | #define vprintf(fmt, ...) LOGE(fmt, ##__VA_ARGS__) 30 | #endif // #ifdef __ANDROID__ 31 | -------------------------------------------------------------------------------- /include/cgreen/internal/c_assertions.h: -------------------------------------------------------------------------------- 1 | #ifndef C_ASSERTIONS_HEADER 2 | #define C_ASSERTIONS_HEADER 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "stringify_token.h" 9 | 10 | #ifndef __cplusplus 11 | #define assert_that_constraint(actual, constraint) assert_core_(FILENAME, __LINE__, STRINGIFY_TOKEN(actual), (intptr_t)(actual), (constraint)) 12 | #endif 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | void assert_core_(const char *file, int line, const char *actual_string, intptr_t actual, Constraint *constraint); 19 | void assert_that_double_(const char *file, int line, const char *expression, double actual, Constraint* constraint); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/cgreen/internal/cgreen_pipe.h: -------------------------------------------------------------------------------- 1 | #ifndef CGREEN_PIPE_HEADER 2 | #define CGREEN_PIPE_HEADER 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | namespace cgreen { 8 | extern "C" { 9 | #endif 10 | 11 | int cgreen_pipe_open(int pipes[2]); 12 | void cgreen_pipe_close(int p); 13 | ssize_t cgreen_pipe_read(int p, void *buf, size_t count); 14 | ssize_t cgreen_pipe_write(int p, const void *buf, size_t count); 15 | 16 | #ifdef __cplusplus 17 | } 18 | } 19 | #endif 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/cgreen/internal/cgreen_time.h: -------------------------------------------------------------------------------- 1 | #ifndef CGREEN_TIME_HEADER 2 | #define CGREEN_TIME_HEADER 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | namespace cgreen { 8 | extern "C" { 9 | #endif 10 | 11 | uint32_t cgreen_time_get_current_milliseconds(void); 12 | uint32_t cgreen_time_duration_in_milliseconds(uint32_t start_time_in_milliseconds, uint32_t end_time_in_milliseconds); 13 | 14 | #ifdef __cplusplus 15 | } 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/cgreen/internal/function_macro.h: -------------------------------------------------------------------------------- 1 | // include this header when using the __func__ macro 2 | // this is where platforms that don't have C99 __func__ will be handled 3 | #ifndef __func__ 4 | # ifdef _MSC_VER 5 | # define __func__ __FUNCTION__ 6 | # endif 7 | #endif 8 | -------------------------------------------------------------------------------- /include/cgreen/internal/mocks_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef MOCKS_INTERNAL_H 2 | #define MOCKS_INTERNAL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | #ifdef __GNUC__ 13 | #define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 14 | #else 15 | #define WARN_UNUSED_RESULT 16 | #endif 17 | 18 | #ifdef __cplusplus 19 | namespace cgreen { 20 | extern "C" { 21 | #endif 22 | 23 | extern void expect_(TestReporter *test_reporter, const char *function, const char *test_file, int test_line, ...); 24 | extern void always_expect_(TestReporter *test_reporter, const char *function, const char *test_file, int test_line, 25 | ...); 26 | extern void never_expect_(TestReporter *test_reporter, const char *function, const char *test_file, int test_line, 27 | ...); 28 | extern intptr_t mock_(TestReporter *test_reporter, const char *function, const char *mock_file, int mock_line, 29 | const char *parameters, ...); 30 | 31 | 32 | /* Warning for unused results from 'when()' helps detecting slip-ups in the expect(): 33 | 34 | expect(mocked_function, will_return(true)), 35 | when(param, is_equal_to(5)); 36 | 37 | Note the extra parenthesis at the end of the first line. Thanks to 38 | the comma operator, this effectively creates a mock expectation 39 | which silently ignores the constraints on its parameter(s), and 40 | passes the test case. /@awilke 41 | 42 | */ 43 | extern Constraint *when_(const char *parameter, Constraint *constraint) WARN_UNUSED_RESULT; 44 | 45 | extern Constraint *times_(int number_times_called); 46 | 47 | extern void clear_mocks(void); 48 | extern void tally_mocks(TestReporter *reporter); 49 | 50 | #ifdef __cplusplus 51 | } 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/cgreen/internal/runner_platform.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_PLATFORM_HEADER 2 | #define RUNNER_PLATFORM_HEADER 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | namespace cgreen { 9 | extern "C" { 10 | #endif 11 | 12 | void run_specified_test_if_child(TestSuite *suite, TestReporter *reporter); 13 | void run_test_in_its_own_process(TestSuite *suite, CgreenTest *test, TestReporter *reporter); 14 | void die(const char *message, ...); 15 | void run_the_test_code(TestSuite *suite, CgreenTest *spec, TestReporter *reporter); 16 | 17 | #ifdef __cplusplus 18 | } 19 | } 20 | #endif 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /include/cgreen/internal/stringify_token.h: -------------------------------------------------------------------------------- 1 | #ifndef STRINGIFY_TOKEN_HEADER 2 | #define STRINGIFY_TOKEN_HEADER 3 | 4 | #define STRINGIFY_TOKEN(token) #token 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /include/cgreen/internal/suite_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef SUITE_INTERNAL_HEADER 2 | #define SUITE_INTERNAL_HEADER 3 | 4 | #include "cgreen/unit.h" 5 | 6 | 7 | enum {test_function, test_suite}; 8 | 9 | typedef struct TestSuite_ TestSuite; 10 | 11 | typedef struct { 12 | int type; 13 | const char *name; 14 | union { 15 | CgreenTest *test; 16 | TestSuite *suite; 17 | } Runnable; 18 | } UnitTest; 19 | 20 | struct TestSuite_ { 21 | const char *name; 22 | const char* filename; 23 | int line; 24 | UnitTest *tests; 25 | void (*setup)(void); 26 | void (*teardown)(void); 27 | int size; 28 | }; 29 | 30 | #ifdef __cplusplus 31 | namespace cgreen { 32 | extern "C" { 33 | #endif 34 | 35 | void do_nothing(void); 36 | 37 | TestSuite *create_named_test_suite_(const char *name, const char *filename, int line); 38 | void add_test_(TestSuite *suite, const char *name, CgreenTest *test); 39 | void add_tests_(TestSuite *suite, const char *names, ...); 40 | void add_suite_(TestSuite *owner, const char *name, TestSuite *suite); 41 | 42 | #ifdef __cplusplus 43 | } 44 | } 45 | #endif 46 | 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /include/cgreen/internal/windows_headers/stdbool.h: -------------------------------------------------------------------------------- 1 | #ifndef __STDBOOL_H__ 2 | #define __STDBOOL_H__ 3 | 4 | #ifndef __cplusplus 5 | 6 | typedef unsigned int bool; 7 | 8 | #define true 1 9 | #define false 0 10 | 11 | #endif //__cplusplus 12 | 13 | #endif //__STDBOOL_H__ -------------------------------------------------------------------------------- /include/cgreen/internal/windows_headers/unistd.h: -------------------------------------------------------------------------------- 1 | #ifndef _UNISTD_H 2 | #define _UNISTD_H 1 3 | 4 | /* This file intended to serve as a drop-in replacement for 5 | * unistd.h on Windows 6 | * Please add functionality as neeeded 7 | */ 8 | 9 | #include 10 | #include 11 | //CMB - not needed for cgreen! 12 | //#include /* getopt from: http://www.pwilson.net/sample.html. */ 13 | #include /* for getpid() and the exec..() family */ 14 | 15 | #define srandom srand 16 | #define random rand 17 | 18 | /* Values for the second argument to access. 19 | These may be OR'd together. */ 20 | #define R_OK 4 /* Test for read permission. */ 21 | #define W_OK 2 /* Test for write permission. */ 22 | //#define X_OK 1 /* execute permission - unsupported in windows*/ 23 | #define F_OK 0 /* Test for existence. */ 24 | 25 | #define access _access 26 | #define ftruncate _chsize 27 | 28 | #define ssize_t int 29 | 30 | #define STDIN_FILENO 0 31 | #define STDOUT_FILENO 1 32 | #define STDERR_FILENO 2 33 | /* should be in some equivalent to */ 34 | /* 35 | typedef __int8 int8_t; 36 | typedef __int16 int16_t; 37 | typedef __int32 int32_t; 38 | typedef __int64 int64_t; 39 | typedef unsigned __int8 uint8_t; 40 | typedef unsigned __int16 uint16_t; 41 | typedef unsigned __int32 uint32_t; 42 | typedef unsigned __int64 uint64_t; 43 | */ 44 | #define pipe(x) _pipe(x,256,0) 45 | 46 | #endif /* unistd.h */ -------------------------------------------------------------------------------- /include/cgreen/internal/windows_headers/wincompat.h: -------------------------------------------------------------------------------- 1 | #ifndef __WINCOMPAT_H__ 2 | #define __WINCOMPAT_H__ 3 | #ifdef _MSC_VER 4 | #include "stdarg.h" 5 | #include "windows.h" 6 | #include "direct.h" 7 | 8 | #define gmtime_r(x,y) gmtime_s(y,x) 9 | 10 | typedef int pid_t; 11 | 12 | #if _MSC_VER < 1900 13 | #define snprintf sprintf_s 14 | #endif 15 | 16 | #define sleep(x) Sleep(x*1000) 17 | #define mkdir(x,y) _mkdir(x) 18 | #define sched_yield() SleepEx (0,0) 19 | 20 | #define CGREEN_READ_HANDLE "CGREEN_READ_HANDLE" 21 | #define CGREEN_WRITE_HANDLE "CGREEN_WRITE_HANDLE" 22 | #define CGREEN_TEST_TO_RUN "CGREEN_TEST_TO_RUN" 23 | 24 | #ifdef __cplusplus 25 | #define PRIdPTR "Id" 26 | #endif 27 | 28 | #endif //_MSC_VER 29 | #endif //__WINCOMPAT_H__ 30 | 31 | -------------------------------------------------------------------------------- /include/cgreen/message_formatting.h: -------------------------------------------------------------------------------- 1 | #ifndef CGREEN_MESSAGE_FORMATTING_H 2 | #define CGREEN_MESSAGE_FORMATTING_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | namespace cgreen { 9 | extern "C" { 10 | #endif 11 | 12 | char *failure_message_for(Constraint *constraint, const char *actual_string, intptr_t actual); 13 | char *validation_failure_message_for(Constraint *constraint, intptr_t actual); 14 | bool parameters_are_not_valid_for(Constraint *constraint, intptr_t actual); 15 | 16 | #ifdef __cplusplus 17 | } 18 | } 19 | #endif 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/cgreen/messaging.h: -------------------------------------------------------------------------------- 1 | #ifndef MESSAGING_HEADER 2 | #define MESSAGING_HEADER 3 | 4 | #ifdef __cplusplus 5 | namespace cgreen { 6 | extern "C" { 7 | #endif 8 | 9 | int start_cgreen_messaging(int tag); 10 | void send_cgreen_message(int messaging, int result); 11 | int receive_cgreen_message(int messaging); 12 | int get_pipe_read_handle(void); 13 | int get_pipe_write_handle(void); 14 | 15 | #ifdef __cplusplus 16 | } 17 | } 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/cgreen/runner.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_HEADER 2 | #define RUNNER_HEADER 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | namespace cgreen { 9 | extern "C" { 10 | #endif 11 | 12 | 13 | int run_test_suite(TestSuite *suite, TestReporter *reporter); 14 | int run_single_test(TestSuite *suite, const char *test, TestReporter *reporter); 15 | void die_in(unsigned int seconds); 16 | 17 | #ifdef __cplusplus 18 | } 19 | } 20 | #endif 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/cgreen/string_comparison.h: -------------------------------------------------------------------------------- 1 | #ifndef CGREEN_STRING_COMPARISON_H 2 | #define CGREEN_STRING_COMPARISON_H 3 | 4 | #ifndef __cplusplus 5 | #include 6 | #endif 7 | #include 8 | 9 | #ifdef __cplusplus 10 | namespace cgreen { 11 | extern "C" { 12 | #endif 13 | 14 | bool strings_are_equal(const char *tried, const char *expected); 15 | bool string_contains(const char *actual, const char *expected); 16 | 17 | #ifdef __cplusplus 18 | } 19 | } 20 | #endif 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/cgreen/suite.h: -------------------------------------------------------------------------------- 1 | #ifndef SUITE_HEADER 2 | #define SUITE_HEADER 3 | 4 | #include "internal/suite_internal.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #ifndef __cplusplus 11 | #include 12 | #endif 13 | 14 | 15 | #ifdef __cplusplus 16 | namespace cgreen { 17 | extern "C" { 18 | #endif 19 | 20 | #define create_test_suite() create_named_test_suite_(__func__, FILENAME, __LINE__) 21 | #define create_named_test_suite(name) create_named_test_suite_(name, FILENAME, __LINE__) 22 | #define add_test(suite, test) add_test_(suite, STRINGIFY_TOKEN(test), &spec_name(default, test)) 23 | #define add_test_with_context(suite, context, test) add_test_(suite, STRINGIFY_TOKEN(test), &spec_name(context, test)) 24 | #define add_tests(suite, ...) add_tests_(suite, #__VA_ARGS__, (CgreenTest *)__VA_ARGS__) 25 | #define add_suite(owner, suite) add_suite_(owner, STRINGIFY_TOKEN(suite), suite) 26 | 27 | void set_setup(TestSuite *suite, void (*set_up)(void)); 28 | void set_teardown(TestSuite *suite, void (*tear_down)(void)); 29 | int count_tests(TestSuite *suite); 30 | bool has_test(TestSuite *suite, const char *name); 31 | bool has_setup(TestSuite *suite); 32 | bool has_teardown(TestSuite *suite); 33 | void destroy_test_suite(TestSuite *suite); 34 | 35 | #ifdef __cplusplus 36 | } 37 | } 38 | #endif 39 | 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /include/cgreen/text_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXT_REPORTER_HEADER 2 | #define TEXT_REPORTER_HEADER 3 | 4 | #include 5 | 6 | #ifndef __cplusplus 7 | #include 8 | #endif 9 | 10 | #ifdef __cplusplus 11 | namespace cgreen { 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct text_reporter_options { 16 | bool use_colours; 17 | bool quiet_mode; 18 | bool inhibit_start_suite_message; 19 | bool inhibit_finish_suite_message; 20 | } TextReporterOptions; 21 | 22 | TestReporter *create_text_reporter(void); 23 | 24 | #ifdef __cplusplus 25 | } 26 | } 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/cgreen/unit.h: -------------------------------------------------------------------------------- 1 | #ifndef UNIT_HEADER 2 | #define UNIT_HEADER 3 | 4 | #include "internal/unit_implementation.h" 5 | 6 | #ifdef __cplusplus 7 | namespace cgreen { 8 | extern "C" { 9 | #endif 10 | 11 | /* BDD style: Describe the Subject Under Test, or context, by name */ 12 | #define Describe(subject) DescribeImplementation(subject) 13 | 14 | /* BDD style: Run this before any tests for that SUT or in that context */ 15 | #define BeforeEach(subject) BeforeEachImplementation(subject) 16 | 17 | /* BDD style: Run this after any tests for that SUT or in that context */ 18 | #define AfterEach(subject) AfterEachImplementation(subject) 19 | 20 | /* NOTE if you use BDD style all three of the above are required */ 21 | /* Then you must also use the BDD style Ensure(subject, test) */ 22 | 23 | /* TDD Style: Ensure(testname) {implementation} */ 24 | /* BDD Style: Ensure(subject, testname) {implementation} */ 25 | #define Ensure(...) Ensure_NARG(0, __VA_ARGS__)(0, __VA_ARGS__) 26 | 27 | /* Temporarily ignore this test */ 28 | #define xEnsure(...) Ensure_NARG(1, __VA_ARGS__)(1, __VA_ARGS__) 29 | 30 | #ifdef __cplusplus 31 | } 32 | } 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/cgreen/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef VECTOR_HEADER 2 | #define VECTOR_HEADER 3 | 4 | #ifdef __cplusplus 5 | namespace cgreen { 6 | extern "C" { 7 | #endif 8 | 9 | typedef void (*GenericDestructor)(void *); 10 | typedef struct CgreenVector_ CgreenVector; 11 | 12 | CgreenVector *create_cgreen_vector(GenericDestructor destructor); 13 | void destroy_cgreen_vector(CgreenVector *vector); 14 | void cgreen_vector_add(CgreenVector *vector, void *item); 15 | void *cgreen_vector_remove(CgreenVector *vector, int position); 16 | void *cgreen_vector_get(const CgreenVector *vector, int position); 17 | int cgreen_vector_size(const CgreenVector *vector); 18 | 19 | #ifdef __cplusplus 20 | } 21 | } 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/cgreen/xml_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef _XML_REPORTER_HEADER_ 2 | #define _XML_REPORTER_HEADER_ 3 | 4 | #include "cgreen/reporter.h" 5 | 6 | #ifndef __cplusplus 7 | #include 8 | #endif 9 | 10 | #ifdef __cplusplus 11 | namespace cgreen { 12 | extern "C" { 13 | #endif 14 | 15 | TestReporter *create_xml_reporter(const char *prefix); 16 | TestReporter *create_libxml_reporter(const char *prefix); 17 | 18 | #ifdef __cplusplus 19 | } 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /linux-setup.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # When you run "make test" CMake obviously runs the correct binraries 4 | # from the build directory. But when you want to run a test manually 5 | # PATH and LD_LIBRARY_PATH need to be set, and it is tedious and error 6 | # prone to remember that all the time. 7 | # 8 | # The follwing sets up the current shell in the same way, so that a 9 | # developer can just source this script and then forget about it. 10 | # 11 | 12 | # Ensure that the script is sourced: 13 | if [[ $_ == $0 ]]; then 14 | echo "You should really source this, like in '. cygwin-setup.sh'" 15 | fi 16 | 17 | # And here's the meat given that you have the standard build tree 18 | export PATH="$PWD/build/tools":$PATH 19 | export LD_LIBRARY_PATH="$PWD/build/src":$PATH 20 | -------------------------------------------------------------------------------- /samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(${CGREEN_PUBLIC_INCLUDE_DIRS} ${PROJECT_BINARY_DIR}) 2 | add_executable(sample sample.c) 3 | -------------------------------------------------------------------------------- /samples/Makefile: -------------------------------------------------------------------------------- 1 | sample: sample.o 2 | $(CC) -o sample sample.o -lcgreen 3 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | cd ..; make --no-print-directory unit 3 | -------------------------------------------------------------------------------- /src/boxed_double.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* NOTE: while returning BoxedDouble* here seems logical, it forces casts all over the place */ 6 | intptr_t box_double(double value) { 7 | BoxedDouble *box = (BoxedDouble *) malloc(sizeof(BoxedDouble)); 8 | box->value = value; 9 | return (intptr_t)box; 10 | } 11 | 12 | double unbox_double(intptr_t box) { 13 | double value = as_double(box); 14 | free((BoxedDouble *)box); 15 | return value; 16 | } 17 | 18 | double as_double(intptr_t box) { 19 | return ((BoxedDouble *)box)->value; 20 | } 21 | -------------------------------------------------------------------------------- /src/breadcrumb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | CgreenBreadcrumb *create_breadcrumb(void) { 6 | CgreenBreadcrumb *breadcrumb = (CgreenBreadcrumb *) malloc(sizeof(CgreenBreadcrumb)); 7 | if (breadcrumb == NULL) { 8 | return NULL; 9 | } 10 | breadcrumb->trail = NULL; 11 | breadcrumb->depth = 0; 12 | breadcrumb->space = 0; 13 | return breadcrumb; 14 | } 15 | 16 | void destroy_breadcrumb(CgreenBreadcrumb *breadcrumb) { 17 | free((void*)breadcrumb->trail); 18 | free((void*)breadcrumb); 19 | } 20 | 21 | void push_breadcrumb(CgreenBreadcrumb *breadcrumb, const char *name) { 22 | breadcrumb->depth++; 23 | if (breadcrumb->depth > breadcrumb->space) { 24 | const char **tmp; 25 | breadcrumb->space++; 26 | tmp = (const char**) realloc((void*)breadcrumb->trail, 27 | sizeof(const char *) * breadcrumb->space); 28 | if (tmp == NULL) { 29 | breadcrumb->space--; 30 | breadcrumb->depth--; 31 | return; 32 | } 33 | breadcrumb->trail = tmp; 34 | } 35 | breadcrumb->trail[breadcrumb->depth - 1] = name; 36 | } 37 | 38 | void pop_breadcrumb(CgreenBreadcrumb *breadcrumb) { 39 | breadcrumb->depth--; 40 | } 41 | 42 | const char *get_current_from_breadcrumb(CgreenBreadcrumb *breadcrumb) { 43 | if (get_breadcrumb_depth(breadcrumb) == 0) { 44 | return NULL; 45 | } 46 | 47 | return breadcrumb->trail[breadcrumb->depth - 1]; 48 | } 49 | 50 | int get_breadcrumb_depth(CgreenBreadcrumb *breadcrumb) { 51 | return breadcrumb->depth; 52 | } 53 | 54 | void walk_breadcrumb(CgreenBreadcrumb *breadcrumb, void (*walker)(const char *, void *), void *memo) { 55 | int i; 56 | for (i = 0; i < breadcrumb->depth; i++) { 57 | (*walker)(breadcrumb->trail[i], memo); 58 | } 59 | } 60 | 61 | /* vim: set ts=4 sw=4 et cindent: */ 62 | -------------------------------------------------------------------------------- /src/cdash_reporter_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef CDASH_REPORTER_INTERNAL_H 2 | #define CDASH_REPORTER_INTERNAL_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef int CDashPrinter(FILE *, const char *format, ...); 11 | typedef int CDashVPrinter(FILE *, const char *format, va_list arguments); 12 | void set_cdash_reporter_printer(TestReporter *reporter, CDashPrinter *printer); 13 | void set_cdash_reporter_vprinter(TestReporter *reporter, CDashVPrinter *vprinter); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/cgreen_time.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cgreen/internal/cgreen_time.h" 3 | 4 | uint32_t cgreen_time_duration_in_milliseconds(uint32_t start_time_in_milliseconds, 5 | uint32_t end_time_in_milliseconds) { 6 | if (end_time_in_milliseconds < start_time_in_milliseconds) { 7 | return 0; 8 | } 9 | 10 | return end_time_in_milliseconds - start_time_in_milliseconds; 11 | } 12 | -------------------------------------------------------------------------------- /src/cgreen_value.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static char *stringdup(const char *string) { 8 | if (string == NULL) 9 | return NULL; 10 | else 11 | return strcpy((char *)malloc(strlen(string)+1), string); 12 | } 13 | 14 | CgreenValue *create_cgreen_value(CgreenValue value) { 15 | CgreenValue *ptr = (CgreenValue*)malloc(sizeof(CgreenValue)); 16 | *ptr = value; 17 | return ptr; 18 | } 19 | 20 | CgreenValue make_cgreen_integer_value(intptr_t integer) { 21 | CgreenValue value = {CGREEN_INTEGER, {0}, sizeof(intptr_t)}; 22 | value.value.integer_value = integer; 23 | return value; 24 | } 25 | 26 | CgreenValue make_cgreen_string_value(const char *string) { 27 | CgreenValue value = {CGREEN_STRING, {0}, sizeof(const char *)}; 28 | value.value.string_value = stringdup(string); 29 | return value; 30 | } 31 | 32 | CgreenValue make_cgreen_pointer_value(void *pointer) { 33 | CgreenValue value = {CGREEN_POINTER, {0}, sizeof(intptr_t)}; 34 | value.value.pointer_value = pointer; 35 | return value; 36 | } 37 | 38 | CgreenValue make_cgreen_double_value(double d) { 39 | CgreenValue value = {CGREEN_DOUBLE, {0}, sizeof(intptr_t)}; 40 | value.value.double_value = d; 41 | return value; 42 | } 43 | 44 | CgreenValue make_cgreen_by_value(void *pointer, size_t size) { 45 | CgreenValue value = {CGREEN_BYVALUE, {0}, size}; 46 | value.value.pointer_value = pointer; 47 | return value; 48 | } 49 | 50 | void destroy_cgreen_value(CgreenValue value) { 51 | if (value.type == CGREEN_STRING) 52 | free((void *)value.value.string_value); 53 | else if (value.type == CGREEN_BYVALUE) 54 | free(value.value.pointer_value); 55 | } 56 | -------------------------------------------------------------------------------- /src/cgreen_value_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef CGREEN_VALUE_INTERNAL_H 2 | #define CGREEN_VALUE_INTERNAL_H 3 | 4 | #include 5 | 6 | /* CgreenValues are used from some user level tests so must be compilable in C++ */ 7 | #ifdef __cplusplus 8 | namespace cgreen { 9 | extern "C" { 10 | #endif 11 | 12 | extern CgreenValue *create_cgreen_value(CgreenValue value); 13 | extern CgreenValue make_cgreen_integer_value(intptr_t integer); 14 | extern CgreenValue make_cgreen_string_value(const char *string); 15 | extern CgreenValue make_cgreen_double_value(double value); 16 | extern CgreenValue make_cgreen_pointer_value(void *ptr); 17 | extern CgreenValue make_cgreen_by_value(void *pointer, size_t size); 18 | extern void destroy_cgreen_value(CgreenValue value); 19 | 20 | #ifdef __cplusplus 21 | } 22 | } 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/constraint_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSTRAINT_INTERNAL_H 2 | #define CONSTRAINT_INTERNAL_H 3 | 4 | #include 5 | 6 | /* constraints internal functions are used from some user level tests so must be compilable in C++ */ 7 | #ifdef __cplusplus 8 | namespace cgreen { 9 | extern "C" { 10 | #endif 11 | 12 | extern void destroy_empty_constraint(Constraint *constraint); 13 | extern void destroy_static_constraint(Constraint *constraint); 14 | extern void destroy_string_constraint(Constraint *constraint); 15 | extern void destroy_double_constraint(Constraint *constraint); 16 | extern void destroy_by_value_constraint(Constraint *constraint); 17 | extern void destroy_constraint(Constraint *); 18 | extern void destroy_constraints(va_list constraints); 19 | 20 | 21 | extern bool no_expected_value_in(const Constraint *constraint); 22 | extern bool values_are_strings_in(const Constraint *constraint); 23 | extern bool is_content_comparing(const Constraint *constraint); 24 | extern bool is_content_setting(const Constraint *constraint); 25 | extern bool is_not_content_setting(const Constraint *constraint); 26 | extern bool is_string_comparing(const Constraint *constraint); 27 | extern bool is_double_comparing(const Constraint *constraint); 28 | extern bool is_comparing(const Constraint *constraint); 29 | extern bool is_not_comparing(const Constraint *constraint); 30 | extern bool is_parameter(const Constraint *); 31 | extern bool constraint_is_not_for_parameter(const Constraint *, const char *); 32 | extern bool constraint_is_for_parameter(const Constraint *, const char *); 33 | extern bool constraint_is_for_parameter_in(const Constraint *, const char *); 34 | extern bool doubles_are_equal(double tried, double expected); 35 | extern bool double_is_lesser(double actual, double expected); 36 | extern bool double_is_greater(double actual, double expected); 37 | 38 | 39 | #ifdef __cplusplus 40 | } 41 | } 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/cute_reporter_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef CUTE_REPORTER_INTERNAL_H 2 | #define CUTE_REPORTER_INTERNAL_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef int CutePrinter(const char *format, ...); 11 | typedef int CuteVPrinter(const char *format, va_list arguments); 12 | 13 | extern void set_cute_reporter_printer(TestReporter *reporter, CutePrinter *printer); 14 | extern void set_cute_reporter_vprinter(TestReporter *reporter, CuteVPrinter *vprinter); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/libxml_reporter_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef XML_REPORTER_INTERNAL_H 2 | #define XML_REPORTER_INTERNAL_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef int XmlPrinter(xmlDocPtr); 13 | extern void set_libxml_reporter_printer(TestReporter *reporter, XmlPrinter *printer); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef MEMORY_HEADER 2 | #define MEMORY_HEADER 3 | 4 | 5 | typedef struct MemoryPool_ MemoryPool; 6 | 7 | MemoryPool *create_memory_pool(); 8 | void free_memory_pool(MemoryPool *pool); 9 | void *memory_pool_allocate(MemoryPool *pool, size_t bytes); 10 | void *memory_pool_reallocate(MemoryPool *pool, void *pointer, size_t bytes); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/parameters.h: -------------------------------------------------------------------------------- 1 | #ifndef PARAMETERS_HEADER 2 | #define PARAMETERS_HEADER 3 | 4 | #include 5 | 6 | /* Parameters are used from some user level tests so must be compilable in C++ */ 7 | #ifdef __cplusplus 8 | namespace cgreen { 9 | extern "C" { 10 | #endif 11 | 12 | CgreenVector *create_vector_of_names(const char *parameters); 13 | CgreenVector *create_vector_of_double_markers_for(const char *parameters); 14 | 15 | #ifdef __cplusplus 16 | } 17 | } 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/posix_cgreen_time.c: -------------------------------------------------------------------------------- 1 | #include "cgreen/internal/cgreen_time.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef __ANDROID__ 7 | #include "cgreen/internal/android_headers/androidcompat.h" 8 | #endif // #ifdef __ANDROID__ 9 | 10 | /* TODO: this should really be handle by CMake config... */ 11 | #if defined(__FreeBSD__) || defined(__linux__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__OpenBSD__) 12 | # include 13 | # define HAVE_GETTIMEOFDAY 1 14 | #else 15 | # error "Your POSIX platform does not support gettimeofday(). Please report a bug to http://github.com/cgreen-devs/cgreen/issues" 16 | #endif 17 | 18 | #if defined(HAVE_GETTIMEOFDAY) 19 | uint32_t cgreen_time_get_current_milliseconds(void) { 20 | #ifdef __CYGWIN__ 21 | /* TODO: This is actually the POSIX recommended way to do this */ 22 | struct timespec ts; 23 | if (clock_gettime(CLOCK_REALTIME, &ts) != 0) { 24 | fprintf(stderr, "cgreen error: could not get time\n"); 25 | return 0; 26 | } 27 | 28 | return ts.tv_sec * 1000u + ts.tv_nsec / 1000000u; 29 | #else 30 | struct timeval tv; 31 | if (gettimeofday(&tv, NULL) != 0) { 32 | fprintf(stderr, "cgreen error: could not get time of day\n"); 33 | return 0; 34 | } 35 | return tv.tv_sec * 1000u + tv.tv_usec / 1000u; 36 | #endif 37 | } 38 | #endif 39 | 40 | /* vim: set ts=4 sw=4 et cindent: */ 41 | -------------------------------------------------------------------------------- /src/runner.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern CgreenTest *current_test; 4 | -------------------------------------------------------------------------------- /src/string_comparison.c: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef __cplusplus 3 | #include 4 | #endif 5 | #include 6 | #include 7 | 8 | 9 | bool strings_are_equal(const char* actual, const char* expected) { 10 | /* TODO: if expected is null, warn user to use appropriate non-string assert instead */ 11 | if ((actual == NULL) && (expected == NULL)) { 12 | return true; 13 | } 14 | 15 | if ((actual == NULL) || (expected == NULL)) { 16 | return false; 17 | } 18 | 19 | return (strcmp(actual, expected) == 0); 20 | } 21 | 22 | bool string_contains(const char* actual, const char* expected) { 23 | /* TODO: if expected is null, warn user */ 24 | if ((actual == NULL) || (expected == NULL)) { 25 | return false; 26 | } 27 | 28 | return (strstr(actual, expected) != NULL); 29 | } 30 | -------------------------------------------------------------------------------- /src/text_reporter_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXT_REPORTER_INTERNAL_H 2 | #define TEXT_REPORTER_INTERNAL_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef int TextPrinter(const char *format, ...); 11 | typedef int TextVPrinter(const char *format, va_list arguments); 12 | 13 | extern void set_text_reporter_printer(TestReporter *reporter, TextPrinter *printer); 14 | extern void set_text_reporter_vprinter(TestReporter *reporter, TextVPrinter *vprinter); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | bool panic_use_colours = false; 10 | 11 | /* TODO these are actually a duplicate of the ones in text_reporter.c */ 12 | #define GREEN "\x1b[32m" 13 | #define YELLOW "\x1b[33m" 14 | #define RED "\x1b[31m" 15 | #define MAGENTA "\x1b[35m" 16 | #define RESET "\x1b[0m" 17 | 18 | #include "../gitrevision.h" 19 | 20 | char *cgreen_library_version = VERSION; 21 | char *cgreen_library_revision = GITREVISION; 22 | 23 | char *string_dup(const char *string) { 24 | char *dup = (char *)malloc(strlen(string)+1); 25 | if (dup) 26 | strcpy(dup, string); 27 | return dup; 28 | } 29 | 30 | 31 | static char *panic_message_buffer = NULL; 32 | 33 | /* For unittesting */ 34 | void panic_set_output_buffer(const char *buffer) { 35 | panic_message_buffer = (char *)buffer; 36 | } 37 | 38 | void panic(const char *filename, int line, const char *fmt, ...) { 39 | va_list args; 40 | char buffer[1000]; 41 | 42 | va_start(args, fmt); 43 | sprintf(buffer, "%sCGREEN EXCEPTION%s: <%s:%d>", 44 | panic_use_colours?MAGENTA:"", 45 | panic_use_colours?RESET:"", 46 | filename, line); 47 | vsprintf(&buffer[strlen(buffer)], fmt, args); 48 | va_end(args); 49 | 50 | if (panic_message_buffer != NULL) 51 | strcpy(panic_message_buffer, buffer); 52 | else 53 | fprintf(stderr, "%s\n", buffer); 54 | } 55 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_HEADER 2 | #define UTILS_HEADER 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | namespace cgreen { 9 | extern "C" { 10 | #endif 11 | 12 | extern bool panic_use_colours; 13 | 14 | #define PANIC(...) panic(FILENAME, __LINE__, __VA_ARGS__) 15 | extern char *string_dup(const char *original); 16 | extern void panic_set_output_buffer(const char *buffer); 17 | extern void panic(const char *filename, int line, const char *fmt, ...); 18 | 19 | #ifdef __cplusplus 20 | } 21 | } 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/win32_cgreen.h: -------------------------------------------------------------------------------- 1 | #ifndef WIN32_CGREEN_H 2 | #define WIN32_CGREEN_H 3 | 4 | #define CGREEN_READ_HANDLE "CGREEN_READ_HANDLE" 5 | #define CGREEN_WRITE_HANDLE "CGREEN_WRITE_HANDLE" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/win32_cgreen_time.c: -------------------------------------------------------------------------------- 1 | #include "cgreen/internal/cgreen_time.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static LARGE_INTEGER qry_freq; 10 | static bool qry_freq_initialized = false; 11 | 12 | uint32_t cgreen_time_get_current_milliseconds() { 13 | if (!qry_freq_initialized) { 14 | QueryPerformanceFrequency(&qry_freq); 15 | qry_freq_initialized = true; 16 | } 17 | 18 | LARGE_INTEGER current_count; 19 | QueryPerformanceCounter(¤t_count); 20 | 21 | current_count.QuadPart = current_count.QuadPart * 1000000 / qry_freq.QuadPart; 22 | 23 | return trunc(current_count.QuadPart / 1000); 24 | } 25 | 26 | /* vim: set ts=4 sw=4 et cindent: */ 27 | -------------------------------------------------------------------------------- /src/xml_reporter_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef XML_REPORTER_INTERNAL_H 2 | #define XML_REPORTER_INTERNAL_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include 11 | 12 | typedef int XmlPrinter(FILE *, const char *format, ...); 13 | extern void set_xml_reporter_printer(TestReporter *reporter, XmlPrinter *printer); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | libassertion_tests.so 2 | libbreadcrumb_tests.so 3 | libcdash_reporter_tests.so 4 | libcgreen_value_tests.so 5 | libconstraint_tests.so 6 | libcute_reporter_tests.so 7 | libdouble_tests.so 8 | libenvironment_variables_tests.so 9 | libmessage_formatting_tests.so 10 | libmessaging_tests.so 11 | libmocks_tests.so 12 | libparameters_tests.so 13 | libreflective_runner_no_teardown_tests.so 14 | libreflective_tests.so 15 | libtext_reporter_tests.so 16 | libunit_tests.so 17 | libutils_tests.so 18 | libvector_tests.so 19 | libxml_reporter_tests.so 20 | -------------------------------------------------------------------------------- /tests/CTestCustom.cmake: -------------------------------------------------------------------------------- 1 | set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE "2048") 2 | set(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE "2048") 3 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | # This make file may serve as an example of how to easily build a lot 2 | # of Cgreen test libraries and run them through the runner. By 3 | # structuring it this way only affected libraries need to be rebuilt. 4 | # 5 | # Note that this is not official builds or tests for Cgreen. To do 6 | # that you should go to root directory and do "make unit" or "make 7 | # test" 8 | 9 | CFLAGS = -Wall -fPIC -std=c99 -I../include -I.. -I../src 10 | 11 | LIBRARY_PATH = ../build/src 12 | ifneq ($(shell uname), Darwin) 13 | LOAD_PATH = LD_LIBRARY_PATH=$(LIBRARY_PATH) 14 | else 15 | LOAD_PATH = DYLD_LIBRARY_PATH=$(LIBRARY_PATH) 16 | endif 17 | 18 | TEST_SOURCES = \ 19 | assertion_tests.c \ 20 | breadcrumb_tests.c \ 21 | cdash_reporter_tests.c \ 22 | cgreen_value_tests.c \ 23 | constraint_tests.c \ 24 | cute_reporter_tests.c \ 25 | double_tests.c \ 26 | environment_variables_tests.c \ 27 | message_formatting_tests.c \ 28 | messaging_tests.c \ 29 | mocks_tests.c \ 30 | multiple_suite_tests.c \ 31 | parameters_tests.c \ 32 | reflective_runner_no_teardown_tests.c \ 33 | reflective_tests.c \ 34 | text_reporter_tests.c \ 35 | unit_tests.c \ 36 | utils_tests.c \ 37 | vector_tests.c \ 38 | xml_reporter_tests.c \ 39 | 40 | TEST_LIBRARIES = $(patsubst %.c,lib%.so, $(TEST_SOURCES)) 41 | 42 | all: $(TEST_LIBRARIES) 43 | cd ..; make --no-print-directory 44 | $(LOAD_PATH) ../build/tools/cgreen-runner -s unittests $? 45 | 46 | lib%_tests.so : %_tests.o ; $(CC) -shared -o $@ $^ -L$(LIBRARY_PATH) -lcgreen 47 | -------------------------------------------------------------------------------- /tests/accept_output_for: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Script to accept the current output for some output comparing test as the golden output 4 | # 5 | # Usage: accept 6 | # 7 | # Will copy build/tests/.output to tests/.expected 8 | 9 | if [ "$#" -ne 1 ] 10 | then 11 | echo "Usage: accept " 12 | exit 1 13 | fi 14 | 15 | scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 16 | rootdir=$(dirname $scriptdir) 17 | 18 | if [[ ! -f $rootdir/build/tests/$1.output ]] 19 | then 20 | echo "Output file does not exist." 21 | exit 22 | fi 23 | echo "About to 'cp build/tests/$1.output tests/$1.expected'" 24 | 25 | read -r -p "Are you sure? [y/N] " response 26 | if [[ ! $response =~ ^([yY][eE][sS]|[yY])$ ]] 27 | then 28 | exit 29 | fi 30 | 31 | cp $rootdir/build/tests/$1.output $rootdir/tests/$1.expected 32 | echo "Accepted!" 33 | -------------------------------------------------------------------------------- /tests/all_cpp_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "all_c_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/api/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This subdirectory verifies that the user level api compiles using 2 | # only the publiced includes by compiling test files refering to that 3 | # api. Goal is to reference, and thus verify, the whole api so that 4 | # unintended changes to the API gets noticed early. 5 | # 6 | # There is no need to run the tests... 7 | 8 | include_directories(${CGREEN_PUBLIC_INCLUDE_DIRS}) 9 | 10 | set(api_SRCS 11 | core_api.c 12 | suites_without_context_api.c 13 | suites_with_context_api.c 14 | ) 15 | 16 | set(CGREEN_API_TEST_LIBRARY 17 | cgreen_api 18 | CACHE INTERNAL "cgreen library of user level api verification source" 19 | ) 20 | 21 | add_library(${CGREEN_API_TEST_LIBRARY} SHARED ${api_SRCS}) 22 | 23 | target_link_libraries(${CGREEN_API_TEST_LIBRARY} ${CGREEN_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) 24 | 25 | #macro_add_test(NAME api_compilation_test 26 | # COMMAND ${PROJECT_SOURCE_DIR}/tools/compare_test_output_to_expected 27 | # ${PROJECT_BINARY_DIR}/tools # Where is cgreen-runner? 28 | # $ # Library to run 29 | # ${PROJECT_SOURCE_DIR} # Remove lines with these from output 30 | # ${CGREEN_API_TEST_LIBRARY} # Normalized library name 31 | # ${CMAKE_CURRENT_SOURCE_DIR}) # Where is the expected output? 32 | -------------------------------------------------------------------------------- /tests/api/core_api.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | These tests are only an attempt to exercise the whole public API of 6 | Cgreen to ensure that it compiles. Attempting to run them will 7 | surely result in crashes, plagues and pestilence. For unit tests 8 | see other tests. */ 9 | 10 | #ifdef __cplusplus 11 | using namespace cgreen; 12 | #endif 13 | 14 | // ASSERT 15 | Ensure(assert_that_compiles) { 16 | assert_that(1 == 1); 17 | assert_that(1 == 1, is_true); 18 | assert_that_double(1, is_equal_to(1)); 19 | significant_figures_for_assert_double_are(3); 20 | } 21 | 22 | // CONSTRAINTS 23 | Ensure(constraints_compiles) { 24 | char array[5]; 25 | char *string = (char *)"some string"; 26 | 27 | assert_that(1, is_equal_to(1)); 28 | assert_that(1, is_not_equal_to(1)); 29 | assert_that(1, is_greater_than(1)); 30 | assert_that(1, is_less_than(1)); 31 | 32 | assert_that(array, is_equal_to_contents_of(array, 5)); 33 | assert_that(array, is_not_equal_to_contents_of(array, 3)); 34 | 35 | assert_that(string, is_equal_to_string(string)); 36 | assert_that(string, is_not_equal_to_string(string)); 37 | assert_that(string, contains_string(string)); 38 | assert_that(string, does_not_contain_string(string)); 39 | assert_that(string, begins_with_string(string)); 40 | } 41 | 42 | static int int_stub(int parameter) { 43 | return mock(parameter); 44 | } 45 | 46 | // Mocks 47 | Ensure(mocks_compiles) { 48 | always_expect(int_stub, will_return(1)); 49 | always_expect(int_stub, will_set_contents_of_output_parameter(parameter, 1, sizeof(int))); 50 | never_expect(int_stub); 51 | expect(int_stub, when(parameter, is_equal_to(1))); 52 | int_stub(1); 53 | } 54 | -------------------------------------------------------------------------------- /tests/api/suites_with_context_api.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | using namespace cgreen; 5 | #endif 6 | 7 | Describe(context_api); 8 | BeforeEach(context_api) {} 9 | AfterEach(context_api) {} 10 | 11 | // SUITES 12 | Ensure(context_api, compiles_suite_api) { 13 | TestSuite *suite = create_test_suite(); 14 | 15 | add_test_with_context(suite, context_api, compiles_suite_api); 16 | 17 | run_test_suite(suite, NULL); 18 | run_single_test(suite, "name", NULL); 19 | 20 | die_in(1); 21 | 22 | destroy_test_suite(suite); 23 | } 24 | -------------------------------------------------------------------------------- /tests/api/suites_without_context_api.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | using namespace cgreen; 5 | #endif 6 | 7 | // SUITES 8 | Ensure(a_test) {} 9 | 10 | Ensure(suites_compiles) { 11 | TestSuite *suite = create_test_suite(); 12 | 13 | add_test(suite, a_test); 14 | add_tests(suite, a_test, a_test, a_test); 15 | 16 | run_test_suite(suite, NULL); 17 | run_single_test(suite, "name", NULL); 18 | 19 | die_in(1); 20 | 21 | destroy_test_suite(suite); 22 | } 23 | -------------------------------------------------------------------------------- /tests/assertion_messages_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef __cplusplus 10 | using namespace cgreen; 11 | #endif 12 | 13 | Describe(AssertionMessage); 14 | BeforeEach(AssertionMessage) {} 15 | AfterEach(AssertionMessage) {} 16 | 17 | 18 | char something[42]; 19 | Ensure(AssertionMessage, for_comparing_content_with_negative_length) { 20 | assert_that(47, is_equal_to_contents_of(something, -4)); 21 | } 22 | 23 | Ensure(AssertionMessage, return_value_constraints_are_not_allowed) { 24 | assert_that(0, will_return(1)); 25 | } 26 | 27 | Ensure(AssertionMessage, for_compare_area_to_null) { 28 | char area[100]; 29 | void *null_pointer = NULL; 30 | assert_that(area, is_equal_to_contents_of(null_pointer, 1)); 31 | } 32 | 33 | Ensure(AssertionMessage, for_compare_null_to_area) { 34 | char area[100]; 35 | assert_that(NULL, is_equal_to_contents_of(area, 1)); 36 | } 37 | 38 | Ensure(AssertionMessage, for_actual_with_percent) { 39 | assert_that(strlen("%d"), is_equal_to(3)); /* Actually, it's not but should preserve '%' */ 40 | } 41 | 42 | /* CAUTION: These two tests outputs the expected warning messages, but 43 | also fails the comparisons, obviously, since that is what they try 44 | to warn against. So the output of those failed constraints might 45 | change unintentionally. */ 46 | Ensure(AssertionMessage, for_using_double_constraints_with_assert_that) { 47 | assert_that(3, is_equal_to_double(3.1415926)); 48 | assert_that(0, is_less_than_double(3.1415926)); 49 | assert_that(7, is_greater_than_double(3.1415926)); 50 | } 51 | 52 | Ensure(AssertionMessage, for_using_non_double_constraints_with_assert_that_double) { 53 | assert_that_double(3, is_equal_to(3)); 54 | } 55 | -------------------------------------------------------------------------------- /tests/assertion_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "assertion_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/breadcrumb_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "breadcrumb_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/cdash_reporter_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "cdash_reporter_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/cgreen_value_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "cgreen_value_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/constraint_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "constraint_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/custom_constraint_messages_tests.expected: -------------------------------------------------------------------------------- 1 | Running "custom_constraint_messages_tests" (3 tests)... 2 | custom_constraint_messages_tests.c:000: Failure: CustomConstraint -> custom_constraint_using_a_function_with_arguments_function 3 | Expected [19] to [be smaller than] [10] 4 | 5 | custom_constraint_messages_tests.c:000: Failure: CustomConstraint -> custom_constraint_using_static_function 6 | Expected [1] to [be bigger than 5] 7 | 8 | custom_constraint_messages_tests.c:000: Failure: CustomConstraint -> more_complex_custom_constraint_function 9 | Expected [&piece99] to [fit in box] [&box1] 10 | at offset: [0] 11 | actual value: [0x63] 12 | expected value: [0x01] 13 | 14 | "CustomConstraint": 3 failures in 0ms. 15 | Completed "custom_constraint_messages_tests": 3 failures in 0ms. 16 | -------------------------------------------------------------------------------- /tests/cute_reporter_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "cute_reporter_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/double_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | using namespace cgreen; 5 | #endif 6 | 7 | Describe(Double); 8 | BeforeEach(Double) {} 9 | AfterEach(Double) {} 10 | 11 | Ensure(Double, comparison_with_negative_values_should_not_always_succeed) { 12 | /* Issue #146 - Fixed */ 13 | assert_that_double(-500, is_not_equal_to_double(0)); 14 | } 15 | 16 | Ensure(Double, comparisons_with_extremely_small_numbers_should_not_always_fail) { 17 | /* Issue #149 */ 18 | assert_that_double(4.9406564584124654E-324, is_equal_to_double(4.9406564584124654E-324)); 19 | } 20 | 21 | Ensure(Double, numbers_within_absolute_tolerance_of_zero_are_considered_equal_to_zero) { 22 | double my_dbl_min = 2.2250738585072014e-308; 23 | assert_that_double(1.0e4 * my_dbl_min, is_equal_to_double(0.0)); 24 | } 25 | -------------------------------------------------------------------------------- /tests/double_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "double_tests.c" 12 | -------------------------------------------------------------------------------- /tests/environment_variables_tests.c: -------------------------------------------------------------------------------- 1 | #define _POSIX_C_SOURCE 200809L 2 | #include 3 | 4 | /* TODO: are these include necessary? */ 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #ifdef __cplusplus 11 | using namespace cgreen; 12 | #endif 13 | 14 | Describe(EnvironmentVariables); 15 | BeforeEach(EnvironmentVariables) { setenv("TEST", "test", true); } 16 | AfterEach(EnvironmentVariables) {} 17 | 18 | Ensure(EnvironmentVariables, set_in_before_each_should_be_set_in_test) { 19 | assert_that(getenv("TEST"), is_equal_to_string("test")); 20 | } 21 | -------------------------------------------------------------------------------- /tests/environment_variables_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "environment_variables_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/failure_messages_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | using namespace cgreen; 9 | #endif 10 | 11 | Describe(FailureMessage); 12 | BeforeEach(FailureMessage) {} 13 | AfterEach(FailureMessage) {} 14 | 15 | Ensure(FailureMessage, for_time_out_in_only_one_second) { 16 | die_in(1); 17 | sleep(10); 18 | } 19 | 20 | Ensure(FailureMessage, for_CGREEN_PER_TEST_TIMEOUT) { 21 | // Setting the environment variable here does not work 22 | // It needs to be set before the runner forks 23 | // setenv("CGREEN_PER_TEST_TIMEOUT", "2", true); 24 | // so we leave that to the test environment... 25 | 26 | // And fail if there is no environment variable set 27 | assert_that(getenv("CGREEN_PER_TEST_TIMEOUT"), is_not_equal_to(NULL)); 28 | sleep(3); 29 | fail_test("This test should have been aborted within CGREEN_PER_TEST_TIMEOUT seconds and not get here. When running this test you need to define CGREEN_PER_TEST_TIMEOUT=2."); 30 | } 31 | 32 | #ifdef __cplusplus 33 | Ensure(FailureMessage, increments_exception_count_when_throwing) { 34 | throw; 35 | } 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /tests/failure_messages_tests.expected: -------------------------------------------------------------------------------- 1 | Running "failure_messages_tests" (2 tests)... 2 | failure_messages_tests.c:000: Exception: FailureMessage -> for_CGREEN_PER_TEST_TIMEOUT 3 | Test terminated unexpectedly, likely from a non-standard exception or Posix signal 4 | 5 | failure_messages_tests.c:000: Exception: FailureMessage -> for_time_out_in_only_one_second 6 | Test terminated unexpectedly, likely from a non-standard exception or Posix signal 7 | 8 | "FailureMessage": 1 pass, 2 exceptions in 0ms. 9 | Completed "failure_messages_tests": 1 pass, 2 exceptions in 0ms. 10 | -------------------------------------------------------------------------------- /tests/ignore_messages_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #ifdef HAVE_SYS_RESOURCE_H 8 | #include 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | using namespace cgreen; 13 | #endif 14 | 15 | Describe(IgnoreMessage); 16 | BeforeEach(IgnoreMessage) {} 17 | AfterEach(IgnoreMessage) {} 18 | 19 | Ensure(IgnoreMessage, should_not_count_empty_tests_as_ignored) { 20 | } 21 | 22 | Ensure(IgnoreMessage, should_not_count_passing_tests_as_ignored) { 23 | assert_that(true); 24 | } 25 | 26 | Ensure(IgnoreMessage, should_not_count_failing_tests_as_ignored) { 27 | assert_that(false); 28 | } 29 | 30 | Ensure(IgnoreMessage, should_not_count_exceptions_as_ignored) { 31 | #ifdef HAVE_SYS_RESOURCE_H 32 | struct rlimit core_limit; 33 | core_limit.rlim_cur = 1U; 34 | core_limit.rlim_max = 1U; 35 | setrlimit(RLIMIT_CORE, &core_limit); 36 | #endif 37 | raise(SIGSEGV); 38 | } 39 | 40 | xEnsure(IgnoreMessage, should_present_this_as_ignored) { 41 | fail_test("Should not be run since it's inside an ignored test"); 42 | } 43 | -------------------------------------------------------------------------------- /tests/ignore_messages_tests.expected: -------------------------------------------------------------------------------- 1 | Running "ignore_messages_tests" (5 tests)... 2 | ignore_messages_tests.c:000: Exception: IgnoreMessage -> should_not_count_exceptions_as_ignored 3 | Test terminated with signal: Segmentation fault 4 | 5 | ignore_messages_tests.c:000: Failure: IgnoreMessage -> should_not_count_failing_tests_as_ignored 6 | Expected [0] to [be true] 7 | 8 | "IgnoreMessage": 1 pass, 1 skipped, 1 failure, 1 exception in 0ms. 9 | Completed "ignore_messages_tests": 1 pass, 1 skipped, 1 failure, 1 exception in 0ms. 10 | -------------------------------------------------------------------------------- /tests/libxml_output_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Ensure(failing_test_is_listed_by_libxml_reporter) { 4 | assert_that(false); 5 | } 6 | 7 | Ensure(passing_test_is_listed_by_libxml_reporter) { 8 | assert_that(true); 9 | } 10 | -------------------------------------------------------------------------------- /tests/libxml_output_tests.expected: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/libxml_reporter_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "libxml_reporter_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/message_formatting_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "message_formatting_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/messaging_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "messaging_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/mocks_struct_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifdef __cplusplus 9 | using namespace cgreen; 10 | 11 | namespace cgreen { 12 | extern "C" { 13 | extern CgreenValue make_cgreen_pointer_value(void *ptr); 14 | } 15 | } 16 | 17 | #else 18 | extern CgreenValue make_cgreen_pointer_value(void *ptr); 19 | #endif 20 | 21 | Describe(MockStruct); 22 | BeforeEach(MockStruct) {} 23 | AfterEach(MockStruct) {} 24 | 25 | typedef struct { 26 | int i; 27 | const char *string; 28 | } Struct; 29 | 30 | 31 | /* If you are only interested in a single, or few, fields: */ 32 | void function_mocking_field(Struct s) { 33 | mock(s.i); 34 | } 35 | 36 | Ensure(MockStruct, can_mock_a_struct_parameters_field) { 37 | Struct struct_to_send = { .i = 12, .string = "hello" }; 38 | 39 | expect(function_mocking_field, when(s.i, is_equal_to(12))); 40 | 41 | function_mocking_field(struct_to_send); 42 | } 43 | 44 | void *cgreen_memdup(void *s, size_t size) { 45 | void *p = malloc(size); 46 | memcpy(p, s, size); 47 | return p; 48 | } 49 | 50 | #define memdup(s) cgreen_memdup(&s, sizeof(s)) 51 | 52 | /* If you need to get the whole struct: */ 53 | void function_mocking_the_whole_struct(Struct s) { 54 | Struct *sP = (Struct *)memdup(s); 55 | mock(sP); 56 | } 57 | 58 | Ensure(MockStruct, can_mock_a_struct_parameter) { 59 | Struct struct_to_send = { .i = 13, .string = "hello" }; 60 | Struct *p; 61 | 62 | expect(function_mocking_the_whole_struct, will_capture_parameter(sP, p)); 63 | 64 | function_mocking_the_whole_struct(struct_to_send); 65 | 66 | assert_that(p->i, is_equal_to(13)); 67 | } 68 | -------------------------------------------------------------------------------- /tests/mocks_struct_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "mocks_struct_tests.c" 12 | -------------------------------------------------------------------------------- /tests/mocks_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "mocks_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/multiple_suite_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | using namespace cgreen; 5 | #endif 6 | 7 | // This funciton exemplifies infrastructure common between multiple suits 8 | static int common_func_btw_SUTs(void) { 9 | return 0; 10 | } 11 | 12 | // Suite A and its unit test 13 | Describe(SuiteA); 14 | BeforeEach(SuiteA) {} 15 | AfterEach(SuiteA) {} 16 | 17 | Ensure(SuiteA, ut_a) { 18 | int num = common_func_btw_SUTs(); 19 | assert_that(num, is_equal_to(0)); 20 | } 21 | 22 | // Suite B and its unit test 23 | Describe(SuiteB); 24 | BeforeEach(SuiteB) {} 25 | AfterEach(SuiteB) {} 26 | 27 | Ensure(SuiteB, ut_b) { 28 | int num = common_func_btw_SUTs(); 29 | assert_that(num, is_equal_to(0)); 30 | } 31 | 32 | TestSuite *test_suite_a(void) { 33 | TestSuite *suite = create_test_suite(); 34 | add_test_with_context(suite, SuiteA, ut_a); 35 | run_test_suite(suite, create_text_reporter()); 36 | return suite; 37 | } 38 | 39 | TestSuite *test_suite_b(void) { 40 | TestSuite *suite = create_test_suite(); 41 | add_test_with_context(suite, SuiteB, ut_b); 42 | run_test_suite(suite, create_text_reporter()); 43 | return suite; 44 | } 45 | -------------------------------------------------------------------------------- /tests/multiple_suite_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "multiple_suite_tests.c" 12 | -------------------------------------------------------------------------------- /tests/normalize_assertion_messages_tests.sed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/tests/normalize_assertion_messages_tests.sed -------------------------------------------------------------------------------- /tests/normalize_constraint_messages_tests.sed: -------------------------------------------------------------------------------- 1 | s/Terminated:.+[0-9]+/Terminated/ 2 | s/Quit:.+[0-9]+/Quit/ 3 | -------------------------------------------------------------------------------- /tests/normalize_custom_constraint_messages_tests.sed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/tests/normalize_custom_constraint_messages_tests.sed -------------------------------------------------------------------------------- /tests/normalize_failure_messages_tests.sed: -------------------------------------------------------------------------------- 1 | # Darwin clang++ : 2 | s/libc\+\+abi.dylib: terminating/terminate called without an active exception/ 3 | -------------------------------------------------------------------------------- /tests/normalize_ignore_messages_tests.sed: -------------------------------------------------------------------------------- 1 | s/Segmentation fault: 11/Segmentation fault/g 2 | -------------------------------------------------------------------------------- /tests/normalize_libxml_output_tests.sed: -------------------------------------------------------------------------------- 1 | # 'time="?.?????"' => time="0.00000" 2 | s/time=".+"/time="0.00000"/g 3 | s/line=".+"/line="0"/g 4 | # filenames, suites, libraries and "classnames" starting with "lib" or "cyg" 5 | s/"lib/"/g 6 | s/"cyg/"/g 7 | -------------------------------------------------------------------------------- /tests/normalize_mock_messages_tests.sed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/tests/normalize_mock_messages_tests.sed -------------------------------------------------------------------------------- /tests/normalize_xml_output_tests.sed: -------------------------------------------------------------------------------- 1 | # 'time="?.?????"' => time="0.00000" 2 | s/time=".+"/time="0.00000"/g 3 | s/line=".+"/line="0"/g 4 | # filenames, suites, libraries and "classnames" starting with "lib", "cyg" or ... 5 | s/"lib/"/g 6 | s/"cyg/"/g 7 | s/"msys-/"/g 8 | -------------------------------------------------------------------------------- /tests/parameters_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "parameters_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/reflective_runner_no_teardown_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | using namespace cgreen; 5 | #endif 6 | 7 | static int counter = 0; 8 | 9 | /* this suite exercises a former crash bug in the reflective runner by not having a teardown */ 10 | Describe(ReflectiveNoTeardownTest); 11 | 12 | BeforeEach(ReflectiveNoTeardownTest) { 13 | counter += 5; 14 | } 15 | 16 | AfterEach(ReflectiveNoTeardownTest) {} 17 | 18 | Ensure(ReflectiveNoTeardownTest, before_called_implicitly_before_each_test) { 19 | assert_that(counter, is_equal_to(5)); 20 | } 21 | 22 | Ensure(ReflectiveNoTeardownTest, second_test_unaffected_by_first) { 23 | assert_that(counter, is_equal_to(5)); 24 | } 25 | 26 | TestSuite *reflective_no_teardown_tests(void) { 27 | TestSuite *suite = create_test_suite(); 28 | 29 | add_test_with_context(suite, ReflectiveNoTeardownTest, before_called_implicitly_before_each_test); 30 | add_test_with_context(suite, ReflectiveNoTeardownTest, second_test_unaffected_by_first); 31 | 32 | return suite; 33 | } 34 | -------------------------------------------------------------------------------- /tests/reflective_runner_no_teardown_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "reflective_runner_no_teardown_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/reflective_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #ifdef __cplusplus 3 | using namespace cgreen; 4 | #endif 5 | 6 | static int counter = 0; 7 | 8 | Describe(ReflectiveRunner); 9 | 10 | BeforeEach(ReflectiveRunner) { 11 | counter += 5; 12 | } 13 | 14 | AfterEach(ReflectiveRunner) { 15 | counter += 1; 16 | } 17 | 18 | Ensure(ReflectiveRunner, calls_setup_before_each_test) { 19 | assert_that(counter, is_equal_to(5)); 20 | } 21 | 22 | Ensure(ReflectiveRunner, running_first_test_does_not_affect_second_test) { 23 | assert_that(counter, is_equal_to(5)); 24 | } 25 | 26 | TestSuite *reflective_tests(void) { 27 | TestSuite *suite = create_test_suite(); 28 | 29 | add_test_with_context(suite, ReflectiveRunner, calls_setup_before_each_test); 30 | add_test_with_context(suite, ReflectiveRunner, running_first_test_does_not_affect_second_test); 31 | 32 | return suite; 33 | } 34 | -------------------------------------------------------------------------------- /tests/reflective_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "reflective_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/text_reporter_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "text_reporter_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/unit_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "unit_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/utils_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../src/utils.h" 5 | 6 | Describe(Utils); 7 | BeforeEach(Utils) {} 8 | AfterEach(Utils) {} 9 | 10 | 11 | Ensure(Utils, panic_output_contains_message) { 12 | char message[] = "some error occurred"; 13 | char buffer[100]; 14 | panic_set_output_buffer(buffer); 15 | PANIC(message); 16 | assert_that(buffer, contains_string(message)); 17 | } 18 | 19 | Ensure(Utils, panic_output_contains_filename) { 20 | char buffer[100]; 21 | panic_set_output_buffer(buffer); 22 | PANIC(""); 23 | assert_that(buffer, contains_string(FILENAME)); 24 | } 25 | -------------------------------------------------------------------------------- /tests/vector_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "vector_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tests/xml_output_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Ensure(failing_test_is_listed_by_xml_reporter) { 5 | assert_that(false); 6 | } 7 | 8 | Ensure(passing_test_is_listed_by_xml_reporter) { 9 | assert_that(true); 10 | } 11 | 12 | Ensure(error_message_gets_escaped_by_xml_reporter) { 13 | char *test_string = 14 | "\n" 15 | "\n" 16 | " I'm the content & have chars which have to be escaped, " 17 | "if put in outer XML.\n" 18 | ""; 19 | char *expected_string = "I'm not to be found!"; 20 | assert_that(test_string, contains_string(expected_string)); 21 | } 22 | -------------------------------------------------------------------------------- /tests/xml_output_tests.expected: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/xml_reporter_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file used to be a link to the corresponding .c file because we 3 | want to compile the same tests for C and C++. But since some systems 4 | don't handle symbolic links the same way as *ix systems we get 5 | inconsistencies (looking at you Cygwin) or plain out wrong (looking 6 | at you MSYS2, copying ?!?!?) behaviour. 7 | 8 | So we will simply include the complete .c source instead... 9 | */ 10 | 11 | #include "xml_reporter_tests.c" 12 | 13 | -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.d 3 | lib*.so 4 | discoverer_unit_test_runner.c 5 | discoverer_unit_tests 6 | runner_unit_test_runner.c 7 | runner_unit_tests -------------------------------------------------------------------------------- /tools/TODO: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgreen-devs/cgreen/d32a27690a4b0a5394752dec584dc7c5e12ca85c/tools/TODO -------------------------------------------------------------------------------- /tools/discoverer.h: -------------------------------------------------------------------------------- 1 | #ifndef DISCOVERER_H 2 | #define DISCOVERER_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | // We want to run our tests with cgreen, of course, so in order to not 9 | // cause conflicts with the function in the library itself we rename 10 | // it here when we are running unittests. Also see Makefile. 11 | #ifdef UNITTESTING 12 | #define discover_tests_in(x,y) unittesting_discover_tests_in(x,y) 13 | #endif 14 | 15 | extern CgreenVector *discover_tests_in(const char *filename, bool verbose); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /tools/discoverer.mock: -------------------------------------------------------------------------------- 1 | #include "cgreen/mocks.h" 2 | 3 | #include "discoverer.h" 4 | 5 | // We want to run our tests with cgreen, of course, so in order to not 6 | // cause conflicts with the function in the library itself we rename 7 | // it here when we are running unittests. Also see Makefile. 8 | #ifdef UNITTESTING 9 | #define discover_tests_in(x,y) unittesting_discover_tests_in(x,y) 10 | #endif 11 | 12 | CgreenVector *discover_tests_in(const char *filename, bool verbose) { 13 | return (CgreenVector *)mock(filename, verbose); 14 | } 15 | -------------------------------------------------------------------------------- /tools/discoverer_acceptance_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "discoverer.h" 4 | 5 | #include 6 | 7 | Describe(Discoverer); 8 | BeforeEach(Discoverer) {} 9 | AfterEach(Discoverer) {} 10 | 11 | static bool verbose = false; 12 | 13 | static int count_tests_in(const char *filename) { 14 | char command[1000]; 15 | sprintf(command, "/usr/bin/nm '%s'", filename); 16 | FILE *nm_output = popen(command, "r"); 17 | char line[10000]; 18 | int count = 0; 19 | while (fgets(line, sizeof(line), nm_output) != 0) { 20 | if (strstr(line, CGREEN_SPEC_PREFIX CGREEN_SEPARATOR) != NULL) 21 | count++; 22 | } 23 | return count; 24 | } 25 | 26 | Ensure(Discoverer, reads_a_library_and_finds_the_tests) { 27 | char filename[] = "libdiscoverer_unit_tests.so"; 28 | CgreenVector *tests = discover_tests_in(filename, verbose); 29 | assert_that(cgreen_vector_size(tests), is_equal_to(count_tests_in(filename))); 30 | } 31 | 32 | TestSuite *discoverer_acceptance_tests(void) { 33 | TestSuite *suite = create_test_suite(); 34 | add_test_with_context(suite, Discoverer, reads_a_library_and_finds_the_tests); 35 | return suite; 36 | } 37 | -------------------------------------------------------------------------------- /tools/io.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | /* Adapter to C I/O functions */ 4 | 5 | #include 6 | 7 | 8 | FILE *open_file(const char *filename, const char *mode) { 9 | return fopen(filename, mode); 10 | } 11 | 12 | int close_file(FILE *file) { 13 | return fclose(file); 14 | } 15 | 16 | FILE *open_process(const char *command, const char *mode) { 17 | return popen(command, mode); 18 | } 19 | 20 | int close_process(FILE *process) { 21 | return pclose(process); 22 | } 23 | 24 | 25 | /* 26 | read_line() - read characters from a FILE 27 | - behaves like fgets() except will return 28 | - number of characters read and 29 | - EOF if at end of file 30 | */ 31 | int read_line(FILE *file, char *buffer, int max_length) { 32 | char *result = fgets(buffer, max_length, file); 33 | return result==NULL? EOF : (signed)strlen(result); 34 | } 35 | -------------------------------------------------------------------------------- /tools/io.h: -------------------------------------------------------------------------------- 1 | #ifndef IO_H 2 | #define IO_H 3 | 4 | #include 5 | 6 | #ifdef UNITTESTING 7 | #define open_file open_file_unittesting 8 | #define close_file close_file_unittesting 9 | #define open_process open_process_file_unittesting 10 | #define close_process close_process_unittesting 11 | #define read_line read_line_unittesting 12 | #endif 13 | 14 | extern FILE *open_file(const char *filename, const char *mode); 15 | extern int close_file(FILE *file); 16 | 17 | extern FILE *open_process(const char *command, const char *mode); 18 | extern int close_process(FILE *file); 19 | 20 | extern int read_line(FILE *file, char *buffer, int max_length); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tools/io.mock: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | FILE *open_file(const char *filename, const char *mode) { 4 | return (FILE *) mock(filename, mode); 5 | } 6 | 7 | int close_file(FILE *file) { 8 | return (int) mock(file); 9 | } 10 | 11 | FILE *open_process(const char *command, const char *mode) { 12 | return (FILE *) mock(command, mode); 13 | } 14 | 15 | int close_process(FILE *file) { 16 | return (int) mock(file); 17 | } 18 | 19 | int read_line(FILE *file, char *buffer, int max_length) { 20 | return (int) mock(file, buffer, max_length); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /tools/runner.h: -------------------------------------------------------------------------------- 1 | #ifndef CGREEN_RUNNER_H 2 | #define CGREEN_RUNNER_H 3 | 4 | /* Cgreen runner module */ 5 | 6 | extern int runner(TestReporter *reporter, const char *test_library, const char *suite_name, const char *test_name, bool verbose, bool no_run); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /tools/runner_unit_test_runner.c: -------------------------------------------------------------------------------- 1 | #include "runner_unit_tests.c" 2 | TestSuite *runner_unit_tests() { 3 | TestSuite *suite = create_test_suite(); 4 | add_test_with_context(suite, Runner, can_get_context_name_of_name); 5 | add_test_with_context(suite, Runner, can_get_test_name_of_symbolic_name); 6 | add_test_with_context(suite, Runner, can_ensure_test_exists_from_context_and_name); 7 | add_test_with_context(suite, Runner, can_match_test_name); 8 | add_test_with_context(suite, Runner, can_add_test_to_the_suite_for_its_context); 9 | add_test_with_context(suite, Runner, can_sort_an_empty_list_of_tests); 10 | add_test_with_context(suite, Runner, can_sort_a_list_of_a_single_tests); 11 | add_test_with_context(suite, Runner, can_sort_a_list_of_two_unordered_tests); 12 | add_test_with_context(suite, Runner, can_sort_an_ordered_list_of_two_tests); 13 | add_test_with_context(suite, Runner, can_sort_an_unordered_list_of_tests); 14 | return suite; 15 | } 16 | int main(int argc, char **argv) { 17 | return run_test_suite(runner_unit_tests(), create_text_reporter()); 18 | } 19 | -------------------------------------------------------------------------------- /tools/test_item.c: -------------------------------------------------------------------------------- 1 | #include "test_item.h" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | 11 | static const char *skip_to_separator(const char *start) { 12 | return strstr(start, CGREEN_SEPARATOR); 13 | } 14 | 15 | static const char *skip_over_separator(const char *start) { 16 | return strstr(start, CGREEN_SEPARATOR)+strlen(CGREEN_SEPARATOR); 17 | } 18 | 19 | static const char *skip_cgreen_spec_marker(const char *string) { 20 | return &string[strlen(CGREEN_SPEC_PREFIX CGREEN_SEPARATOR)]; 21 | } 22 | 23 | static const char *string_copy_of(const char *start, const char *end) { 24 | char *string = strdup(start); 25 | string[end-start] = '\0'; 26 | return string; 27 | } 28 | 29 | static const char *context_name_from(const char *specification_name) { 30 | const char *start = skip_cgreen_spec_marker(specification_name); 31 | const char *end = skip_to_separator(start); 32 | return string_copy_of(start, end); 33 | } 34 | 35 | static const char *test_name_from(const char *specification_name) { 36 | const char *start = skip_cgreen_spec_marker(specification_name); 37 | start = skip_over_separator(start); 38 | const char *end = skip_to_separator(start); 39 | return string_copy_of(start, end? end : &start[strlen(start)]); 40 | } 41 | 42 | TestItem *create_test_item_from(const char *specification_name) { 43 | TestItem *test_item = (TestItem *)malloc(sizeof(TestItem)); 44 | 45 | test_item->specification_name = strdup(specification_name); 46 | test_item->context_name = context_name_from(specification_name); 47 | test_item->test_name = test_name_from(specification_name); 48 | 49 | return test_item; 50 | } 51 | 52 | void destroy_test_item(TestItem *item) { 53 | free((void *)item->specification_name); 54 | free((void *)item->context_name); 55 | free((void *)item->test_name); 56 | free((void *)item); 57 | } 58 | -------------------------------------------------------------------------------- /tools/test_item.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_ITEM_H 2 | #define TEST_ITEM_H 3 | 4 | /* The name of a test is either a named mangled from the name of the 5 | context, if any, and the actual test name. Names (or patterns) on 6 | the command line is formatted as a symbolic name composed of the 7 | context name, a colon and the test name. The variable naming below 8 | is trying to be clear about which type of name it is. */ 9 | 10 | typedef struct test_item { 11 | const char *specification_name; 12 | const char *context_name; 13 | const char *test_name; 14 | } TestItem; 15 | 16 | extern TestItem *create_test_item_from(const char *specification_name); 17 | extern void destroy_test_item(TestItem *item); 18 | 19 | #endif 20 | --------------------------------------------------------------------------------