diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4d390e4 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +* text=auto + +*.h text +*.cpp text + +# VS 20xx files +*.sln text eol=crlf +*.vcproj text eol=crlf +*.vcxproj text eol=crlf +*.vcxproj.filters text eol=crlf + +# VC6 files +*.dsw text eol=crlf +*.dsp text eol=crlf + +# Other 'windows-specific' files +*.bat text eol=crlf \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c36c64c --- /dev/null +++ b/.gitignore @@ -0,0 +1,44 @@ +*.o +*.a +*.lo +*.la + +# Visual Studio temp/user files +*.user +*.suo +*.sdf +*.opensdf +*.ncb + +# Build output directories +Release +Debug +MinSizeRel +RelWithDebInfo +ipch + +# files generated by autotools +/aclocal.m4 +/autom4te.cache +/config.guess +/config.h +/config.h.in +/config.status +/config.sub +/configure +/depcomp +/install-sh +/libtool +/ltmain.sh +/m4 +/missing +/stamp-h* +/test-driver +/UnitTest++/TestUnitTest++ +Makefile +Makefile.in +.deps +.libs +*.log +*.trs +*.pc diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..58e923a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "docs"] + path = docs + url = https://github.com/unittest-cpp/unittest-cpp.wiki.git + ignore = dirty \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..4a44b0e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +language: cpp + +# Build with gcc and clang. +compiler: + - gcc + - clang + +# Build both debug and release configurations, through use of an environment variable in the build matrix. +env: + - CONFIGURATION=Debug + - CONFIGURATION=Release + +# Run cmake to generate makefiles in 'builds' directory. +# No need to create it because it's part of the repo. +# Pass along configuration type to cmake. +before_script: + - cd builds && cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=$CONFIGURATION ../ && cd .. + +# Run make in the directory containing generated makefiles. +script: + - make -C builds diff --git a/.uncrustify b/.uncrustify new file mode 100644 index 0000000..ea1187b --- /dev/null +++ b/.uncrustify @@ -0,0 +1,488 @@ +# Uncrustify 0.61 +newlines = auto +input_tab_size = 4 +output_tab_size = 3 +string_escape_char = 92 +string_escape_char2 = 0 +tok_split_gte = false +utf8_bom = remove +utf8_byte = false +utf8_force = false +indent_columns = 3 +indent_continue = 0 +indent_with_tabs = 0 +indent_cmt_with_tabs = false +indent_align_string = false +indent_xml_string = 0 +indent_brace = 0 +indent_braces = false +indent_braces_no_func = false +indent_braces_no_class = false +indent_braces_no_struct = false +indent_brace_parent = false +indent_paren_open_brace = false +indent_namespace = true +indent_namespace_single_indent = false +indent_namespace_level = 0 +indent_namespace_limit = 0 +indent_extern = false +indent_class = true +indent_class_colon = false +indent_constr_colon = false +indent_ctor_init_leading = 1 +indent_ctor_init = 0 +indent_else_if = false +indent_var_def_blk = 0 +indent_var_def_cont = false +indent_func_def_force_col1 = false +indent_func_call_param = false +indent_func_def_param = false +indent_func_proto_param = false +indent_func_class_param = false +indent_func_ctor_var_param = false +indent_template_param = false +indent_func_param_double = false +indent_func_const = 0 +indent_func_throw = 0 +indent_member = indent_columns +indent_sing_line_comments = 0 +indent_relative_single_line_comments = true +indent_switch_case = 0 +indent_case_shift = 0 +indent_case_brace = 0 +indent_col1_comment = false +indent_label = 1 +indent_access_spec = -3 +indent_access_spec_body = false +indent_paren_nl = false +indent_paren_close = 0 +indent_comma_paren = false +indent_bool_paren = false +indent_first_bool_expr = false +indent_square_nl = false +indent_preserve_sql = false +indent_align_assign = true +indent_oc_block = false +indent_oc_block_msg = 0 +indent_oc_msg_colon = 0 +indent_oc_msg_prioritize_first_colon = true +indent_oc_block_msg_xcode_style = false +indent_oc_block_msg_from_keyword = false +indent_oc_block_msg_from_colon = false +indent_oc_block_msg_from_caret = false +indent_oc_block_msg_from_brace = false +sp_arith = ignore +sp_assign = ignore +sp_cpp_lambda_assign = ignore +sp_cpp_lambda_paren = ignore +sp_assign_default = ignore +sp_before_assign = ignore +sp_after_assign = ignore +sp_enum_paren = ignore +sp_enum_assign = ignore +sp_enum_before_assign = ignore +sp_enum_after_assign = ignore +sp_pp_concat = add +sp_pp_stringify = ignore +sp_before_pp_stringify = ignore +sp_bool = ignore +sp_compare = ignore +sp_inside_paren = ignore +sp_paren_paren = ignore +sp_cparen_oparen = ignore +sp_balance_nested_parens = false +sp_paren_brace = ignore +sp_before_ptr_star = ignore +sp_before_unnamed_ptr_star = ignore +sp_between_ptr_star = ignore +sp_after_ptr_star = ignore +sp_after_ptr_star_qualifier = ignore +sp_after_ptr_star_func = ignore +sp_ptr_star_paren = ignore +sp_before_ptr_star_func = ignore +sp_before_byref = ignore +sp_before_unnamed_byref = ignore +sp_after_byref = ignore +sp_after_byref_func = ignore +sp_before_byref_func = ignore +sp_after_type = force +sp_before_template_paren = ignore +sp_template_angle = ignore +sp_before_angle = ignore +sp_inside_angle = ignore +sp_after_angle = ignore +sp_angle_paren = ignore +sp_angle_word = ignore +sp_angle_shift = add +sp_permit_cpp11_shift = false +sp_before_sparen = ignore +sp_inside_sparen = ignore +sp_inside_sparen_close = ignore +sp_inside_sparen_open = ignore +sp_after_sparen = ignore +sp_sparen_brace = ignore +sp_invariant_paren = ignore +sp_after_invariant_paren = ignore +sp_special_semi = ignore +sp_before_semi = remove +sp_before_semi_for = ignore +sp_before_semi_for_empty = ignore +sp_after_semi = add +sp_after_semi_for = force +sp_after_semi_for_empty = ignore +sp_before_square = ignore +sp_before_squares = ignore +sp_inside_square = ignore +sp_after_comma = ignore +sp_before_comma = remove +sp_paren_comma = force +sp_before_ellipsis = ignore +sp_after_class_colon = ignore +sp_before_class_colon = ignore +sp_after_constr_colon = ignore +sp_before_constr_colon = ignore +sp_before_case_colon = remove +sp_after_operator = ignore +sp_after_operator_sym = ignore +sp_after_cast = ignore +sp_inside_paren_cast = ignore +sp_cpp_cast_paren = ignore +sp_sizeof_paren = ignore +sp_after_tag = ignore +sp_inside_braces_enum = ignore +sp_inside_braces_struct = ignore +sp_inside_braces = ignore +sp_inside_braces_empty = ignore +sp_type_func = ignore +sp_func_proto_paren = ignore +sp_func_def_paren = ignore +sp_inside_fparens = ignore +sp_inside_fparen = ignore +sp_inside_tparen = ignore +sp_after_tparen_close = ignore +sp_square_fparen = ignore +sp_fparen_brace = ignore +sp_fparen_dbrace = ignore +sp_func_call_paren = ignore +sp_func_call_paren_empty = ignore +sp_func_call_user_paren = ignore +sp_func_class_paren = ignore +sp_return_paren = ignore +sp_attribute_paren = ignore +sp_defined_paren = ignore +sp_throw_paren = ignore +sp_after_throw = ignore +sp_catch_paren = ignore +sp_version_paren = ignore +sp_scope_paren = ignore +sp_macro = ignore +sp_macro_func = ignore +sp_else_brace = ignore +sp_brace_else = ignore +sp_brace_typedef = ignore +sp_catch_brace = ignore +sp_brace_catch = ignore +sp_finally_brace = ignore +sp_brace_finally = ignore +sp_try_brace = ignore +sp_getset_brace = ignore +sp_word_brace = add +sp_word_brace_ns = add +sp_before_dc = ignore +sp_after_dc = ignore +sp_d_array_colon = ignore +sp_not = remove +sp_inv = remove +sp_addr = remove +sp_member = remove +sp_deref = remove +sp_sign = remove +sp_incdec = remove +sp_before_nl_cont = add +sp_after_oc_scope = ignore +sp_after_oc_colon = ignore +sp_before_oc_colon = ignore +sp_after_oc_dict_colon = ignore +sp_before_oc_dict_colon = ignore +sp_after_send_oc_colon = ignore +sp_before_send_oc_colon = ignore +sp_after_oc_type = ignore +sp_after_oc_return_type = ignore +sp_after_oc_at_sel = ignore +sp_after_oc_at_sel_parens = ignore +sp_inside_oc_at_sel_parens = ignore +sp_before_oc_block_caret = ignore +sp_after_oc_block_caret = ignore +sp_after_oc_msg_receiver = ignore +sp_after_oc_property = ignore +sp_cond_colon = ignore +sp_cond_colon_before = ignore +sp_cond_colon_after = ignore +sp_cond_question = ignore +sp_cond_question_before = ignore +sp_cond_question_after = ignore +sp_cond_ternary_short = ignore +sp_case_label = ignore +sp_range = ignore +sp_after_for_colon = ignore +sp_before_for_colon = ignore +sp_extern_paren = ignore +sp_cmt_cpp_start = ignore +sp_endif_cmt = ignore +sp_after_new = ignore +sp_before_tr_emb_cmt = ignore +sp_num_before_tr_emb_cmt = 0 +sp_annotation_paren = ignore +align_keep_tabs = false +align_with_tabs = false +align_on_tabstop = false +align_number_left = false +align_keep_extra_space = false +align_func_params = false +align_same_func_call_params = false +align_var_def_span = 0 +align_var_def_star_style = 0 +align_var_def_amp_style = 0 +align_var_def_thresh = 0 +align_var_def_gap = 0 +align_var_def_colon = false +align_var_def_attribute = false +align_var_def_inline = false +align_assign_span = 0 +align_assign_thresh = 0 +align_enum_equ_span = 0 +align_enum_equ_thresh = 0 +align_var_struct_span = 0 +align_var_struct_thresh = 0 +align_var_struct_gap = 0 +align_struct_init_span = 0 +align_typedef_gap = 0 +align_typedef_span = 0 +align_typedef_func = 0 +align_typedef_star_style = 0 +align_typedef_amp_style = 0 +align_right_cmt_span = 0 +align_right_cmt_mix = false +align_right_cmt_gap = 0 +align_right_cmt_at_col = 0 +align_func_proto_span = 0 +align_func_proto_gap = 0 +align_on_operator = false +align_mix_var_proto = false +align_single_line_func = false +align_single_line_brace = false +align_single_line_brace_gap = 0 +align_oc_msg_spec_span = 0 +align_nl_cont = true +align_pp_define_together = false +align_pp_define_gap = 0 +align_pp_define_span = 0 +align_left_shift = true +align_oc_msg_colon_span = 0 +align_oc_msg_colon_first = false +align_oc_decl_colon = false +nl_collapse_empty_body = true +nl_assign_leave_one_liners = false +nl_class_leave_one_liners = false +nl_enum_leave_one_liners = false +nl_getset_leave_one_liners = false +nl_func_leave_one_liners = false +nl_cpp_lambda_leave_one_liners = false +nl_if_leave_one_liners = false +nl_oc_msg_leave_one_liner = false +nl_start_of_file = ignore +nl_start_of_file_min = 0 +nl_end_of_file = ignore +nl_end_of_file_min = 0 +nl_assign_brace = ignore +nl_assign_square = ignore +nl_after_square_assign = ignore +nl_func_var_def_blk = 0 +nl_typedef_blk_start = 0 +nl_typedef_blk_end = 0 +nl_typedef_blk_in = 0 +nl_var_def_blk_start = 0 +nl_var_def_blk_end = 0 +nl_var_def_blk_in = 0 +nl_fcall_brace = ignore +nl_enum_brace = ignore +nl_struct_brace = ignore +nl_union_brace = ignore +nl_if_brace = ignore +nl_brace_else = ignore +nl_elseif_brace = ignore +nl_else_brace = ignore +nl_else_if = ignore +nl_brace_finally = ignore +nl_finally_brace = ignore +nl_try_brace = ignore +nl_getset_brace = ignore +nl_for_brace = ignore +nl_catch_brace = ignore +nl_brace_catch = ignore +nl_brace_square = ignore +nl_brace_fparen = ignore +nl_while_brace = ignore +nl_scope_brace = ignore +nl_unittest_brace = ignore +nl_version_brace = ignore +nl_using_brace = ignore +nl_brace_brace = ignore +nl_do_brace = ignore +nl_brace_while = ignore +nl_switch_brace = ignore +nl_multi_line_cond = false +nl_multi_line_define = false +nl_before_case = false +nl_before_throw = ignore +nl_after_case = false +nl_case_colon_brace = ignore +nl_namespace_brace = ignore +nl_template_class = ignore +nl_class_brace = ignore +nl_class_init_args = ignore +nl_constr_init_args = ignore +nl_func_type_name = ignore +nl_func_type_name_class = ignore +nl_func_scope_name = ignore +nl_func_proto_type_name = ignore +nl_func_paren = ignore +nl_func_def_paren = ignore +nl_func_decl_start = ignore +nl_func_def_start = ignore +nl_func_decl_start_single = ignore +nl_func_def_start_single = ignore +nl_func_decl_args = ignore +nl_func_def_args = ignore +nl_func_decl_end = ignore +nl_func_def_end = ignore +nl_func_decl_end_single = ignore +nl_func_def_end_single = ignore +nl_func_decl_empty = ignore +nl_func_def_empty = ignore +nl_oc_msg_args = false +nl_fdef_brace = ignore +nl_cpp_ldef_brace = ignore +nl_return_expr = ignore +nl_after_semicolon = false +nl_paren_dbrace_open = ignore +nl_after_brace_open = false +nl_after_brace_open_cmt = false +nl_after_vbrace_open = false +nl_after_vbrace_open_empty = false +nl_after_brace_close = false +nl_after_vbrace_close = false +nl_brace_struct_var = ignore +nl_define_macro = false +nl_squeeze_ifdef = false +nl_before_if = ignore +nl_after_if = ignore +nl_before_for = ignore +nl_after_for = ignore +nl_before_while = ignore +nl_after_while = ignore +nl_before_switch = ignore +nl_after_switch = ignore +nl_before_do = ignore +nl_after_do = ignore +nl_ds_struct_enum_cmt = false +nl_ds_struct_enum_close_brace = false +nl_class_colon = ignore +nl_constr_colon = ignore +nl_create_if_one_liner = false +nl_create_for_one_liner = false +nl_create_while_one_liner = false +pos_arith = ignore +pos_assign = ignore +pos_bool = ignore +pos_compare = ignore +pos_conditional = ignore +pos_comma = ignore +pos_class_comma = ignore +pos_constr_comma = ignore +pos_class_colon = ignore +pos_constr_colon = ignore +code_width = 0 +ls_for_split_full = false +ls_func_split_full = false +ls_code_width = false +nl_max = 0 +nl_after_func_proto = 0 +nl_after_func_proto_group = 0 +nl_after_func_body = 0 +nl_after_func_body_class = 0 +nl_after_func_body_one_liner = 0 +nl_before_block_comment = 0 +nl_before_c_comment = 0 +nl_before_cpp_comment = 0 +nl_after_multiline_comment = false +nl_after_struct = 0 +nl_after_class = 0 +nl_before_access_spec = 0 +nl_after_access_spec = 0 +nl_comment_func_def = 0 +nl_after_try_catch_finally = 0 +nl_around_cs_property = 0 +nl_between_get_set = 0 +nl_property_brace = ignore +eat_blanks_after_open_brace = false +eat_blanks_before_close_brace = false +nl_remove_extra_newlines = 0 +nl_before_return = false +nl_after_return = false +nl_after_annotation = ignore +nl_between_annotation = ignore +mod_full_brace_do = ignore +mod_full_brace_for = ignore +mod_full_brace_function = ignore +mod_full_brace_if = ignore +mod_full_brace_if_chain = false +mod_full_brace_nl = 0 +mod_full_brace_while = ignore +mod_full_brace_using = ignore +mod_paren_on_return = ignore +mod_pawn_semicolon = false +mod_full_paren_if_bool = false +mod_remove_extra_semicolon = false +mod_add_long_function_closebrace_comment = 0 +mod_add_long_namespace_closebrace_comment = 0 +mod_add_long_switch_closebrace_comment = 0 +mod_add_long_ifdef_endif_comment = 0 +mod_add_long_ifdef_else_comment = 0 +mod_sort_import = false +mod_sort_using = false +mod_sort_include = false +mod_move_case_break = false +mod_case_brace = ignore +mod_remove_empty_return = false +cmt_width = 0 +cmt_reflow_mode = 0 +cmt_convert_tab_to_spaces = false +cmt_indent_multi = true +cmt_c_group = false +cmt_c_nl_start = false +cmt_c_nl_end = false +cmt_cpp_group = false +cmt_cpp_nl_start = false +cmt_cpp_nl_end = false +cmt_cpp_to_c = false +cmt_star_cont = false +cmt_sp_before_star_cont = 0 +cmt_sp_after_star_cont = 0 +cmt_multi_check_last = true +cmt_insert_file_header = "" +cmt_insert_file_footer = "" +cmt_insert_func_header = "" +cmt_insert_class_header = "" +cmt_insert_oc_msg_header = "" +cmt_insert_before_preproc = false +pp_indent = ignore +pp_indent_at_level = false +pp_indent_count = 3 +pp_space = ignore +pp_space_count = 0 +pp_indent_region = 0 +pp_region_indent_code = false +pp_indent_if = 0 +pp_if_indent_code = false +pp_define_at_level = true diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..ea32dd9 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +See README.md for the historic contributor list. + +The maintainer of UnitTest++ is Patrick Johnmeyer (pjohnmeyer@gmail.com). diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b4c75c9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,145 @@ +cmake_minimum_required(VERSION 3.0) +project(UnitTest++ VERSION 2.1.0) + +option(UTPP_USE_PLUS_SIGN + "Set this to OFF if you wish to use '-cpp' instead of '++' in lib/include paths" + ON) +option(UTPP_INCLUDE_TESTS_IN_BUILD + "Set this to OFF if you do not wish to automatically build or run unit tests as part of the default cmake --build" + ON) +option(UTPP_AMPLIFY_WARNINGS + "Set this to OFF if you wish to use CMake default warning levels; should generally only use to work around support issues for your specific compiler" + ON) + +set(LIB_SUFFIX "" CACHE STRING "Identifier to add to end of lib directory name e.g. 64 for lib64") + +if (MSVC) + # CHECK_CXX_COMPILER_FLAG could be used + # but MSVC version is preferred for feature requirements + if (MSVC14 OR MSVC12) + # has the support we need + else() + message(STATUS "The MSVC compiler version does not support UnitTest++ C++11 features.") + endif() +else() + include(CheckCXXCompilerFlag) + CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14) + CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) + if(COMPILER_SUPPORTS_CXX14) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") + elseif(COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + else() + message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support.") + endif() +endif() + +# up warning level for project +if (${UTPP_AMPLIFY_WARNINGS}) + # instead of getting compiler specific, we're going to try making an assumption that an existing /W# means + # we are dealing with an MSVC or MSVC-like compiler (e.g. Intel on Windows) + if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror") + endif() +endif() + +# get the main sources +file(GLOB headers_ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} UnitTest++/*.h) +file(GLOB sources_ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} UnitTest++/*.cpp) +source_group("" FILES ${headers_} ${sources_}) + +# get platform specific sources +if (WIN32) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + set(platformDir_ Win32) +else() + set(platformDir_ Posix) +endif(WIN32) + +file(GLOB platformHeaders_ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} UnitTest++/${platformDir_}/*.h) +file(GLOB platformSources_ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} UnitTest++/${platformDir_}/*.cpp) +source_group(${platformDir_} FILES ${platformHeaders_} ${platformSources_}) + +# create the lib +add_library(UnitTest++ STATIC ${headers_} ${sources_} ${platformHeaders_} ${platformSources_}) +add_library(UnitTest++::UnitTest++ ALIAS UnitTest++) + + +if(${UTPP_USE_PLUS_SIGN}) + set_target_properties(UnitTest++ PROPERTIES OUTPUT_NAME UnitTest++) +endif() + + +# build the test runner +file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} tests/*.cpp tests/*.h) +source_group( "" FILES ${TEST_SRCS}) +add_executable(TestUnitTest++ ${TEST_SRCS}) + + +if(${UTPP_USE_PLUS_SIGN}) + set_target_properties(TestUnitTest++ PROPERTIES OUTPUT_NAME TestUnitTest++) +endif() + +target_link_libraries(TestUnitTest++ + PUBLIC + UnitTest++::UnitTest++ + ) + +# run unit tests as post build step +add_custom_command(TARGET TestUnitTest++ + POST_BUILD COMMAND TestUnitTest++ + COMMENT "Running unit tests") + +if(NOT ${UTPP_INCLUDE_TESTS_IN_BUILD}) + set_target_properties(TestUnitTest++ PROPERTIES EXCLUDE_FROM_ALL 1) +endif() + +# add install targets +# need a custom install path? +# define CMAKE_INSTALL_PREFIX to change root folder +if(${UTPP_USE_PLUS_SIGN}) + set (UTPP_INSTALL_DESTINATION "include/UnitTest++") +else() + set (UTPP_INSTALL_DESTINATION "include/UnitTestPP") +endif() + +target_include_directories( UnitTest++ + PUBLIC + $ + $ + ) +set_target_properties(UnitTest++ PROPERTIES DEBUG_POSTFIX "-d") +set_target_properties(TestUnitTest++ PROPERTIES DEBUG_POSTFIX "-d") + +set(config_install_dir_ lib${LIB_SUFFIX}/cmake/${PROJECT_NAME}) +set(targets_export_name_ "${PROJECT_NAME}Targets") +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + cmake/UnitTest++ConfigVersion.cmake + VERSION ${UnitTest++_VERSION} + COMPATIBILITY SameMajorVersion + ) + +install(TARGETS UnitTest++ EXPORT "${targets_export_name_}" DESTINATION lib${LIB_SUFFIX}) +install(FILES ${headers_} DESTINATION ${UTPP_INSTALL_DESTINATION}) +install(FILES ${platformHeaders_} DESTINATION ${UTPP_INSTALL_DESTINATION}/${platformDir_}) +install(FILES + cmake/UnitTest++Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake/UnitTest++ConfigVersion.cmake + DESTINATION "${config_install_dir_}") +install(EXPORT "${targets_export_name_}" NAMESPACE "UnitTest++::" DESTINATION "${config_install_dir_}") + +set(prefix ${CMAKE_INSTALL_PREFIX}) +set(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin) +set(libdir ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) +set(includedir ${CMAKE_INSTALL_PREFIX}/include/UnitTest++) +configure_file("UnitTest++.pc.in" "UnitTest++.pc" @ONLY) +if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") + set(pkgconfdir ${CMAKE_INSTALL_PREFIX}/libdata/pkgconfig) +else() + set(pkgconfdir ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig) +endif() +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/UnitTest++.pc" + DESTINATION "${pkgconfdir}") diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..6c99c94 --- /dev/null +++ b/INSTALL @@ -0,0 +1,376 @@ + +Preamble: If you are installing UnitTest++ from source, or from a +release prior to 1.6.1, you will need to have autotools installed and +run `autoreconf -i; autoconf` prior to following the standard +instructions below. + +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. diff --git a/COPYING b/LICENSE similarity index 98% rename from COPYING rename to LICENSE index dc16f73..9f96308 100644 --- a/COPYING +++ b/LICENSE @@ -1,20 +1,20 @@ -Copyright (c) 2006 Noel Llopis and Charles Nicholson - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Copyright (c) 2006 Noel Llopis and Charles Nicholson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile deleted file mode 100644 index 205dedc..0000000 --- a/Makefile +++ /dev/null @@ -1,100 +0,0 @@ -CXX = g++ -CXXFLAGS ?= -g -Wall -W -Winline -ansi -LDFLAGS ?= -SED = sed -MV = mv -RM = rm - -.SUFFIXES: .o .cpp - -lib = libunittestpp.a -test = test-unittestpp - -src = src/AssertException.cpp \ - src/Test.cpp \ - src/Checks.cpp \ - src/TestRunner.cpp \ - src/TestResults.cpp \ - src/TestReporter.cpp \ - src/TestReporterStdout.cpp \ - src/ReportAssert.cpp \ - src/TestList.cpp \ - src/TimeConstraint.cpp \ - src/TestDetails.cpp \ - src/MemoryOutStream.cpp \ - src/DeferredTestReporter.cpp \ - src/DeferredTestResult.cpp \ - src/XmlTestReporter.cpp \ - src/CurrentTest.cpp \ - src/CompositeTestReporter.cpp - -ifeq ($(MSYSTEM), MINGW32) - src += src/Win32/TimeHelpers.cpp -else - src += src/Posix/SignalTranslator.cpp \ - src/Posix/TimeHelpers.cpp -endif - -test_src = src/tests/Main.cpp \ - src/tests/TestAssertHandler.cpp \ - src/tests/TestChecks.cpp \ - src/tests/TestUnitTestPP.cpp \ - src/tests/TestTest.cpp \ - src/tests/TestTestResults.cpp \ - src/tests/TestTestRunner.cpp \ - src/tests/TestCheckMacros.cpp \ - src/tests/TestTestList.cpp \ - src/tests/TestTestMacros.cpp \ - src/tests/TestTimeConstraint.cpp \ - src/tests/TestTimeConstraintMacro.cpp \ - src/tests/TestMemoryOutStream.cpp \ - src/tests/TestDeferredTestReporter.cpp \ - src/tests/TestXmlTestReporter.cpp \ - src/tests/TestCurrentTest.cpp \ - src/tests/TestCompositeTestReporter.cpp - -objects = $(patsubst %.cpp, %.o, $(src)) -test_objects = $(patsubst %.cpp, %.o, $(test_src)) -dependencies = $(subst .o,.d,$(objects)) -test_dependencies = $(subst .o,.d,$(test_objects)) - -define make-depend - $(CXX) $(CXXFLAGS) -M $1 | \ - $(SED) -e 's,\($(notdir $2)\) *:,$(dir $2)\1: ,' > $3.tmp - $(SED) -e 's/#.*//' \ - -e 's/^[^:]*: *//' \ - -e 's/ *\\$$//' \ - -e '/^$$/ d' \ - -e 's/$$/ :/' $3.tmp >> $3.tmp - $(MV) $3.tmp $3 -endef - - -all: $(test) - - -$(lib): $(objects) - @mkdir -p lib/win32_gcc_debug - @echo Creating $(lib) library... - @ar cr lib/win32_gcc_debug/$(lib) $(objects) - -$(test): $(lib) $(test_objects) - @mkdir -p bin/win32_gcc_static_debug - @echo Linking $(test)... - @$(CXX) $(LDFLAGS) -o bin/win32_gcc_static_debug/$(test) $(test_objects) lib/win32_gcc_debug/$(lib) - @echo Running unit tests... - @bin/win32_gcc_static_debug/$(test) - -clean: - -@$(RM) $(objects) $(test_objects) $(dependencies) $(test_dependencies) $(test) $(lib) 2> /dev/null - -%.o : %.cpp - @echo $< - @$(call make-depend,$<,$@,$(subst .o,.d,$@)) - @$(CXX) $(CXXFLAGS) -c $< -o $(patsubst %.cpp, %.o, $<) - - -ifneq "$(MAKECMDGOALS)" "clean" --include $(dependencies) --include $(test_dependencies) -endif diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..18db0ef --- /dev/null +++ b/Makefile.am @@ -0,0 +1,8 @@ +ACLOCAL_AMFLAGS = -I m4 +EXTRA_DIST = docs + +include UnitTest++/Makefile.am +include tests/Makefile.am + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = UnitTest++.pc diff --git a/README b/README deleted file mode 100644 index 1389cc6..0000000 --- a/README +++ /dev/null @@ -1,68 +0,0 @@ -UnitTest++ README -Version: v1.4 -Last update: 2008-10-30 - -UnitTest++ is free software. You may copy, distribute, and modify it under -the terms of the License contained in the file COPYING distributed -with this package. This license is the same as the MIT/X Consortium -license. - -See src/tests/TestUnitTest++.cpp for usage. - -Authors: -Noel Llopis (llopis@convexhull.com) -Charles Nicholson (charles.nicholson@gmail.com) - -Contributors: -Jim Tilander -Kim Grasman -Jonathan Jansson -Dirck Blaskey -Rory Driscoll -Dan Lind -Matt Kimmel -- Submitted with permission from Blue Fang Games -Anthony Moralez -Jeff Dixon -Randy Coulman -Lieven van der Heide - -Release notes: --------------- -Version 1.4 (2008-10-30) -- CHECK macros work at arbitrary stack depth from inside TESTs. -- Remove obsolete TEST_UTILITY macros -- Predicated test execution (via TestRunner::RunTestsIf) -- Better exception handling for fixture ctors/dtors. -- VC6/7/8/9 support - -Version 1.3 (2007-4-22) -- Removed dynamic memory allocations (other than streams) -- MinGW support -- Consistent (native) line endings -- Minor bug fixing - -Version 1.2 (2006-10-29) -- First pass at documentation. -- More detailed error crash catching in fixtures. -- Standard streams used for printing objects under check. This should allow the - use of standard class types such as std::string or other custom classes with - stream operators to ostream. -- Standard streams can be optionally compiled off by defining UNITTEST_USE_CUSTOM_STREAMS - in Config.h -- Added named test suites -- Added CHECK_ARRAY2D_CLOSE -- Posix library name is libUnitTest++.a now -- Floating point numbers are postfixed with 'f' in the failure reports - -Version 1.1 (2006-04-18) -- CHECK macros do not have side effects even if one of the parameters changes state -- Removed CHECK_ARRAY_EQUAL (too similar to CHECK_ARRAY_CLOSE) -- Added local and global time constraints -- Removed dependencies on strstream -- Improved Posix signal to exception translator -- Failing tests are added to Visual Studio's error list -- Fixed Visual Studio projects to work with spaces in directories - -Version 1.0 (2006-03-15) -- Initial release - diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ece10e --- /dev/null +++ b/README.md @@ -0,0 +1,141 @@ +> ### Maintenance of UnitTest++, recently sporadic, is officially on hiatus until 26 November 2020. Subscribe to https://github.com/unittest-cpp/unittest-cpp/issues/180 for updates. + + +[![Build Status](https://travis-ci.org/unittest-cpp/unittest-cpp.svg?branch=master)](https://travis-ci.org/unittest-cpp/unittest-cpp) +[![Build status](https://ci.appveyor.com/api/projects/status/ffs2k8dddts5cyok/branch/master?svg=true)](https://ci.appveyor.com/project/pjohnmeyer/unittest-cpp/branch/master) + +UnitTest++ +=========== + +UnitTest++ is a lightweight unit testing framework for C++. It was designed to do test-driven development on a wide variety of platforms. Simplicity, portability, speed, and small footprint are all very important aspects of UnitTest++. UnitTest++ is mostly standard C++ and makes minimal use of advanced library and language features, which means it should be easily portable to just about any platform. Out of the box, the following platforms are supported: + +* Windows +* Linux +* Mac OS X + +Documentation +-------------- +The full documentation for building and using UnitTest++ can be found on the [GitHub wiki page](https://github.com/unittest-cpp/unittest-cpp/wiki). The contents of this wiki are also included as a git submodule under the `docs` folder, so version-specific Markdown documentation is always available along with the download. + +Pre-requisites +--------------- +While there are currently some bundled automake files, UnitTest++ is primarily built and supported using [CMake](http://cmake.org). + +Downloading +------------ +### Latest (HEAD) ### + +Via git: + + git clone https://github.com/unittest-cpp/unittest-cpp + +Via svn: + + svn checkout https://github.com/unittest-cpp/unittest-cpp/trunk unittest-cpp + +### Latest release (v2.0.0) ### + +Via git: + + git clone https://github.com/unittest-cpp/unittest-cpp + cd unittest-cpp + git checkout v2.0.0 + +Via svn: + + svn checkout https://github.com/unittest-cpp/unittest-cpp/tags/v2.0.0 unittest-cpp + +License +--------- +*UnitTest++ is free software. You may copy, distribute, and modify it under +the terms of the License contained in the file LICENSE distributed +with this package. This license is the same as the MIT/X Consortium +license.* + +Contributors +-------------- +### [GitHub Contributor Graph](https://github.com/unittest-cpp/unittest-cpp/contributors) ### + +### Current Maintainers: ### +* Patrick Johnmeyer (pjohnmeyer@gmail.com) @pjohnmeyer +* Charles Nicholson (charles.nicholson@gmail.com) @charlesnicholson + +### Original Authors: ### +* Noel Llopis (llopis@convexhull.com) +* Charles Nicholson (charles.nicholson@gmail.com) + +### Contributors not included in github history ### +* Jim Tilander +* Kim Grasman +* Jonathan Jansson +* Dirck Blaskey +* Rory Driscoll +* Dan Lind +* Matt Kimmel -- Submitted with permission from Blue Fang Games +* Anthony Moralez +* Jeff Dixon +* Randy Coulman +* Lieven van der Heide + +Historic release notes +---------------------- + +### Version 2.0.0 (2017-01-13) ### +- Change Check method supporting CHECK macro to accept argument by reference +- Introduce long macro forms (e.g. UNITTEST_CHECK); make short forms optional +- Improved Visual Studio 2015 support +- [Full List](https://github.com/unittest-cpp/unittest-cpp/issues?q=milestone%3A2.0.0+) + +### Version 1.6.0 (2016-02-29) ### +- Add REQUIRE macro to end tests early when selected checks fail +- [Full List](https://github.com/unittest-cpp/unittest-cpp/issues?q=milestone%3A1.6.0+) + +### Version 1.5.1 (2016-01-30) ### +- pkg-config support +- Fix for Visual Studio 2010 compilation issue in 1.5.0 +- [Full List](https://github.com/unittest-cpp/unittest-cpp/issues?q=milestone%3A1.5.1+) + +### Version 1.5 (2015-11-04) ### +- Visual Studio 2015 support +- CMake-based build management +- Integration of SourceForge and Google Code versions of the project +- [Full List](https://github.com/unittest-cpp/unittest-cpp/issues?q=is%3Aissue+is%3Aclosed+milestone%3A1.5.0) + +### Version 1.4 (2008-10-30) ### +- CHECK macros work at arbitrary stack depth from inside TESTs. +- Remove obsolete TEST_UTILITY macros +- Predicated test execution (via TestRunner::RunTestsIf) +- Better exception handling for fixture ctors/dtors. +- VC6/7/8/9 support + +### Version 1.3 (2007-4-22) ### +- Removed dynamic memory allocations (other than streams) +- MinGW support +- Consistent (native) line endings +- Minor bug fixing + +### Version 1.2 (2006-10-29) ### +- First pass at documentation. +- More detailed error crash catching in fixtures. +- Standard streams used for printing objects under check. This should allow the + use of standard class types such as std::string or other custom classes with + stream operators to ostream. +- Standard streams can be optionally compiled off by defining UNITTEST_USE_CUSTOM_STREAMS + in Config.h +- Added named test suites +- Added CHECK_ARRAY2D_CLOSE +- Posix library name is libUnitTest++.a now +- Floating point numbers are postfixed with 'f' in the failure reports + +### Version 1.1 (2006-04-18) ### +- CHECK macros do not have side effects even if one of the parameters changes state +- Removed CHECK_ARRAY_EQUAL (too similar to CHECK_ARRAY_CLOSE) +- Added local and global time constraints +- Removed dependencies on strstream +- Improved Posix signal to exception translator +- Failing tests are added to Visual Studio's error list +- Fixed Visual Studio projects to work with spaces in directories + +### Version 1.0 (2006-03-15) ### +- Initial release + diff --git a/TestUnitTest++.vsnet2003.vcproj b/TestUnitTest++.vsnet2003.vcproj deleted file mode 100644 index fbc4154..0000000 --- a/TestUnitTest++.vsnet2003.vcproj +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/TestUnitTest++.vsnet2005.vcproj b/TestUnitTest++.vsnet2005.vcproj deleted file mode 100644 index aa8f95b..0000000 --- a/TestUnitTest++.vsnet2005.vcproj +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/TestUnitTestPP_vs6.dsp b/TestUnitTestPP_vs6.dsp deleted file mode 100644 index bdfb234..0000000 --- a/TestUnitTestPP_vs6.dsp +++ /dev/null @@ -1,169 +0,0 @@ -# Microsoft Developer Studio Project File - Name="TestUnitTestPP_vs6" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** ҏWȂł ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=TestUnitTestPP_vs6 - Win32 Debug -!MESSAGE ͗LҲ̧قł͂܂B ۼުĂނ邽߂ɂ NMAKE gpĂB -!MESSAGE [Ҳ̧ق̴߰] ނgpĎsĂ -!MESSAGE -!MESSAGE NMAKE /f "TestUnitTestPP_vs6.mak". -!MESSAGE -!MESSAGE NMAKE ̎sɍ\wł܂ -!MESSAGE ײݏϸۂ̐ݒ`܂B: -!MESSAGE -!MESSAGE NMAKE /f "TestUnitTestPP_vs6.mak" CFG="TestUnitTestPP_vs6 - Win32 Debug" -!MESSAGE -!MESSAGE I”\ Ӱ: -!MESSAGE -!MESSAGE "TestUnitTestPP_vs6 - Win32 Release" ("Win32 (x86) Console Application" p) -!MESSAGE "TestUnitTestPP_vs6 - Win32 Debug" ("Win32 (x86) Console Application" p) -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "TestUnitTestPP_vs6 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x411 /d "NDEBUG" -# ADD RSC /l 0x411 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "TestUnitTestPP_vs6 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x411 /d "_DEBUG" -# ADD RSC /l 0x411 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "TestUnitTestPP_vs6 - Win32 Release" -# Name "TestUnitTestPP_vs6 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\src\tests\Main.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestAssertHandler.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestCheckMacros.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestChecks.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestCurrentTest.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestDeferredTestReporter.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestMemoryOutStream.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestTest.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestTestList.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestTestMacros.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestTestResults.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestTestRunner.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestTestSuite.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestTimeConstraint.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestTimeConstraintMacro.cpp -# End Source File -# Begin Source File - -SOURCE=".\src\tests\TestUnitTestPP.cpp" -# End Source File -# Begin Source File - -SOURCE=.\src\tests\TestXmlTestReporter.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\src\tests\RecordingReporter.h -# End Source File -# Begin Source File - -SOURCE=.\src\tests\ScopedCurrentTest.h -# End Source File -# End Group -# End Target -# End Project diff --git a/UnitTest++.pc.in b/UnitTest++.pc.in new file mode 100644 index 0000000..5020a22 --- /dev/null +++ b/UnitTest++.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: UnitTest++ +Description: UnitTest++ is a simple C++ Unit Test Framework +URL: https://github.com/unittest-cpp/unittest-cpp +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lUnitTest++ +Cflags: -I${includedir}/ diff --git a/UnitTest++.vsnet2003.sln b/UnitTest++.vsnet2003.sln deleted file mode 100644 index 748dedb..0000000 --- a/UnitTest++.vsnet2003.sln +++ /dev/null @@ -1,30 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest++.vsnet2003", "UnitTest++.vsnet2003.vcproj", "{7E5DD804-EC63-4FA5-BB6D-53DA86806EF5}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestUnitTest++.vsnet2003", "TestUnitTest++.vsnet2003.vcproj", "{ACDF9A6A-874F-49E5-AB7C-74F8150BB4C7}" - ProjectSection(ProjectDependencies) = postProject - {7E5DD804-EC63-4FA5-BB6D-53DA86806EF5} = {7E5DD804-EC63-4FA5-BB6D-53DA86806EF5} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {7E5DD804-EC63-4FA5-BB6D-53DA86806EF5}.Debug.ActiveCfg = Debug|Win32 - {7E5DD804-EC63-4FA5-BB6D-53DA86806EF5}.Debug.Build.0 = Debug|Win32 - {7E5DD804-EC63-4FA5-BB6D-53DA86806EF5}.Release.ActiveCfg = Release|Win32 - {7E5DD804-EC63-4FA5-BB6D-53DA86806EF5}.Release.Build.0 = Release|Win32 - {ACDF9A6A-874F-49E5-AB7C-74F8150BB4C7}.Debug.ActiveCfg = Debug|Win32 - {ACDF9A6A-874F-49E5-AB7C-74F8150BB4C7}.Debug.Build.0 = Debug|Win32 - {ACDF9A6A-874F-49E5-AB7C-74F8150BB4C7}.Release.ActiveCfg = Release|Win32 - {ACDF9A6A-874F-49E5-AB7C-74F8150BB4C7}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/UnitTest++.vsnet2003.vcproj b/UnitTest++.vsnet2003.vcproj deleted file mode 100644 index 7fc9721..0000000 --- a/UnitTest++.vsnet2003.vcproj +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/UnitTest++.vsnet2005.sln b/UnitTest++.vsnet2005.sln deleted file mode 100644 index f27ed4a..0000000 --- a/UnitTest++.vsnet2005.sln +++ /dev/null @@ -1,29 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest++.vsnet2005", "UnitTest++.vsnet2005.vcproj", "{64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestUnitTest++.vsnet2005", "TestUnitTest++.vsnet2005.vcproj", "{9CCC3439-309E-4E85-B3B8-CE704D385D48}" - ProjectSection(ProjectDependencies) = postProject - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6} = {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.Debug|Win32.ActiveCfg = Debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.Debug|Win32.Build.0 = Debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.Release|Win32.ActiveCfg = Release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.Release|Win32.Build.0 = Release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.Debug|Win32.ActiveCfg = Debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.Debug|Win32.Build.0 = Debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.Release|Win32.ActiveCfg = Release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/UnitTest++.vsnet2005.vcproj b/UnitTest++.vsnet2005.vcproj deleted file mode 100644 index 9c56365..0000000 --- a/UnitTest++.vsnet2005.vcproj +++ /dev/null @@ -1,318 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/UnitTest++/AssertException.cpp b/UnitTest++/AssertException.cpp new file mode 100644 index 0000000..29b3939 --- /dev/null +++ b/UnitTest++/AssertException.cpp @@ -0,0 +1,15 @@ +#include "AssertException.h" + +#ifndef UNITTEST_NO_EXCEPTIONS + +namespace UnitTest { + + AssertException::AssertException() + {} + + AssertException::~AssertException() throw() + {} + +} + +#endif diff --git a/src/AssertException.h b/UnitTest++/AssertException.h similarity index 50% rename from src/AssertException.h rename to UnitTest++/AssertException.h index 74291db..e604f63 100644 --- a/src/AssertException.h +++ b/UnitTest++/AssertException.h @@ -1,23 +1,23 @@ -#ifndef UNITTEST_ASSERTEXCEPTION_H -#define UNITTEST_ASSERTEXCEPTION_H - -#include "../config.h" -#ifndef UNITTEST_NO_EXCEPTIONS - -#include "HelperMacros.h" -#include - -namespace UnitTest { - -class UNITTEST_LINKAGE AssertException : public std::exception -{ -public: - AssertException(); - virtual ~AssertException() throw(); -}; - -} - -#endif - -#endif +#ifndef UNITTEST_ASSERTEXCEPTION_H +#define UNITTEST_ASSERTEXCEPTION_H + +#include "Config.h" +#ifndef UNITTEST_NO_EXCEPTIONS + +#include "HelperMacros.h" +#include + +namespace UnitTest { + + class UNITTEST_LINKAGE AssertException : public std::exception + { + public: + AssertException(); + virtual ~AssertException() throw(); + }; + +} + +#endif + +#endif diff --git a/UnitTest++/CheckMacros.h b/UnitTest++/CheckMacros.h new file mode 100644 index 0000000..898559d --- /dev/null +++ b/UnitTest++/CheckMacros.h @@ -0,0 +1,216 @@ +#ifndef UNITTEST_CHECKMACROS_H +#define UNITTEST_CHECKMACROS_H + +#include "HelperMacros.h" +#include "ExceptionMacros.h" +#include "Checks.h" +#include "AssertException.h" +#include "RequiredCheckException.h" +#include "MemoryOutStream.h" +#include "TestDetails.h" +#include "CurrentTest.h" +#include "ReportAssertImpl.h" + +#define UNITTEST_CHECK(value) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UNITTEST_IMPL_TRY \ + ({ \ + if (!UnitTest::Check(value)) \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \ + }) \ + UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream UnitTest_message; \ + UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK(" #value ")"; \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + UnitTest_message.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + "Unhandled exception in CHECK(" #value ")"); \ + }) \ + UNITTEST_MULTILINE_MACRO_END + +#define UNITTEST_CHECK_EQUAL(expected, actual) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UNITTEST_IMPL_TRY \ + ({ \ + UnitTest::CheckEqual(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ + }) \ + UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream UnitTest_message; \ + UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + UnitTest_message.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \ + }) \ + UNITTEST_MULTILINE_MACRO_END + +#define UNITTEST_CHECK_CLOSE(expected, actual, tolerance) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UNITTEST_IMPL_TRY \ + ({ \ + UnitTest::CheckClose(*UnitTest::CurrentTest::Results(), expected, actual, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ + }) \ + UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream UnitTest_message; \ + UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_CLOSE(" #expected ", " #actual ")"; \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + UnitTest_message.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + "Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \ + }) \ + UNITTEST_MULTILINE_MACRO_END + +#define UNITTEST_CHECK_ARRAY_EQUAL(expected, actual, count) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UNITTEST_IMPL_TRY \ + ({ \ + UnitTest::CheckArrayEqual(*UnitTest::CurrentTest::Results(), expected, actual, count, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ + }) \ + UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream UnitTest_message; \ + UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"; \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + UnitTest_message.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + "Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \ + }) \ + UNITTEST_MULTILINE_MACRO_END + +#define UNITTEST_CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UNITTEST_IMPL_TRY \ + ({ \ + UnitTest::CheckArrayClose(*UnitTest::CurrentTest::Results(), expected, actual, count, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ + }) \ + UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream UnitTest_message; \ + UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"; \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + UnitTest_message.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \ + }) \ + UNITTEST_MULTILINE_MACRO_END + +#define UNITTEST_CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UNITTEST_IMPL_TRY \ + ({ \ + UnitTest::CheckArray2DClose(*UnitTest::CurrentTest::Results(), expected, actual, rows, columns, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ + }) \ + UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream UnitTest_message; \ + UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_ARRAY2D_CLOSE(" #expected ", " #actual ")"; \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + UnitTest_message.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + "Unhandled exception in CHECK_ARRAY2D_CLOSE(" #expected ", " #actual ")"); \ + }) \ + UNITTEST_MULTILINE_MACRO_END + +#ifndef UNITTEST_DISABLE_SHORT_MACROS + #ifdef CHECK + #error CHECK already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK instead + #else + #define CHECK UNITTEST_CHECK + #endif + + #ifdef CHECK_EQUAL + #error CHECK_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_EQUAL instead + #else + #define CHECK_EQUAL UNITTEST_CHECK_EQUAL + #endif + + #ifdef CHECK_CLOSE + #error CHECK_CLOSE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_CLOSE instead + #else + #define CHECK_CLOSE UNITTEST_CHECK_CLOSE + #endif + + #ifdef CHECK_ARRAY_EQUAL + #error CHECK_ARRAY_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_ARRAY_EQUAL instead + #else + #define CHECK_ARRAY_EQUAL UNITTEST_CHECK_ARRAY_EQUAL + #endif + + #ifdef CHECK_ARRAY_CLOSE + #error CHECK_ARRAY_CLOSE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_ARRAY_CLOSE instead + #else + #define CHECK_ARRAY_CLOSE UNITTEST_CHECK_ARRAY_CLOSE + #endif + + #ifdef CHECK_ARRAY2D_CLOSE + #error CHECK_ARRAY2D_CLOSE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_ARRAY2D_CLOSE instead + #else + #define CHECK_ARRAY2D_CLOSE UNITTEST_CHECK_ARRAY2D_CLOSE + #endif +#endif + +// CHECK_THROW and CHECK_ASSERT only exist when UNITTEST_NO_EXCEPTIONS isn't defined (see config.h) +#ifndef UNITTEST_NO_EXCEPTIONS + +#define UNITTEST_CHECK_THROW(expression, ExpectedExceptionType) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + bool caught_ = false; \ + try { expression; } \ + catch (ExpectedExceptionType const&) { caught_ = true; } \ + catch (...) {} \ + if (!caught_) \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \ + UNITTEST_MULTILINE_MACRO_END + + +#define UNITTEST_CHECK_ASSERT(expression) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UnitTest::Detail::ExpectAssert(true); \ + CHECK_THROW(expression, UnitTest::AssertException); \ + UnitTest::Detail::ExpectAssert(false); \ + UNITTEST_MULTILINE_MACRO_END +#endif + +#ifndef UNITTEST_DISABLE_SHORT_MACROS + #ifdef CHECK_THROW + #error CHECK_THROW already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_THROW instead + #else + #define CHECK_THROW UNITTEST_CHECK_THROW + #endif + + #ifdef CHECK_ASSERT + #error CHECK_ASSERT already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_ASSERT instead + #else + #define CHECK_ASSERT UNITTEST_CHECK_ASSERT + #endif +#endif + +#endif + diff --git a/UnitTest++/Checks.cpp b/UnitTest++/Checks.cpp new file mode 100644 index 0000000..9c0a960 --- /dev/null +++ b/UnitTest++/Checks.cpp @@ -0,0 +1,50 @@ +#include "Checks.h" +#include + +namespace UnitTest { + + namespace { + + void CheckStringsEqual(TestResults& results, char const* expected, char const* actual, + TestDetails const& details) + { + using namespace std; + + if ((expected && actual) ? strcmp(expected, actual) : (expected || actual)) + { + UnitTest::MemoryOutStream stream; + stream << "Expected " << (expected ? expected : "") << " but was " << (actual ? actual : ""); + + results.OnTestFailure(details, stream.GetText()); + } + } + + } + + + void CheckEqual(TestResults& results, char const* expected, char const* actual, + TestDetails const& details) + { + CheckStringsEqual(results, expected, actual, details); + } + + void CheckEqual(TestResults& results, char* expected, char* actual, + TestDetails const& details) + { + CheckStringsEqual(results, expected, actual, details); + } + + void CheckEqual(TestResults& results, char* expected, char const* actual, + TestDetails const& details) + { + CheckStringsEqual(results, expected, actual, details); + } + + void CheckEqual(TestResults& results, char const* expected, char* actual, + TestDetails const& details) + { + CheckStringsEqual(results, expected, actual, details); + } + + +} diff --git a/UnitTest++/Checks.h b/UnitTest++/Checks.h new file mode 100644 index 0000000..7c37691 --- /dev/null +++ b/UnitTest++/Checks.h @@ -0,0 +1,158 @@ +#ifndef UNITTEST_CHECKS_H +#define UNITTEST_CHECKS_H + +#include "Config.h" +#include "TestResults.h" +#include "MemoryOutStream.h" + +namespace UnitTest { + + + template< typename Value > + bool Check(Value const& value) + { + return !!value; // doing double negative to avoid silly VS warnings + } + + + template< typename Expected, typename Actual > + void CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) + { + if (!(expected == actual)) + { + UnitTest::MemoryOutStream stream; + stream << "Expected " << expected << " but was " << actual; + + results.OnTestFailure(details, stream.GetText()); + } + } + + UNITTEST_LINKAGE void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details); + + UNITTEST_LINKAGE void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details); + + UNITTEST_LINKAGE void CheckEqual(TestResults& results, char* expected, char const* actual, TestDetails const& details); + + UNITTEST_LINKAGE void CheckEqual(TestResults& results, char const* expected, char* actual, TestDetails const& details); + + template< typename Expected, typename Actual, typename Tolerance > + bool AreClose(Expected const& expected, Actual const& actual, Tolerance const& tolerance) + { + return (actual >= (expected - tolerance)) && (actual <= (expected + tolerance)); + } + + template< typename Expected, typename Actual, typename Tolerance > + void CheckClose(TestResults& results, Expected const& expected, Actual const& actual, Tolerance const& tolerance, + TestDetails const& details) + { + if (!AreClose(expected, actual, tolerance)) + { + UnitTest::MemoryOutStream stream; + stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual; + + results.OnTestFailure(details, stream.GetText()); + } + } + + + template< typename Expected, typename Actual > + void CheckArrayEqual(TestResults& results, Expected const& expected, Actual const& actual, + size_t const count, TestDetails const& details) + { + bool equal = true; + for (size_t i = 0; i < count; ++i) + equal &= (expected[i] == actual[i]); + + if (!equal) + { + UnitTest::MemoryOutStream stream; + + stream << "Expected [ "; + + for (size_t expectedIndex = 0; expectedIndex < count; ++expectedIndex) + stream << expected[expectedIndex] << " "; + + stream << "] but was [ "; + + for (size_t actualIndex = 0; actualIndex < count; ++actualIndex) + stream << actual[actualIndex] << " "; + + stream << "]"; + + results.OnTestFailure(details, stream.GetText()); + } + } + + template< typename Expected, typename Actual, typename Tolerance > + bool ArrayAreClose(Expected const& expected, Actual const& actual, size_t const count, Tolerance const& tolerance) + { + bool equal = true; + for (size_t i = 0; i < count; ++i) + equal &= AreClose(expected[i], actual[i], tolerance); + return equal; + } + + template< typename Expected, typename Actual, typename Tolerance > + void CheckArrayClose(TestResults& results, Expected const& expected, Actual const& actual, + size_t const count, Tolerance const& tolerance, TestDetails const& details) + { + bool equal = ArrayAreClose(expected, actual, count, tolerance); + + if (!equal) + { + UnitTest::MemoryOutStream stream; + + stream << "Expected [ "; + for (size_t expectedIndex = 0; expectedIndex < count; ++expectedIndex) + stream << expected[expectedIndex] << " "; + stream << "] +/- " << tolerance << " but was [ "; + + for (size_t actualIndex = 0; actualIndex < count; ++actualIndex) + stream << actual[actualIndex] << " "; + stream << "]"; + + results.OnTestFailure(details, stream.GetText()); + } + } + + template< typename Expected, typename Actual, typename Tolerance > + void CheckArray2DClose(TestResults& results, Expected const& expected, Actual const& actual, + size_t const rows, size_t const columns, Tolerance const& tolerance, TestDetails const& details) + { + bool equal = true; + for (size_t i = 0; i < rows; ++i) + equal &= ArrayAreClose(expected[i], actual[i], columns, tolerance); + + if (!equal) + { + UnitTest::MemoryOutStream stream; + + stream << "Expected [ "; + + for (size_t expectedRow = 0; expectedRow < rows; ++expectedRow) + { + stream << "[ "; + for (size_t expectedColumn = 0; expectedColumn < columns; ++expectedColumn) + stream << expected[expectedRow][expectedColumn] << " "; + stream << "] "; + } + + stream << "] +/- " << tolerance << " but was [ "; + + for (size_t actualRow = 0; actualRow < rows; ++actualRow) + { + stream << "[ "; + for (size_t actualColumn = 0; actualColumn < columns; ++actualColumn) + stream << actual[actualRow][actualColumn] << " "; + stream << "] "; + } + + stream << "]"; + + results.OnTestFailure(details, stream.GetText()); + } + } + +} + +#endif diff --git a/UnitTest++/CompositeTestReporter.cpp b/UnitTest++/CompositeTestReporter.cpp new file mode 100644 index 0000000..53769f0 --- /dev/null +++ b/UnitTest++/CompositeTestReporter.cpp @@ -0,0 +1,66 @@ +#include "CompositeTestReporter.h" +#include + +namespace UnitTest { + + CompositeTestReporter::CompositeTestReporter() + : m_reporterCount(0) + {} + + int CompositeTestReporter::GetReporterCount() const + { + return m_reporterCount; + } + + bool CompositeTestReporter::AddReporter(TestReporter* reporter) + { + if (m_reporterCount == kMaxReporters) + return false; + + m_reporters[m_reporterCount++] = reporter; + return true; + } + + bool CompositeTestReporter::RemoveReporter(TestReporter* reporter) + { + for (int index = 0; index < m_reporterCount; ++index) + { + if (m_reporters[index] == reporter) + { + m_reporters[index] = m_reporters[m_reporterCount - 1]; + --m_reporterCount; + return true; + } + } + + return false; + } + + void CompositeTestReporter::ReportFailure(TestDetails const& details, char const* failure) + { + for (int index = 0; index < m_reporterCount; ++index) + m_reporters[index]->ReportFailure(details, failure); + } + + void CompositeTestReporter::ReportTestStart(TestDetails const& test) + { + for (int index = 0; index < m_reporterCount; ++index) + m_reporters[index]->ReportTestStart(test); + } + + void CompositeTestReporter::ReportTestFinish(TestDetails const& test, float secondsElapsed) + { + for (int index = 0; index < m_reporterCount; ++index) + m_reporters[index]->ReportTestFinish(test, secondsElapsed); + } + + void CompositeTestReporter::ReportSummary(int totalTestCount, + int failedTestCount, + int failureCount, + float secondsElapsed) + { + for (int index = 0; index < m_reporterCount; ++index) + m_reporters[index]->ReportSummary(totalTestCount, failedTestCount, failureCount, secondsElapsed); + } + +} diff --git a/UnitTest++/CompositeTestReporter.h b/UnitTest++/CompositeTestReporter.h new file mode 100644 index 0000000..c7e1e6b --- /dev/null +++ b/UnitTest++/CompositeTestReporter.h @@ -0,0 +1,34 @@ +#ifndef UNITTEST_COMPOSITETESTREPORTER_H +#define UNITTEST_COMPOSITETESTREPORTER_H + +#include "TestReporter.h" + +namespace UnitTest { + + class UNITTEST_LINKAGE CompositeTestReporter : public TestReporter + { + public: + CompositeTestReporter(); + + int GetReporterCount() const; + bool AddReporter(TestReporter* reporter); + bool RemoveReporter(TestReporter* reporter); + + virtual void ReportTestStart(TestDetails const& test); + virtual void ReportFailure(TestDetails const& test, char const* failure); + virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed); + virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); + + private: + enum { kMaxReporters = 16 }; + TestReporter* m_reporters[kMaxReporters]; + int m_reporterCount; + + // revoked + CompositeTestReporter(const CompositeTestReporter&); + CompositeTestReporter& operator =(const CompositeTestReporter&); + }; + +} + +#endif diff --git a/UnitTest++/Config.h b/UnitTest++/Config.h new file mode 100644 index 0000000..14429ee --- /dev/null +++ b/UnitTest++/Config.h @@ -0,0 +1,84 @@ +#ifndef UNITTEST_CONFIG_H +#define UNITTEST_CONFIG_H + +// Standard defines documented here: http://predef.sourceforge.net + +#if defined(_MSC_VER) + #pragma warning(disable:4702)// unreachable code + #pragma warning(disable:4722)// destructor never returns, potential memory leak + + #if (_MSC_VER == 1200) // VC6 + #define UNITTEST_COMPILER_IS_MSVC6 + #pragma warning(disable:4786) + #pragma warning(disable:4290) + #endif + + #ifdef _USRDLL + #define UNITTEST_WIN32_DLL + #endif + + #define UNITTEST_WIN32 +#endif + +#if defined(unix) || defined(__unix__) || defined(__unix) || defined(linux) || \ + defined(__APPLE__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) \ + || defined (__HAIKU__) || defined(_AIX) + #define UNITTEST_POSIX +#endif + +#if defined(__MINGW32__) + #define UNITTEST_MINGW +#endif + + +// By default, MemoryOutStream is implemented in terms of std::ostringstream. +// This is useful if you are using the CHECK macros on objects that have something like this defined: +// std::ostringstream& operator<<(std::ostringstream& s, const YourObject& value) +// +// On the other hand, it can be more expensive. +// Un-comment this line to use the custom MemoryOutStream (no deps on std::ostringstream). + +// #define UNITTEST_USE_CUSTOM_STREAMS + +// Developer note: This dual-macro setup is to preserve compatibility with UnitTest++ 1.4 users +// who may have used or defined UNITTEST_USE_CUSTOM_STREAMS outside of this configuration file, as +// well as Google Code HEAD users that may have used or defined +// UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM outside of this configuration file. +#ifndef UNITTEST_USE_CUSTOM_STREAMS + #define UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM +#endif + +// DeferredTestReporter uses the STL to collect test results for subsequent export by reporters like +// XmlTestReporter. If you don't want to use this functionality, uncomment this line and no STL +// headers or code will be compiled into UnitTest++ + +//#define UNITTEST_NO_DEFERRED_REPORTER + + +// By default, asserts that you report via UnitTest::ReportAssert() abort the current test and +// continue to the next one by throwing an exception, which unwinds the stack naturally, destroying +// all auto variables on its way back down. If you don't want to (or can't) use exceptions for your +// platform/compiler, uncomment this line. All exception code will be removed from UnitTest++, +// assert recovery will be done via setjmp/longjmp, and NO correct stack unwinding will happen! + +//#define UNITTEST_NO_EXCEPTIONS + + +// std namespace qualification: used for functions like strcpy that +// may live in std:: namespace (cstring header). +#if defined( UNITTEST_COMPILER_IS_MSVC6 ) + #define UNIITEST_NS_QUAL_STD(x) x +#else + #define UNIITEST_NS_QUAL_STD(x) ::std::x +#endif + +// By default, UnitTest++ will attempt to define "short" macro names like CHECK and CHECK_EQUAL +// for "public" interface macros etc. Defining UNITTEST_DISABLE_SHORT_MACROS in your project +// will disable this behavior, leaving only the longer macros "namespaced" with the UNITTEST_ +// prefix. +// +// "Internal" utility macros will only have the UNITTEST_IMPL_ prefix. + +// #define UNITTEST_DISABLE_SHORT_MACROS + +#endif diff --git a/UnitTest++/CurrentTest.cpp b/UnitTest++/CurrentTest.cpp new file mode 100644 index 0000000..b1b1995 --- /dev/null +++ b/UnitTest++/CurrentTest.cpp @@ -0,0 +1,18 @@ +#include "CurrentTest.h" +#include + +namespace UnitTest { + + UNITTEST_LINKAGE TestResults*& CurrentTest::Results() + { + static TestResults* testResults = NULL; + return testResults; + } + + UNITTEST_LINKAGE const TestDetails*& CurrentTest::Details() + { + static const TestDetails* testDetails = NULL; + return testDetails; + } + +} diff --git a/UnitTest++/CurrentTest.h b/UnitTest++/CurrentTest.h new file mode 100644 index 0000000..54c40ac --- /dev/null +++ b/UnitTest++/CurrentTest.h @@ -0,0 +1,19 @@ +#ifndef UNITTEST_CURRENTTESTRESULTS_H +#define UNITTEST_CURRENTTESTRESULTS_H + +#include "HelperMacros.h" + +namespace UnitTest { + + class TestResults; + class TestDetails; + + namespace CurrentTest + { + UNITTEST_LINKAGE TestResults*& Results(); + UNITTEST_LINKAGE const TestDetails*& Details(); + } + +} + +#endif diff --git a/src/DeferredTestReporter.cpp b/UnitTest++/DeferredTestReporter.cpp similarity index 53% rename from src/DeferredTestReporter.cpp rename to UnitTest++/DeferredTestReporter.cpp index 83dee1a..165e542 100644 --- a/src/DeferredTestReporter.cpp +++ b/UnitTest++/DeferredTestReporter.cpp @@ -1,33 +1,33 @@ -#include "../config.h" -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "DeferredTestReporter.h" -#include "TestDetails.h" - -using namespace UnitTest; - -void DeferredTestReporter::ReportTestStart(TestDetails const& details) -{ - m_results.push_back(DeferredTestResult(details.suiteName, details.testName)); -} - -void DeferredTestReporter::ReportFailure(TestDetails const& details, char const* failure) -{ - DeferredTestResult& r = m_results.back(); - r.failed = true; - r.failures.push_back(DeferredTestFailure(details.lineNumber, failure)); - r.failureFile = details.filename; -} - -void DeferredTestReporter::ReportTestFinish(TestDetails const&, float secondsElapsed) -{ - DeferredTestResult& r = m_results.back(); - r.timeElapsed = secondsElapsed; -} - -DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults() -{ - return m_results; -} - -#endif +#include "Config.h" +#ifndef UNITTEST_NO_DEFERRED_REPORTER + +#include "DeferredTestReporter.h" +#include "TestDetails.h" + +using namespace UnitTest; + +void DeferredTestReporter::ReportTestStart(TestDetails const& details) +{ + m_results.push_back(DeferredTestResult(details.suiteName, details.testName)); +} + +void DeferredTestReporter::ReportFailure(TestDetails const& details, char const* failure) +{ + DeferredTestResult& r = m_results.back(); + r.failed = true; + r.failures.push_back(DeferredTestFailure(details.lineNumber, failure)); + r.failureFile = details.filename; +} + +void DeferredTestReporter::ReportTestFinish(TestDetails const&, float secondsElapsed) +{ + DeferredTestResult& r = m_results.back(); + r.timeElapsed = secondsElapsed; +} + +DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults() +{ + return m_results; +} + +#endif diff --git a/UnitTest++/DeferredTestReporter.h b/UnitTest++/DeferredTestReporter.h new file mode 100644 index 0000000..51ac866 --- /dev/null +++ b/UnitTest++/DeferredTestReporter.h @@ -0,0 +1,35 @@ +#ifndef UNITTEST_DEFERREDTESTREPORTER_H +#define UNITTEST_DEFERREDTESTREPORTER_H + +#include "Config.h" + +#ifndef UNITTEST_NO_DEFERRED_REPORTER + +#include "TestReporter.h" +#include "DeferredTestResult.h" + +#include + +UNITTEST_STDVECTOR_LINKAGE(UnitTest::DeferredTestResult); + +namespace UnitTest +{ + + class UNITTEST_LINKAGE DeferredTestReporter : public TestReporter + { + public: + virtual void ReportTestStart(TestDetails const& details); + virtual void ReportFailure(TestDetails const& details, char const* failure); + virtual void ReportTestFinish(TestDetails const& details, float secondsElapsed); + + typedef std::vector< DeferredTestResult > DeferredTestResultList; + DeferredTestResultList& GetResults(); + + private: + DeferredTestResultList m_results; + }; + +} + +#endif +#endif diff --git a/UnitTest++/DeferredTestResult.cpp b/UnitTest++/DeferredTestResult.cpp new file mode 100644 index 0000000..9a3ee93 --- /dev/null +++ b/UnitTest++/DeferredTestResult.cpp @@ -0,0 +1,43 @@ +#include "Config.h" +#ifndef UNITTEST_NO_DEFERRED_REPORTER + +#include "DeferredTestResult.h" +#include + +namespace UnitTest +{ + + DeferredTestFailure::DeferredTestFailure() + : lineNumber(-1) + { + failureStr[0] = '\0'; + } + + DeferredTestFailure::DeferredTestFailure(int lineNumber_, const char* failureStr_) + : lineNumber(lineNumber_) + { + UNIITEST_NS_QUAL_STD(strcpy)(failureStr, failureStr_); + } + + DeferredTestResult::DeferredTestResult() + : suiteName("") + , testName("") + , failureFile("") + , timeElapsed(0.0f) + , failed(false) + {} + + DeferredTestResult::DeferredTestResult(char const* suite, char const* test) + : suiteName(suite) + , testName(test) + , failureFile("") + , timeElapsed(0.0f) + , failed(false) + {} + + DeferredTestResult::~DeferredTestResult() + {} + +} + +#endif diff --git a/UnitTest++/DeferredTestResult.h b/UnitTest++/DeferredTestResult.h new file mode 100644 index 0000000..e0d74ef --- /dev/null +++ b/UnitTest++/DeferredTestResult.h @@ -0,0 +1,52 @@ +#ifndef UNITTEST_DEFERREDTESTRESULT_H +#define UNITTEST_DEFERREDTESTRESULT_H + +#include "Config.h" +#ifndef UNITTEST_NO_DEFERRED_REPORTER + +#include "HelperMacros.h" +#include +#include + +namespace UnitTest +{ + + class UNITTEST_LINKAGE DeferredTestFailure + { + public: + DeferredTestFailure(); + DeferredTestFailure(int lineNumber_, const char* failureStr_); + + int lineNumber; + char failureStr[1024]; + }; + +} + +UNITTEST_STDVECTOR_LINKAGE(UnitTest::DeferredTestFailure); + +namespace UnitTest +{ + + class UNITTEST_LINKAGE DeferredTestResult + { + public: + DeferredTestResult(); + DeferredTestResult(char const* suite, char const* test); + ~DeferredTestResult(); + + std::string suiteName; + std::string testName; + std::string failureFile; + + typedef std::vector< DeferredTestFailure > FailureVec; + FailureVec failures; + + float timeElapsed; + bool failed; + }; + +} + +#endif +#endif diff --git a/UnitTest++/ExceptionMacros.h b/UnitTest++/ExceptionMacros.h new file mode 100644 index 0000000..9b2bad4 --- /dev/null +++ b/UnitTest++/ExceptionMacros.h @@ -0,0 +1,20 @@ +#ifndef UNITTEST_EXCEPTIONMACROS_H +#define UNITTEST_EXCEPTIONMACROS_H + +#include "Config.h" + +#ifndef UNITTEST_NO_EXCEPTIONS + #define UNITTEST_IMPL_TRY(x) try x + #define UNITTEST_IMPL_THROW(x) throw x + #define UNITTEST_IMPL_RETHROW(ExceptionType) catch(ExceptionType&) { throw; } + #define UNITTEST_IMPL_CATCH(ExceptionType, ExceptionName, CatchBody) catch(ExceptionType& ExceptionName) CatchBody + #define UNITTEST_IMPL_CATCH_ALL(CatchBody) catch(...) CatchBody +#else + #define UNITTEST_IMPL_TRY(x) x + #define UNITTEST_IMPL_THROW(x) + #define UNITTEST_IMPL_RETHROW(ExceptionType) + #define UNITTEST_IMPL_CATCH(ExceptionType, ExceptionName, CatchBody) + #define UNITTEST_IMPL_CATCH_ALL(CatchBody) +#endif + +#endif diff --git a/UnitTest++/ExecuteTest.h b/UnitTest++/ExecuteTest.h new file mode 100644 index 0000000..2759aad --- /dev/null +++ b/UnitTest++/ExecuteTest.h @@ -0,0 +1,61 @@ +#ifndef UNITTEST_EXECUTE_TEST_H +#define UNITTEST_EXECUTE_TEST_H + +#include "Config.h" +#include "ExceptionMacros.h" +#include "TestDetails.h" +#include "TestResults.h" +#include "MemoryOutStream.h" +#include "AssertException.h" +#include "RequiredCheckException.h" +#include "CurrentTest.h" + +#ifdef UNITTEST_NO_EXCEPTIONS +#include "ReportAssertImpl.h" +#endif + +#ifdef UNITTEST_POSIX +#include "Posix/SignalTranslator.h" +#endif + +namespace UnitTest { + + template< typename T > + void ExecuteTest(T& testObject, TestDetails const& details, bool isMockTest) + { + if (isMockTest == false) + CurrentTest::Details() = &details; + +#ifdef UNITTEST_NO_EXCEPTIONS + if (UNITTEST_SET_ASSERT_JUMP_TARGET() == 0) + { +#endif +#ifndef UNITTEST_POSIX + UNITTEST_IMPL_TRY({ testObject.RunImpl(); }) +#else + UNITTEST_IMPL_TRY + ({ + UNITTEST_THROW_SIGNALS_POSIX_ONLY + testObject.RunImpl(); + }) +#endif + UNITTEST_IMPL_CATCH(RequiredCheckException, e, { (void)e; }) + UNITTEST_IMPL_CATCH(AssertException, e, { (void)e; }) + UNITTEST_IMPL_CATCH(std::exception, e, + { + MemoryOutStream stream; + stream << "Unhandled exception: " << e.what(); + CurrentTest::Results()->OnTestFailure(details, stream.GetText()); + }) + UNITTEST_IMPL_CATCH_ALL + ({ + CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: test crashed"); + }) +#ifdef UNITTEST_NO_EXCEPTIONS + } +#endif + } + +} + +#endif diff --git a/UnitTest++/HelperMacros.h b/UnitTest++/HelperMacros.h new file mode 100644 index 0000000..6d72f22 --- /dev/null +++ b/UnitTest++/HelperMacros.h @@ -0,0 +1,52 @@ +#ifndef UNITTEST_HELPERMACROS_H +#define UNITTEST_HELPERMACROS_H + +#include "Config.h" + +#define UNITTEST_MULTILINE_MACRO_BEGIN do { + +#if defined(UNITTEST_WIN32) && !defined(UNITTEST_COMPILER_IS_MSVC6) + #define UNITTEST_MULTILINE_MACRO_END \ + } __pragma(warning(push)) __pragma(warning(disable: 4127)) while (0) __pragma(warning(pop)) +#else + #define UNITTEST_MULTILINE_MACRO_END } while(0) +#endif + + +#ifdef UNITTEST_WIN32_DLL + #define UNITTEST_IMPORT __declspec(dllimport) + #define UNITTEST_EXPORT __declspec(dllexport) + + #ifdef UNITTEST_DLL_EXPORT + #define UNITTEST_LINKAGE UNITTEST_EXPORT + #define UNITTEST_IMPEXP_TEMPLATE + #else + #define UNITTEST_LINKAGE UNITTEST_IMPORT + #define UNITTEST_IMPEXP_TEMPLATE extern + #endif + + #define UNITTEST_STDVECTOR_LINKAGE(T) \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4231)) \ + UNITTEST_IMPEXP_TEMPLATE template class UNITTEST_LINKAGE std::allocator< T >; \ + UNITTEST_IMPEXP_TEMPLATE template class UNITTEST_LINKAGE std::vector< T >; \ + __pragma(warning(pop)) +#else + #define UNITTEST_IMPORT + #define UNITTEST_EXPORT + #define UNITTEST_LINKAGE + #define UNITTEST_IMPEXP_TEMPLATE + #define UNITTEST_STDVECTOR_LINKAGE(T) +#endif + +#ifdef UNITTEST_WIN32 + #define UNITTEST_JMPBUF jmp_buf + #define UNITTEST_SETJMP setjmp + #define UNITTEST_LONGJMP longjmp +#elif defined UNITTEST_POSIX + #define UNITTEST_JMPBUF std::jmp_buf + #define UNITTEST_SETJMP setjmp + #define UNITTEST_LONGJMP std::longjmp +#endif + +#endif diff --git a/UnitTest++/Makefile.am b/UnitTest++/Makefile.am new file mode 100644 index 0000000..62e246f --- /dev/null +++ b/UnitTest++/Makefile.am @@ -0,0 +1,17 @@ +lib_LTLIBRARIES = UnitTest++/libUnitTest++.la +pkgincludedir = $(includedir) + +nobase_pkginclude_HEADERS = UnitTest++/AssertException.h UnitTest++/CheckMacros.h UnitTest++/Checks.h UnitTest++/CompositeTestReporter.h UnitTest++/Config.h UnitTest++/CurrentTest.h UnitTest++/DeferredTestReporter.h UnitTest++/DeferredTestResult.h UnitTest++/ExceptionMacros.h UnitTest++/ExecuteTest.h UnitTest++/HelperMacros.h UnitTest++/MemoryOutStream.h UnitTest++/ReportAssert.h UnitTest++/ReportAssertImpl.h UnitTest++/RequireMacros.h UnitTest++/RequiredCheckException.h UnitTest++/RequiredCheckTestReporter.h UnitTest++/Test.h UnitTest++/TestDetails.h UnitTest++/TestList.h UnitTest++/TestMacros.h UnitTest++/TestReporter.h UnitTest++/TestReporterStdout.h UnitTest++/TestResults.h UnitTest++/TestRunner.h UnitTest++/TestSuite.h UnitTest++/ThrowingTestReporter.h UnitTest++/TimeConstraint.h UnitTest++/TimeHelpers.h UnitTest++/UnitTest++.h UnitTest++/UnitTestPP.h UnitTest++/XmlTestReporter.h +UnitTest___libUnitTest___la_SOURCES = UnitTest++/AssertException.cpp UnitTest++/Checks.cpp UnitTest++/CompositeTestReporter.cpp UnitTest++/CurrentTest.cpp UnitTest++/DeferredTestReporter.cpp UnitTest++/DeferredTestResult.cpp UnitTest++/MemoryOutStream.cpp UnitTest++/ReportAssert.cpp UnitTest++/RequiredCheckException.cpp UnitTest++/RequiredCheckTestReporter.cpp UnitTest++/Test.cpp UnitTest++/TestDetails.cpp UnitTest++/TestList.cpp UnitTest++/TestReporter.cpp UnitTest++/TestReporterStdout.cpp UnitTest++/TestResults.cpp UnitTest++/TestRunner.cpp UnitTest++/ThrowingTestReporter.cpp UnitTest++/TimeConstraint.cpp UnitTest++/XmlTestReporter.cpp + +if WINDOWS +nobase_pkginclude_HEADERS += UnitTest++/Win32/TimeHelpers.h +UnitTest___libUnitTest___la_SOURCES += UnitTest++/Win32/TimeHelpers.cpp +else +nobase_pkginclude_HEADERS += UnitTest++/Posix/SignalTranslator.h UnitTest++/Posix/TimeHelpers.h +UnitTest___libUnitTest___la_SOURCES += UnitTest++/Posix/SignalTranslator.cpp UnitTest++/Posix/TimeHelpers.cpp +endif + +UnitTest___libUnitTest___la_LDFLAGS = -version-number @LIBUNITTEST_SO_VERSION@ + + diff --git a/UnitTest++/MemoryOutStream.cpp b/UnitTest++/MemoryOutStream.cpp new file mode 100644 index 0000000..98e52e6 --- /dev/null +++ b/UnitTest++/MemoryOutStream.cpp @@ -0,0 +1,218 @@ +#include "MemoryOutStream.h" + +#ifdef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM + +namespace UnitTest { + + char const* MemoryOutStream::GetText() const + { + m_text = this->str(); + return m_text.c_str(); + } + + void MemoryOutStream::Clear() + { + this->str(std::string()); + m_text = this->str(); + } + +#ifdef UNITTEST_COMPILER_IS_MSVC6 + + #define snprintf _snprintf + + template + std::ostream& FormatToStream(std::ostream& stream, char const* format, ValueType const& value) + { + using namespace std; + + const size_t BUFFER_SIZE=32; + char txt[BUFFER_SIZE]; + snprintf(txt, BUFFER_SIZE, format, value); + return stream << txt; + } + + std::ostream& operator<<(std::ostream& stream, __int64 const n) + { + return FormatToStream(stream, "%I64d", n); + } + + std::ostream& operator<<(std::ostream& stream, unsigned __int64 const n) + { + return FormatToStream(stream, "%I64u", n); + } + +#endif + +} + +#else + +#include +#include + +#if _MSC_VER +#define snprintf _snprintf +#endif + +namespace UnitTest { + + namespace { + + template + void FormatToStream(MemoryOutStream& stream, char const* format, ValueType const& value) + { + using namespace std; + + const size_t BUFFER_SIZE=32; + char txt[BUFFER_SIZE]; + snprintf(txt, BUFFER_SIZE, format, value); + stream << txt; + } + + int RoundUpToMultipleOfPow2Number (int n, int pow2Number) + { + return (n + (pow2Number - 1)) & ~(pow2Number - 1); + } + + } + + + MemoryOutStream::MemoryOutStream(int const size) + : m_capacity (0) + , m_buffer (0) + + { + GrowBuffer(size); + } + + MemoryOutStream::~MemoryOutStream() + { + delete [] m_buffer; + } + + void MemoryOutStream::Clear() + { + m_buffer[0] = '\0'; + } + + char const* MemoryOutStream::GetText() const + { + return m_buffer; + } + + MemoryOutStream& MemoryOutStream::operator <<(char const* txt) + { + using namespace std; + + int const bytesLeft = m_capacity - (int)strlen(m_buffer); + int const bytesRequired = (int)strlen(txt) + 1; + + if (bytesRequired > bytesLeft) + { + int const requiredCapacity = bytesRequired + m_capacity - bytesLeft; + GrowBuffer(requiredCapacity); + } + + strcat(m_buffer, txt); + return *this; + } + + MemoryOutStream& MemoryOutStream::operator <<(int const n) + { + FormatToStream(*this, "%i", n); + return *this; + } + + MemoryOutStream& MemoryOutStream::operator <<(long const n) + { + FormatToStream(*this, "%li", n); + return *this; + } + + MemoryOutStream& MemoryOutStream::operator <<(unsigned long const n) + { + FormatToStream(*this, "%lu", n); + return *this; + } + +#ifdef UNITTEST_COMPILER_IS_MSVC6 + MemoryOutStream& MemoryOutStream::operator <<(__int64 const n) +#else + MemoryOutStream& MemoryOutStream::operator <<(long long const n) +#endif + { +#ifdef UNITTEST_WIN32 + FormatToStream(*this, "%I64d", n); +#else + FormatToStream(*this, "%lld", n); +#endif + + return *this; + } + +#ifdef UNITTEST_COMPILER_IS_MSVC6 + MemoryOutStream& MemoryOutStream::operator <<(unsigned __int64 const n) +#else + MemoryOutStream& MemoryOutStream::operator <<(unsigned long long const n) +#endif + { +#ifdef UNITTEST_WIN32 + FormatToStream(*this, "%I64u", n); +#else + FormatToStream(*this, "%llu", n); +#endif + + return *this; + } + + MemoryOutStream& MemoryOutStream::operator <<(float const f) + { + FormatToStream(*this, "%0.6f", f); + return *this; + } + + MemoryOutStream& MemoryOutStream::operator <<(void const* p) + { + FormatToStream(*this, "%p", p); + return *this; + } + + MemoryOutStream& MemoryOutStream::operator <<(unsigned int const s) + { + FormatToStream(*this, "%u", s); + return *this; + } + + MemoryOutStream& MemoryOutStream::operator <<(double const d) + { + FormatToStream(*this, "%0.6f", d); + return *this; + } + + int MemoryOutStream::GetCapacity() const + { + return m_capacity; + } + + + void MemoryOutStream::GrowBuffer(int const desiredCapacity) + { + int const newCapacity = RoundUpToMultipleOfPow2Number(desiredCapacity, GROW_CHUNK_SIZE); + + using namespace std; + + char* buffer = new char[newCapacity]; + if (m_buffer) + strcpy(buffer, m_buffer); + else + strcpy(buffer, ""); + + delete [] m_buffer; + m_buffer = buffer; + m_capacity = newCapacity; + } + +} + + +#endif diff --git a/UnitTest++/MemoryOutStream.h b/UnitTest++/MemoryOutStream.h new file mode 100644 index 0000000..8a18721 --- /dev/null +++ b/UnitTest++/MemoryOutStream.h @@ -0,0 +1,87 @@ +#ifndef UNITTEST_MEMORYOUTSTREAM_H +#define UNITTEST_MEMORYOUTSTREAM_H + +#include "Config.h" +#include "HelperMacros.h" + +#ifdef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM + +#include + +namespace UnitTest +{ + + class UNITTEST_LINKAGE MemoryOutStream : public std::ostringstream + { + public: + MemoryOutStream() {} + ~MemoryOutStream() {} + void Clear(); + char const* GetText() const; + + private: + MemoryOutStream(MemoryOutStream const&); + void operator =(MemoryOutStream const&); + + mutable std::string m_text; + }; + +#ifdef UNITTEST_COMPILER_IS_MSVC6 + std::ostream& operator<<(std::ostream& stream, __int64 const n); + std::ostream& operator<<(std::ostream& stream, unsigned __int64 const n); +#endif + +} + +#else + +#include + +#ifdef UNITTEST_COMPILER_IS_MSVC6 +namespace std {} +#endif + +namespace UnitTest +{ + + class UNITTEST_LINKAGE MemoryOutStream + { + public: + explicit MemoryOutStream(int const size = 256); + ~MemoryOutStream(); + + void Clear(); + char const* GetText() const; + + MemoryOutStream& operator <<(char const* txt); + MemoryOutStream& operator <<(int n); + MemoryOutStream& operator <<(long n); + MemoryOutStream& operator <<(unsigned long n); +#ifdef UNITTEST_COMPILER_IS_MSVC6 + MemoryOutStream& operator <<(__int64 n); + MemoryOutStream& operator <<(unsigned __int64 n); +#else + MemoryOutStream& operator <<(long long n); + MemoryOutStream& operator <<(unsigned long long n); +#endif + MemoryOutStream& operator <<(float f); + MemoryOutStream& operator <<(double d); + MemoryOutStream& operator <<(void const* p); + MemoryOutStream& operator <<(unsigned int s); + + enum { GROW_CHUNK_SIZE = 32 }; + int GetCapacity() const; + + private: + void operator= (MemoryOutStream const&); + void GrowBuffer(int capacity); + + int m_capacity; + char* m_buffer; + }; + +} + +#endif + +#endif diff --git a/UnitTest++/Posix/SignalTranslator.cpp b/UnitTest++/Posix/SignalTranslator.cpp new file mode 100644 index 0000000..69cc194 --- /dev/null +++ b/UnitTest++/Posix/SignalTranslator.cpp @@ -0,0 +1,46 @@ +#include "SignalTranslator.h" + +namespace UnitTest { + + sigjmp_buf* SignalTranslator::s_jumpTarget = 0; + + namespace { + + void SignalHandler(int sig) + { + siglongjmp(*SignalTranslator::s_jumpTarget, sig ); + } + + } + + + SignalTranslator::SignalTranslator() + { + m_oldJumpTarget = s_jumpTarget; + s_jumpTarget = &m_currentJumpTarget; + + struct sigaction action; + action.sa_flags = 0; + action.sa_handler = SignalHandler; + sigemptyset( &action.sa_mask ); + + sigaction( SIGSEGV, &action, &m_old_SIGSEGV_action ); + sigaction( SIGFPE, &action, &m_old_SIGFPE_action ); + sigaction( SIGTRAP, &action, &m_old_SIGTRAP_action ); + sigaction( SIGBUS, &action, &m_old_SIGBUS_action ); + sigaction( SIGILL, &action, &m_old_SIGILL_action ); + } + + SignalTranslator::~SignalTranslator() + { + sigaction( SIGILL, &m_old_SIGILL_action, 0 ); + sigaction( SIGBUS, &m_old_SIGBUS_action, 0 ); + sigaction( SIGTRAP, &m_old_SIGTRAP_action, 0 ); + sigaction( SIGFPE, &m_old_SIGFPE_action, 0 ); + sigaction( SIGSEGV, &m_old_SIGSEGV_action, 0 ); + + s_jumpTarget = m_oldJumpTarget; + } + + +} diff --git a/UnitTest++/Posix/SignalTranslator.h b/UnitTest++/Posix/SignalTranslator.h new file mode 100644 index 0000000..66d388d --- /dev/null +++ b/UnitTest++/Posix/SignalTranslator.h @@ -0,0 +1,41 @@ +#ifndef UNITTEST_SIGNALTRANSLATOR_H +#define UNITTEST_SIGNALTRANSLATOR_H + +#include +#include + +namespace UnitTest { + + class SignalTranslator + { + public: + SignalTranslator(); + ~SignalTranslator(); + + static sigjmp_buf* s_jumpTarget; + + private: + sigjmp_buf m_currentJumpTarget; + sigjmp_buf* m_oldJumpTarget; + + struct sigaction m_old_SIGFPE_action; + struct sigaction m_old_SIGTRAP_action; + struct sigaction m_old_SIGSEGV_action; + struct sigaction m_old_SIGBUS_action; + struct sigaction m_old_SIGILL_action; + }; + +#if !defined (__GNUC__) + #define UNITTEST_EXTENSION +#else + #define UNITTEST_EXTENSION __extension__ +#endif + + #define UNITTEST_THROW_SIGNALS_POSIX_ONLY \ + UnitTest::SignalTranslator sig; \ + if (UNITTEST_EXTENSION sigsetjmp(*UnitTest::SignalTranslator::s_jumpTarget, 1) != 0) \ + throw ("Unhandled system exception"); + +} + +#endif diff --git a/UnitTest++/Posix/TimeHelpers.cpp b/UnitTest++/Posix/TimeHelpers.cpp new file mode 100644 index 0000000..d9a78eb --- /dev/null +++ b/UnitTest++/Posix/TimeHelpers.cpp @@ -0,0 +1,33 @@ +#include "TimeHelpers.h" +#include + +namespace UnitTest { + + Timer::Timer() + { + m_startTime.tv_sec = 0; + m_startTime.tv_usec = 0; + } + + void Timer::Start() + { + gettimeofday(&m_startTime, 0); + } + + double Timer::GetTimeInMs() const + { + struct timeval currentTime; + gettimeofday(¤tTime, 0); + + double const dsecs = currentTime.tv_sec - m_startTime.tv_sec; + double const dus = currentTime.tv_usec - m_startTime.tv_usec; + + return (dsecs * 1000.0) + (dus / 1000.0); + } + + void TimeHelpers::SleepMs(int ms) + { + usleep(static_cast(ms * 1000)); + } + +} diff --git a/UnitTest++/Posix/TimeHelpers.h b/UnitTest++/Posix/TimeHelpers.h new file mode 100644 index 0000000..630260d --- /dev/null +++ b/UnitTest++/Posix/TimeHelpers.h @@ -0,0 +1,28 @@ +#ifndef UNITTEST_TIMEHELPERS_H +#define UNITTEST_TIMEHELPERS_H + +#include + +namespace UnitTest { + + class Timer + { + public: + Timer(); + void Start(); + double GetTimeInMs() const; + + private: + struct timeval m_startTime; + }; + + + namespace TimeHelpers + { + void SleepMs(int ms); + } + + +} + +#endif diff --git a/UnitTest++/ReportAssert.cpp b/UnitTest++/ReportAssert.cpp new file mode 100644 index 0000000..47d0c5f --- /dev/null +++ b/UnitTest++/ReportAssert.cpp @@ -0,0 +1,71 @@ +#include "ReportAssert.h" +#include "ReportAssertImpl.h" +#include "AssertException.h" +#include "CurrentTest.h" +#include "TestResults.h" +#include "TestDetails.h" + +#ifdef UNITTEST_NO_EXCEPTIONS + #include "ReportAssertImpl.h" +#endif + +namespace UnitTest { + + namespace + { + bool& AssertExpectedFlag() + { + static bool s_assertExpected = false; + return s_assertExpected; + } + } + + UNITTEST_LINKAGE void ReportAssert(char const* description, char const* filename, int lineNumber) + { + Detail::ReportAssertEx(CurrentTest::Results(), CurrentTest::Details(), + description, filename, lineNumber); + } + + namespace Detail { + +#ifdef UNITTEST_NO_EXCEPTIONS + UNITTEST_JMPBUF* GetAssertJmpBuf() + { + static UNITTEST_JMPBUF s_jmpBuf; + return &s_jmpBuf; + } +#endif + + UNITTEST_LINKAGE void ReportAssertEx(TestResults* testResults, + const TestDetails* testDetails, + char const* description, + char const* filename, + int lineNumber) + { + if (AssertExpectedFlag() == false) + { + TestDetails assertDetails(testDetails->testName, testDetails->suiteName, filename, lineNumber); + testResults->OnTestFailure(assertDetails, description); + } + + ExpectAssert(false); + +#ifndef UNITTEST_NO_EXCEPTIONS + throw AssertException(); +#else + UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET(); +#endif + } + + UNITTEST_LINKAGE void ExpectAssert(bool expected) + { + AssertExpectedFlag() = expected; + } + + UNITTEST_LINKAGE bool AssertExpected() + { + return AssertExpectedFlag(); + } + + } +} diff --git a/src/ReportAssert.h b/UnitTest++/ReportAssert.h similarity index 50% rename from src/ReportAssert.h rename to UnitTest++/ReportAssert.h index 7bdf7bb..c22faab 100644 --- a/src/ReportAssert.h +++ b/UnitTest++/ReportAssert.h @@ -1,12 +1,12 @@ -#ifndef UNITTEST_ASSERT_H -#define UNITTEST_ASSERT_H - -#include "HelperMacros.h" - -namespace UnitTest { - -UNITTEST_LINKAGE void ReportAssert(char const* description, char const* filename, int lineNumber); - -} - -#endif +#ifndef UNITTEST_ASSERT_H +#define UNITTEST_ASSERT_H + +#include "HelperMacros.h" + +namespace UnitTest { + + UNITTEST_LINKAGE void ReportAssert(char const* description, char const* filename, int lineNumber); + +} + +#endif diff --git a/UnitTest++/ReportAssertImpl.h b/UnitTest++/ReportAssertImpl.h new file mode 100644 index 0000000..865292f --- /dev/null +++ b/UnitTest++/ReportAssertImpl.h @@ -0,0 +1,46 @@ +#ifndef UNITTEST_REPORTASSERTIMPL_H +#define UNITTEST_REPORTASSERTIMPL_H + +#include "Config.h" +#include "HelperMacros.h" + +#ifdef UNITTEST_NO_EXCEPTIONS + #include +#endif + +namespace UnitTest { + + class TestResults; + class TestDetails; + + namespace Detail { + + UNITTEST_LINKAGE void ExpectAssert(bool expected); + + UNITTEST_LINKAGE void ReportAssertEx(TestResults* testResults, + const TestDetails* testDetails, + char const* description, + char const* filename, + int lineNumber); + + UNITTEST_LINKAGE bool AssertExpected(); + +#ifdef UNITTEST_NO_EXCEPTIONS + UNITTEST_LINKAGE UNITTEST_JMPBUF* GetAssertJmpBuf(); + +#ifdef UNITTEST_WIN32 + #define UNITTEST_SET_ASSERT_JUMP_TARGET() \ + __pragma(warning(push)) __pragma(warning(disable: 4611)) \ + UNITTEST_SETJMP(*UnitTest::Detail::GetAssertJmpBuf()) \ + __pragma(warning(pop)) +#else + #define UNITTEST_SET_ASSERT_JUMP_TARGET() UNITTEST_SETJMP(*UnitTest::Detail::GetAssertJmpBuf()) +#endif + + #define UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET() UNITTEST_LONGJMP(*UnitTest::Detail::GetAssertJmpBuf(), 1) +#endif + + } +} + +#endif diff --git a/UnitTest++/RequireMacros.h b/UnitTest++/RequireMacros.h new file mode 100644 index 0000000..7fe793b --- /dev/null +++ b/UnitTest++/RequireMacros.h @@ -0,0 +1,16 @@ +#ifndef UNITTEST_REQUIREMACROS_H +#define UNITTEST_REQUIREMACROS_H + +#include "RequiredCheckTestReporter.h" + +#define UNITTEST_REQUIRE for(UnitTest::RequiredCheckTestReporter decoratedReporter(*UnitTest::CurrentTest::Results()); decoratedReporter.Next(); ) + +#ifndef UNITTEST_DISABLE_SHORT_MACROS + #ifdef REQUIRE + #error REQUIRE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_REQUIRE instead + #else + #define REQUIRE UNITTEST_REQUIRE + #endif +#endif + +#endif diff --git a/UnitTest++/RequiredCheckException.cpp b/UnitTest++/RequiredCheckException.cpp new file mode 100644 index 0000000..874370e --- /dev/null +++ b/UnitTest++/RequiredCheckException.cpp @@ -0,0 +1,17 @@ +#include "RequiredCheckException.h" + +#ifndef UNITTEST_NO_EXCEPTIONS + +namespace UnitTest { + + RequiredCheckException::RequiredCheckException() + { + } + + RequiredCheckException::~RequiredCheckException() throw() + { + } + +} + +#endif diff --git a/UnitTest++/RequiredCheckException.h b/UnitTest++/RequiredCheckException.h new file mode 100644 index 0000000..c9a36da --- /dev/null +++ b/UnitTest++/RequiredCheckException.h @@ -0,0 +1,23 @@ +#ifndef UNITTEST_REQUIREDCHECKEXCEPTION_H +#define UNITTEST_REQUIREDCHECKEXCEPTION_H + +#include "Config.h" +#ifndef UNITTEST_NO_EXCEPTIONS + +#include "HelperMacros.h" +#include + +namespace UnitTest { + + class UNITTEST_LINKAGE RequiredCheckException : public std::exception + { + public: + RequiredCheckException(); + virtual ~RequiredCheckException() throw(); + }; + +} + +#endif + +#endif diff --git a/UnitTest++/RequiredCheckTestReporter.cpp b/UnitTest++/RequiredCheckTestReporter.cpp new file mode 100644 index 0000000..7c21d20 --- /dev/null +++ b/UnitTest++/RequiredCheckTestReporter.cpp @@ -0,0 +1,26 @@ +#include "RequiredCheckTestReporter.h" + +#include "CurrentTest.h" +#include "TestResults.h" + +namespace UnitTest { + + RequiredCheckTestReporter::RequiredCheckTestReporter(TestResults& results) + : m_results(results) + , m_originalTestReporter(results.m_testReporter) + , m_throwingReporter(results.m_testReporter) + , m_continue(0) + { + m_results.m_testReporter = &m_throwingReporter; + } + + RequiredCheckTestReporter::~RequiredCheckTestReporter() + { + m_results.m_testReporter = m_originalTestReporter; + } + + bool RequiredCheckTestReporter::Next() + { + return m_continue++ == 0; + } +} \ No newline at end of file diff --git a/UnitTest++/RequiredCheckTestReporter.h b/UnitTest++/RequiredCheckTestReporter.h new file mode 100644 index 0000000..99d9cdd --- /dev/null +++ b/UnitTest++/RequiredCheckTestReporter.h @@ -0,0 +1,33 @@ +#ifndef UNITTEST_REQUIRED_CHECK_TEST_REPORTER_H +#define UNITTEST_REQUIRED_CHECK_TEST_REPORTER_H + +#include "HelperMacros.h" +#include "ThrowingTestReporter.h" + +namespace UnitTest { + + class TestResults; + + // This RAII class decorates the current TestReporter with + // a version that throws after reporting a failure. + class UNITTEST_LINKAGE RequiredCheckTestReporter + { + public: + explicit RequiredCheckTestReporter(TestResults& results); + ~RequiredCheckTestReporter(); + + bool Next(); + + private: + RequiredCheckTestReporter(RequiredCheckTestReporter const&); + RequiredCheckTestReporter& operator =(RequiredCheckTestReporter const&); + + TestResults& m_results; + TestReporter* m_originalTestReporter; + ThrowingTestReporter m_throwingReporter; + int m_continue; + }; +} + +#endif + diff --git a/UnitTest++/Test.cpp b/UnitTest++/Test.cpp new file mode 100644 index 0000000..82ed710 --- /dev/null +++ b/UnitTest++/Test.cpp @@ -0,0 +1,38 @@ +#include "Config.h" +#include "Test.h" +#include "TestList.h" +#include "TestResults.h" +#include "AssertException.h" +#include "MemoryOutStream.h" +#include "ExecuteTest.h" + +#ifdef UNITTEST_POSIX +#include "Posix/SignalTranslator.h" +#endif + +namespace UnitTest { + + TestList& Test::GetTestList() + { + static TestList s_list; + return s_list; + } + + Test::Test(char const* testName, char const* suiteName, char const* filename, int lineNumber) + : m_details(testName, suiteName, filename, lineNumber) + , m_nextTest(0) + , m_isMockTest(false) + {} + + Test::~Test() + {} + + void Test::Run() + { + ExecuteTest(*this, m_details, m_isMockTest); + } + + void Test::RunImpl() const + {} + +} diff --git a/UnitTest++/Test.h b/UnitTest++/Test.h new file mode 100644 index 0000000..beb0769 --- /dev/null +++ b/UnitTest++/Test.h @@ -0,0 +1,35 @@ +#ifndef UNITTEST_TEST_H +#define UNITTEST_TEST_H + +#include "TestDetails.h" + +namespace UnitTest { + + class TestResults; + class TestList; + + class UNITTEST_LINKAGE Test + { + public: + explicit Test(char const* testName, char const* suiteName = "DefaultSuite", char const* filename = "", int lineNumber = 0); + virtual ~Test(); + void Run(); + + TestDetails const m_details; + Test* m_nextTest; + + mutable bool m_isMockTest; + + static TestList& GetTestList(); + + virtual void RunImpl() const; + + private: + Test(Test const&); + Test& operator =(Test const&); + }; + + +} + +#endif diff --git a/UnitTest++/TestDetails.cpp b/UnitTest++/TestDetails.cpp new file mode 100644 index 0000000..deb6639 --- /dev/null +++ b/UnitTest++/TestDetails.cpp @@ -0,0 +1,22 @@ +#include "TestDetails.h" + +namespace UnitTest { + + TestDetails::TestDetails(char const* testName_, char const* suiteName_, char const* filename_, int lineNumber_) + : suiteName(suiteName_) + , testName(testName_) + , filename(filename_) + , lineNumber(lineNumber_) + , timeConstraintExempt(false) + {} + + TestDetails::TestDetails(const TestDetails& details, int lineNumber_) + : suiteName(details.suiteName) + , testName(details.testName) + , filename(details.filename) + , lineNumber(lineNumber_) + , timeConstraintExempt(details.timeConstraintExempt) + {} + + +} diff --git a/UnitTest++/TestDetails.h b/UnitTest++/TestDetails.h new file mode 100644 index 0000000..cf6f1d3 --- /dev/null +++ b/UnitTest++/TestDetails.h @@ -0,0 +1,27 @@ +#ifndef UNITTEST_TESTDETAILS_H +#define UNITTEST_TESTDETAILS_H + +#include "HelperMacros.h" + +namespace UnitTest { + + class UNITTEST_LINKAGE TestDetails + { + public: + TestDetails(char const* testName, char const* suiteName, char const* filename, int lineNumber); + TestDetails(const TestDetails& details, int lineNumber); + + char const* const suiteName; + char const* const testName; + char const* const filename; + int const lineNumber; + mutable bool timeConstraintExempt; + + TestDetails(TestDetails const&); // Why is it public? --> http://gcc.gnu.org/bugs.html#cxx_rvalbind + private: + TestDetails& operator=(TestDetails const&); + }; + +} + +#endif diff --git a/UnitTest++/TestList.cpp b/UnitTest++/TestList.cpp new file mode 100644 index 0000000..a2bc4b7 --- /dev/null +++ b/UnitTest++/TestList.cpp @@ -0,0 +1,38 @@ +#include "TestList.h" +#include "Test.h" + +#include + +namespace UnitTest { + + TestList::TestList() + : m_head(0) + , m_tail(0) + {} + + void TestList::Add(Test* test) + { + if (m_tail == 0) + { + assert(m_head == 0); + m_head = test; + m_tail = test; + } + else + { + m_tail->m_nextTest = test; + m_tail = test; + } + } + + Test* TestList::GetHead() const + { + return m_head; + } + + ListAdder::ListAdder(TestList& list, Test* test) + { + list.Add(test); + } + +} diff --git a/UnitTest++/TestList.h b/UnitTest++/TestList.h new file mode 100644 index 0000000..d52ab51 --- /dev/null +++ b/UnitTest++/TestList.h @@ -0,0 +1,33 @@ +#ifndef UNITTEST_TESTLIST_H +#define UNITTEST_TESTLIST_H + +#include "HelperMacros.h" + +namespace UnitTest { + + class Test; + + class UNITTEST_LINKAGE TestList + { + public: + TestList(); + void Add (Test* test); + + Test* GetHead() const; + + private: + Test* m_head; + Test* m_tail; + }; + + + class UNITTEST_LINKAGE ListAdder + { + public: + ListAdder(TestList& list, Test* test); + }; + +} + + +#endif diff --git a/UnitTest++/TestMacros.h b/UnitTest++/TestMacros.h new file mode 100644 index 0000000..0c8e903 --- /dev/null +++ b/UnitTest++/TestMacros.h @@ -0,0 +1,126 @@ +#ifndef UNITTEST_TESTMACROS_H +#define UNITTEST_TESTMACROS_H + +#include "Config.h" +#include "TestSuite.h" +#include "ExceptionMacros.h" +#include "ExecuteTest.h" +#include "AssertException.h" +#include "TestDetails.h" +#include "MemoryOutStream.h" + +#ifndef UNITTEST_POSIX +#define UNITTEST_THROW_SIGNALS_POSIX_ONLY +#else +#include "Posix/SignalTranslator.h" +#endif + +#define UNITTEST_SUITE(Name) \ + namespace Suite ## Name { \ + namespace UnitTestSuite { \ + inline char const* GetSuiteName () { \ + return #Name; \ + } \ + } \ + } \ + namespace Suite ## Name + +#define UNITTEST_IMPL_TEST(Name, List) \ + class Test ## Name : public UnitTest::Test \ + { \ + public: \ + Test ## Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ + private: \ + virtual void RunImpl() const; \ + } static test ## Name ## Instance; \ + \ + static UnitTest::ListAdder adder ## Name (List, &test ## Name ## Instance); \ + \ + void Test ## Name::RunImpl() const + + +#define UNITTEST_TEST(Name) UNITTEST_IMPL_TEST(Name, UnitTest::Test::GetTestList()) + + +#define UNITTEST_IMPL_TEST_FIXTURE(Fixture, Name, List) \ + class Fixture ## Name ## Helper : public Fixture \ + { \ + public: \ + explicit Fixture ## Name ## Helper(UnitTest::TestDetails const& details) : m_details(details) {} \ + void RunImpl(); \ + UnitTest::TestDetails const& m_details; \ + virtual ~Fixture ## Name ## Helper(); \ + private: \ + Fixture ## Name ## Helper(Fixture ## Name ## Helper const&); \ + Fixture ## Name ## Helper& operator =(Fixture ## Name ## Helper const&); \ + }; \ + Fixture ## Name ## Helper::~Fixture ## Name ## Helper(){} \ + \ + class Test ## Fixture ## Name : public UnitTest::Test \ + { \ + public: \ + Test ## Fixture ## Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ + private: \ + virtual void RunImpl() const; \ + } static test ## Fixture ## Name ## Instance; \ + \ + static UnitTest::ListAdder adder ## Fixture ## Name (List, &test ## Fixture ## Name ## Instance); \ + \ + void Test ## Fixture ## Name::RunImpl() const \ + { \ + volatile bool ctorOk = false; \ + UNITTEST_IMPL_TRY \ + ({ \ + Fixture ## Name ## Helper fixtureHelper(m_details); \ + ctorOk = true; \ + UnitTest::ExecuteTest(fixtureHelper, m_details, false); \ + }) \ + UNITTEST_IMPL_CATCH (UnitTest::AssertException, e, \ + { \ + (void)e; \ + }) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream stream; \ + stream << "Unhandled exception: " << e.what(); \ + UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + if (ctorOk) \ + { \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception while destroying fixture " #Fixture); \ + } \ + else \ + { \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception while constructing fixture " #Fixture); \ + } \ + }) \ + } \ + void Fixture ## Name ## Helper::RunImpl() + +#define UNITTEST_TEST_FIXTURE(Fixture,Name) UNITTEST_IMPL_TEST_FIXTURE(Fixture, Name, UnitTest::Test::GetTestList()) + +#ifndef UNITTEST_DISABLE_SHORT_MACROS + #ifdef SUITE + #error SUITE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_SUITE instead + #else + #define SUITE UNITTEST_SUITE + #endif + + #ifdef TEST + #error TEST already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_TEST instead + #else + #define TEST UNITTEST_TEST + #endif + + #ifdef TEST_FIXTURE + #error TEST_FIXTURE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_TEST_FIXTURE instead + #else + #define TEST_FIXTURE UNITTEST_TEST_FIXTURE + #endif +#endif + +#endif diff --git a/src/TestReporter.cpp b/UnitTest++/TestReporter.cpp similarity index 54% rename from src/TestReporter.cpp rename to UnitTest++/TestReporter.cpp index 78c765f..362da93 100644 --- a/src/TestReporter.cpp +++ b/UnitTest++/TestReporter.cpp @@ -1,9 +1,8 @@ -#include "TestReporter.h" - -namespace UnitTest { - -TestReporter::~TestReporter() -{ -} - -} +#include "TestReporter.h" + +namespace UnitTest { + + TestReporter::~TestReporter() + {} + +} diff --git a/UnitTest++/TestReporter.h b/UnitTest++/TestReporter.h new file mode 100644 index 0000000..f296a59 --- /dev/null +++ b/UnitTest++/TestReporter.h @@ -0,0 +1,22 @@ +#ifndef UNITTEST_TESTREPORTER_H +#define UNITTEST_TESTREPORTER_H + +#include "HelperMacros.h" + +namespace UnitTest { + + class TestDetails; + + class UNITTEST_LINKAGE TestReporter + { + public: + virtual ~TestReporter(); + + virtual void ReportTestStart(TestDetails const& test) = 0; + virtual void ReportFailure(TestDetails const& test, char const* failure) = 0; + virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed) = 0; + virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) = 0; + }; + +} +#endif diff --git a/UnitTest++/TestReporterStdout.cpp b/UnitTest++/TestReporterStdout.cpp new file mode 100644 index 0000000..97b0f14 --- /dev/null +++ b/UnitTest++/TestReporterStdout.cpp @@ -0,0 +1,44 @@ +#include "TestReporterStdout.h" +#include + +#include "TestDetails.h" + +// cstdio doesn't pull in namespace std on VC6, so we do it here. +#if defined(UNITTEST_WIN32) && (_MSC_VER == 1200) +namespace std {} +#endif + +namespace UnitTest { + + void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure) + { + using namespace std; +#if defined(__APPLE__) || defined(__GNUG__) + char const* const errorFormat = "%s:%d:%d: error: Failure in %s: %s\n"; + fprintf(stderr, errorFormat, details.filename, details.lineNumber, 1, details.testName, failure); +#else + char const* const errorFormat = "%s(%d): error: Failure in %s: %s\n"; + fprintf(stderr, errorFormat, details.filename, details.lineNumber, details.testName, failure); +#endif + } + + void TestReporterStdout::ReportTestStart(TestDetails const& /*test*/) + {} + + void TestReporterStdout::ReportTestFinish(TestDetails const& /*test*/, float) + {} + + void TestReporterStdout::ReportSummary(int const totalTestCount, int const failedTestCount, + int const failureCount, float const secondsElapsed) + { + using namespace std; + + if (failureCount > 0) + printf("FAILURE: %d out of %d tests failed (%d failures).\n", failedTestCount, totalTestCount, failureCount); + else + printf("Success: %d tests passed.\n", totalTestCount); + + printf("Test time: %.2f seconds.\n", secondsElapsed); + } + +} diff --git a/UnitTest++/TestReporterStdout.h b/UnitTest++/TestReporterStdout.h new file mode 100644 index 0000000..6cedfc5 --- /dev/null +++ b/UnitTest++/TestReporterStdout.h @@ -0,0 +1,19 @@ +#ifndef UNITTEST_TESTREPORTERSTDOUT_H +#define UNITTEST_TESTREPORTERSTDOUT_H + +#include "TestReporter.h" + +namespace UnitTest { + + class UNITTEST_LINKAGE TestReporterStdout : public TestReporter + { + private: + virtual void ReportTestStart(TestDetails const& test); + virtual void ReportFailure(TestDetails const& test, char const* failure); + virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed); + virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); + }; + +} + +#endif diff --git a/UnitTest++/TestResults.cpp b/UnitTest++/TestResults.cpp new file mode 100644 index 0000000..e40ea70 --- /dev/null +++ b/UnitTest++/TestResults.cpp @@ -0,0 +1,59 @@ +#include "TestResults.h" +#include "TestReporter.h" + +#include "TestDetails.h" + +namespace UnitTest { + + TestResults::TestResults(TestReporter* testReporter) + : m_testReporter(testReporter) + , m_totalTestCount(0) + , m_failedTestCount(0) + , m_failureCount(0) + , m_currentTestFailed(false) + {} + + void TestResults::OnTestStart(TestDetails const& test) + { + ++m_totalTestCount; + m_currentTestFailed = false; + if (m_testReporter) + m_testReporter->ReportTestStart(test); + } + + void TestResults::OnTestFailure(TestDetails const& test, char const* failure) + { + ++m_failureCount; + if (!m_currentTestFailed) + { + ++m_failedTestCount; + m_currentTestFailed = true; + } + + if (m_testReporter) + m_testReporter->ReportFailure(test, failure); + } + + void TestResults::OnTestFinish(TestDetails const& test, float secondsElapsed) + { + if (m_testReporter) + m_testReporter->ReportTestFinish(test, secondsElapsed); + } + + int TestResults::GetTotalTestCount() const + { + return m_totalTestCount; + } + + int TestResults::GetFailedTestCount() const + { + return m_failedTestCount; + } + + int TestResults::GetFailureCount() const + { + return m_failureCount; + } + + +} diff --git a/UnitTest++/TestResults.h b/UnitTest++/TestResults.h new file mode 100644 index 0000000..a4d8e60 --- /dev/null +++ b/UnitTest++/TestResults.h @@ -0,0 +1,41 @@ +#ifndef UNITTEST_TESTRESULTS_H +#define UNITTEST_TESTRESULTS_H + +#include "HelperMacros.h" + +namespace UnitTest { + + class RequiredCheckTestReporter; + class TestReporter; + class TestDetails; + + class UNITTEST_LINKAGE TestResults + { + public: + explicit TestResults(TestReporter* reporter = 0); + + void OnTestStart(TestDetails const& test); + void OnTestFailure(TestDetails const& test, char const* failure); + void OnTestFinish(TestDetails const& test, float secondsElapsed); + + int GetTotalTestCount() const; + int GetFailedTestCount() const; + int GetFailureCount() const; + + private: + friend class RequiredCheckTestReporter; + + TestReporter* m_testReporter; + int m_totalTestCount; + int m_failedTestCount; + int m_failureCount; + + bool m_currentTestFailed; + + TestResults(TestResults const&); + TestResults& operator =(TestResults const&); + }; + +} + +#endif diff --git a/UnitTest++/TestRunner.cpp b/UnitTest++/TestRunner.cpp new file mode 100644 index 0000000..8e0581d --- /dev/null +++ b/UnitTest++/TestRunner.cpp @@ -0,0 +1,82 @@ +#include "TestRunner.h" +#include "TestResults.h" +#include "TestReporter.h" +#include "TestReporterStdout.h" +#include "TimeHelpers.h" +#include "MemoryOutStream.h" + +#include + + +namespace UnitTest { + + int RunAllTests() + { + TestReporterStdout reporter; + TestRunner runner(reporter); + return runner.RunTestsIf(Test::GetTestList(), NULL, True(), 0); + } + + + TestRunner::TestRunner(TestReporter& reporter) + : m_reporter(&reporter) + , m_result(new TestResults(&reporter)) + , m_timer(new Timer) + { + m_timer->Start(); + } + + TestRunner::~TestRunner() + { + delete m_result; + delete m_timer; + } + + TestResults* TestRunner::GetTestResults() + { + return m_result; + } + + int TestRunner::Finish() const + { + float const secondsElapsed = static_cast(m_timer->GetTimeInMs() / 1000.0); + m_reporter->ReportSummary(m_result->GetTotalTestCount(), + m_result->GetFailedTestCount(), + m_result->GetFailureCount(), + secondsElapsed); + + return m_result->GetFailureCount(); + } + + bool TestRunner::IsTestInSuite(const Test* const curTest, char const* suiteName) const + { + using namespace std; + return (suiteName == NULL) || !strcmp(curTest->m_details.suiteName, suiteName); + } + + void TestRunner::RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const + { + if (curTest->m_isMockTest == false) + CurrentTest::Results() = result; + + Timer testTimer; + testTimer.Start(); + + result->OnTestStart(curTest->m_details); + + curTest->Run(); + + double const testTimeInMs = testTimer.GetTimeInMs(); + if (maxTestTimeInMs > 0 && testTimeInMs > maxTestTimeInMs && !curTest->m_details.timeConstraintExempt) + { + MemoryOutStream stream; + stream << "Global time constraint failed. Expected under " << maxTestTimeInMs << + "ms but took " << testTimeInMs << "ms."; + + result->OnTestFailure(curTest->m_details, stream.GetText()); + } + + result->OnTestFinish(curTest->m_details, static_cast< float >(testTimeInMs / 1000.0)); + } + +} diff --git a/UnitTest++/TestRunner.h b/UnitTest++/TestRunner.h new file mode 100644 index 0000000..914249a --- /dev/null +++ b/UnitTest++/TestRunner.h @@ -0,0 +1,61 @@ +#ifndef UNITTEST_TESTRUNNER_H +#define UNITTEST_TESTRUNNER_H + +#include "Test.h" +#include "TestList.h" +#include "CurrentTest.h" + +namespace UnitTest { + + class TestReporter; + class TestResults; + class Timer; + + UNITTEST_LINKAGE int RunAllTests(); + + struct True + { + bool operator()(const Test* const) const + { + return true; + } + }; + + class UNITTEST_LINKAGE TestRunner + { + public: + explicit TestRunner(TestReporter& reporter); + ~TestRunner(); + + template< class Predicate > + int RunTestsIf(TestList const& list, char const* suiteName, + const Predicate& predicate, int maxTestTimeInMs) const + { + Test* curTest = list.GetHead(); + + while (curTest != 0) + { + if (IsTestInSuite(curTest, suiteName) && predicate(curTest)) + RunTest(m_result, curTest, maxTestTimeInMs); + + curTest = curTest->m_nextTest; + } + + return Finish(); + } + + TestResults* GetTestResults(); + + private: + TestReporter* m_reporter; + TestResults* m_result; + Timer* m_timer; + + int Finish() const; + bool IsTestInSuite(const Test* const curTest, char const* suiteName) const; + void RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const; + }; + +} + +#endif diff --git a/UnitTest++/TestSuite.h b/UnitTest++/TestSuite.h new file mode 100644 index 0000000..7b70122 --- /dev/null +++ b/UnitTest++/TestSuite.h @@ -0,0 +1,12 @@ +#ifndef UNITTEST_TESTSUITE_H +#define UNITTEST_TESTSUITE_H + +namespace UnitTestSuite +{ + inline char const* GetSuiteName () + { + return "DefaultSuite"; + } +} + +#endif diff --git a/UnitTest++/ThrowingTestReporter.cpp b/UnitTest++/ThrowingTestReporter.cpp new file mode 100644 index 0000000..4e56149 --- /dev/null +++ b/UnitTest++/ThrowingTestReporter.cpp @@ -0,0 +1,61 @@ +#include "ThrowingTestReporter.h" +#include "RequiredCheckException.h" + +#ifdef UNITTEST_NO_EXCEPTIONS +#include "ReportAssertImpl.h" +#endif + +namespace UnitTest { + + ThrowingTestReporter::ThrowingTestReporter(TestReporter* decoratedReporter) + : m_decoratedReporter(decoratedReporter) + {} + + //virtual + ThrowingTestReporter::~ThrowingTestReporter() + {} + + //virtual + void ThrowingTestReporter::ReportTestStart(TestDetails const& test) + { + if(m_decoratedReporter) + { + m_decoratedReporter->ReportTestStart(test); + } + } + + //virtual + void ThrowingTestReporter::ReportFailure(TestDetails const& test, char const* failure) + { + if(m_decoratedReporter) + { + m_decoratedReporter->ReportFailure(test, failure); + } + + #ifndef UNITTEST_NO_EXCEPTIONS + throw RequiredCheckException(); + #else + static const int stopTest = 1; + UNITTEST_LONGJMP(*UnitTest::Detail::GetAssertJmpBuf(), stopTest); + #endif + } + + //virtual + void ThrowingTestReporter::ReportTestFinish(TestDetails const& test, float secondsElapsed) + { + if(m_decoratedReporter) + { + m_decoratedReporter->ReportTestFinish(test, secondsElapsed); + } + } + + //virtual + void ThrowingTestReporter::ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) + { + if(m_decoratedReporter) + { + m_decoratedReporter->ReportSummary(totalTestCount, failedTestCount, failureCount, secondsElapsed); + } + } + +} diff --git a/UnitTest++/ThrowingTestReporter.h b/UnitTest++/ThrowingTestReporter.h new file mode 100644 index 0000000..34e105e --- /dev/null +++ b/UnitTest++/ThrowingTestReporter.h @@ -0,0 +1,26 @@ +#ifndef UNITTEST_THROWINGTESTREPORTER_H +#define UNITTEST_THROWINGTESTREPORTER_H + +#include "TestReporter.h" + +namespace UnitTest { + + // A TestReporter that throws when ReportFailure is called. Otherwise it + // forwards the calls to a decorated TestReporter + class ThrowingTestReporter : public TestReporter + { + public: + explicit ThrowingTestReporter(TestReporter* reporter); + + virtual ~ThrowingTestReporter(); + virtual void ReportTestStart(TestDetails const& test); + virtual void ReportFailure(TestDetails const& test, char const* failure); + virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed); + virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); + + private: + TestReporter* m_decoratedReporter; + }; +} + +#endif diff --git a/UnitTest++/TimeConstraint.cpp b/UnitTest++/TimeConstraint.cpp new file mode 100644 index 0000000..e45dd97 --- /dev/null +++ b/UnitTest++/TimeConstraint.cpp @@ -0,0 +1,29 @@ +#include "TimeConstraint.h" +#include "TestResults.h" +#include "MemoryOutStream.h" +#include "CurrentTest.h" + +namespace UnitTest { + + + TimeConstraint::TimeConstraint(int ms, TestDetails const& details, int lineNumber) + : m_details(details, lineNumber) + , m_maxMs(ms) + { + m_timer.Start(); + } + + TimeConstraint::~TimeConstraint() + { + double const totalTimeInMs = m_timer.GetTimeInMs(); + if (totalTimeInMs > m_maxMs) + { + MemoryOutStream stream; + stream << "Time constraint failed. Expected to run test under " << m_maxMs << + "ms but took " << totalTimeInMs << "ms."; + + CurrentTest::Results()->OnTestFailure(m_details, stream.GetText()); + } + } + +} diff --git a/UnitTest++/TimeConstraint.h b/UnitTest++/TimeConstraint.h new file mode 100644 index 0000000..be9d255 --- /dev/null +++ b/UnitTest++/TimeConstraint.h @@ -0,0 +1,37 @@ +#ifndef UNITTEST_TIMECONSTRAINT_H +#define UNITTEST_TIMECONSTRAINT_H + +#include "TimeHelpers.h" +#include "HelperMacros.h" +#include "TestDetails.h" + +namespace UnitTest { + + class TestResults; + + class UNITTEST_LINKAGE TimeConstraint + { + public: + TimeConstraint(int ms, TestDetails const& details, int lineNumber); + ~TimeConstraint(); + + private: + void operator=(TimeConstraint const&); + TimeConstraint(TimeConstraint const&); + + Timer m_timer; + TestDetails const m_details; + int const m_maxMs; + }; + + #define UNITTEST_TIME_CONSTRAINT(ms) \ + UnitTest::TimeConstraint unitTest__timeConstraint__(ms, m_details, __LINE__) + + #define UNITTEST_TIME_CONSTRAINT_EXEMPT() \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + m_details.timeConstraintExempt = true; \ + UNITTEST_MULTILINE_MACRO_END + +} + +#endif diff --git a/UnitTest++/TimeHelpers.h b/UnitTest++/TimeHelpers.h new file mode 100644 index 0000000..2f186ff --- /dev/null +++ b/UnitTest++/TimeHelpers.h @@ -0,0 +1,7 @@ +#include "Config.h" + +#if defined UNITTEST_POSIX + #include "Posix/TimeHelpers.h" +#else + #include "Win32/TimeHelpers.h" +#endif diff --git a/UnitTest++/UnitTest++.h b/UnitTest++/UnitTest++.h new file mode 100644 index 0000000..1a9fe86 --- /dev/null +++ b/UnitTest++/UnitTest++.h @@ -0,0 +1 @@ +#include "UnitTestPP.h" \ No newline at end of file diff --git a/UnitTest++/UnitTestPP.h b/UnitTest++/UnitTestPP.h new file mode 100644 index 0000000..3e02d31 --- /dev/null +++ b/UnitTest++/UnitTestPP.h @@ -0,0 +1,12 @@ +#ifndef UNITTESTPP_H +#define UNITTESTPP_H + +#include "Config.h" +#include "TestMacros.h" +#include "CheckMacros.h" +#include "RequireMacros.h" +#include "TestRunner.h" +#include "TimeConstraint.h" +#include "ReportAssert.h" + +#endif diff --git a/UnitTest++/Win32/TimeHelpers.cpp b/UnitTest++/Win32/TimeHelpers.cpp new file mode 100644 index 0000000..684ffdf --- /dev/null +++ b/UnitTest++/Win32/TimeHelpers.cpp @@ -0,0 +1,49 @@ +#include "TimeHelpers.h" + +#define WIN32_LEAN_AND_MEAN +#include + +namespace UnitTest { + + Timer::Timer() + : m_threadHandle(::GetCurrentThread()) + , m_startTime(0) + { +#if defined(UNITTEST_WIN32) && (_MSC_VER == 1200) // VC6 doesn't have DWORD_PTR + typedef unsigned long DWORD_PTR; +#endif + + DWORD_PTR systemMask; + ::GetProcessAffinityMask(GetCurrentProcess(), &m_processAffinityMask, &systemMask); + ::SetThreadAffinityMask(m_threadHandle, 1); + ::QueryPerformanceFrequency(reinterpret_cast< LARGE_INTEGER* >(&m_frequency)); + ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask); + } + + void Timer::Start() + { + m_startTime = GetTime(); + } + + double Timer::GetTimeInMs() const + { + __int64 const elapsedTime = GetTime() - m_startTime; + double const seconds = double(elapsedTime) / double(m_frequency); + return seconds * 1000.0; + } + + __int64 Timer::GetTime() const + { + LARGE_INTEGER curTime; + ::SetThreadAffinityMask(m_threadHandle, 1); + ::QueryPerformanceCounter(&curTime); + ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask); + return curTime.QuadPart; + } + + void TimeHelpers::SleepMs(int ms) + { + ::Sleep(ms); + } + +} diff --git a/UnitTest++/Win32/TimeHelpers.h b/UnitTest++/Win32/TimeHelpers.h new file mode 100644 index 0000000..11d4352 --- /dev/null +++ b/UnitTest++/Win32/TimeHelpers.h @@ -0,0 +1,45 @@ +#ifndef UNITTEST_TIMEHELPERS_H +#define UNITTEST_TIMEHELPERS_H + +#include "../Config.h" +#include "../HelperMacros.h" + +#ifdef UNITTEST_MINGW +#ifndef __int64 +#define __int64 long long +#endif +#endif + +namespace UnitTest { + + class UNITTEST_LINKAGE Timer + { + public: + Timer(); + void Start(); + double GetTimeInMs() const; + + private: + __int64 GetTime() const; + + void* m_threadHandle; + +#if defined(_WIN64) + unsigned __int64 m_processAffinityMask; +#else + unsigned long m_processAffinityMask; +#endif + + __int64 m_startTime; + __int64 m_frequency; + }; + + + namespace TimeHelpers + { + UNITTEST_LINKAGE void SleepMs(int ms); + } + +} + +#endif diff --git a/UnitTest++/XmlTestReporter.cpp b/UnitTest++/XmlTestReporter.cpp new file mode 100644 index 0000000..d44de05 --- /dev/null +++ b/UnitTest++/XmlTestReporter.cpp @@ -0,0 +1,130 @@ +#include "Config.h" +#ifndef UNITTEST_NO_DEFERRED_REPORTER + +#include "XmlTestReporter.h" + +#include +#include +#include + +using std::string; +using std::ostringstream; +using std::ostream; + +namespace { + + void ReplaceChar(string& str, char c, string const& replacement) + { + for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1)) + str.replace(pos, 1, replacement); + } + + string XmlEscape(string const& value) + { + string escaped = value; + + ReplaceChar(escaped, '&', "&"); + ReplaceChar(escaped, '<', "<"); + ReplaceChar(escaped, '>', ">"); + ReplaceChar(escaped, '\'', "'"); + ReplaceChar(escaped, '\"', """); + + return escaped; + } + + string BuildFailureMessage(string const& file, int line, string const& message) + { + ostringstream failureMessage; + failureMessage << file << "(" << line << ") : " << message; + return failureMessage.str(); + } + +} + +namespace UnitTest { + + XmlTestReporter::XmlTestReporter(ostream& ostream) + : m_ostream(ostream) + {} + + void XmlTestReporter::ReportSummary(int totalTestCount, int failedTestCount, + int failureCount, float secondsElapsed) + { + AddXmlElement(m_ostream, NULL); + + BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed); + + DeferredTestResultList const& results = GetResults(); + for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i) + { + BeginTest(m_ostream, *i); + + if (i->failed) + AddFailure(m_ostream, *i); + + EndTest(m_ostream, *i); + } + + EndResults(m_ostream); + } + + void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding) + { + os << ""; + } + + void XmlTestReporter::BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, + int failureCount, float secondsElapsed) + { + os << ""; + } + + void XmlTestReporter::EndResults(std::ostream& os) + { + os << ""; + } + + void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result) + { + os << ""; + else + os << "/>"; + } + + void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result) + { + os << ">"; // close element + + for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin(); + it != result.failures.end(); + ++it) + { + string const escapedMessage = XmlEscape(std::string(it->failureStr)); + string const message = BuildFailureMessage(result.failureFile, it->lineNumber, escapedMessage); + + os << ""; + } + } + +} + +#endif diff --git a/UnitTest++/XmlTestReporter.h b/UnitTest++/XmlTestReporter.h new file mode 100644 index 0000000..9466903 --- /dev/null +++ b/UnitTest++/XmlTestReporter.h @@ -0,0 +1,38 @@ +#ifndef UNITTEST_XMLTESTREPORTER_H +#define UNITTEST_XMLTESTREPORTER_H + +#include "Config.h" +#ifndef UNITTEST_NO_DEFERRED_REPORTER + +#include "DeferredTestReporter.h" + +#include + +namespace UnitTest +{ + + class UNITTEST_LINKAGE XmlTestReporter : public DeferredTestReporter + { + public: + explicit XmlTestReporter(std::ostream& ostream); + + virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); + + private: + XmlTestReporter(XmlTestReporter const&); + XmlTestReporter& operator=(XmlTestReporter const&); + + void AddXmlElement(std::ostream& os, char const* encoding); + void BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); + void EndResults(std::ostream& os); + void BeginTest(std::ostream& os, DeferredTestResult const& result); + void AddFailure(std::ostream& os, DeferredTestResult const& result); + void EndTest(std::ostream& os, DeferredTestResult const& result); + + std::ostream& m_ostream; + }; + +} + +#endif +#endif diff --git a/UnitTestPP_vs6.dsp b/UnitTestPP_vs6.dsp deleted file mode 100644 index 564471b..0000000 --- a/UnitTestPP_vs6.dsp +++ /dev/null @@ -1,260 +0,0 @@ -# Microsoft Developer Studio Project File - Name="UnitTestPP_vs6" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** ҏWȂł ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=UnitTestPP_vs6 - Win32 Debug -!MESSAGE ͗LҲ̧قł͂܂B ۼުĂނ邽߂ɂ NMAKE gpĂB -!MESSAGE [Ҳ̧ق̴߰] ނgpĎsĂ -!MESSAGE -!MESSAGE NMAKE /f "UnitTestPP_vs6.mak". -!MESSAGE -!MESSAGE NMAKE ̎sɍ\wł܂ -!MESSAGE ײݏϸۂ̐ݒ`܂B: -!MESSAGE -!MESSAGE NMAKE /f "UnitTestPP_vs6.mak" CFG="UnitTestPP_vs6 - Win32 Debug" -!MESSAGE -!MESSAGE I”\ Ӱ: -!MESSAGE -!MESSAGE "UnitTestPP_vs6 - Win32 Release" ("Win32 (x86) Static Library" p) -!MESSAGE "UnitTestPP_vs6 - Win32 Debug" ("Win32 (x86) Static Library" p) -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "UnitTestPP_vs6 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD BASE RSC /l 0x411 /d "NDEBUG" -# ADD RSC /l 0x411 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ELSEIF "$(CFG)" == "UnitTestPP_vs6 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD BASE RSC /l 0x411 /d "_DEBUG" -# ADD RSC /l 0x411 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ENDIF - -# Begin Target - -# Name "UnitTestPP_vs6 - Win32 Release" -# Name "UnitTestPP_vs6 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\src\AssertException.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\Checks.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\CurrentTest.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\DeferredTestReporter.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\DeferredTestResult.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\MemoryOutStream.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\ReportAssert.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\Test.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\TestDetails.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\TestList.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\TestReporter.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\TestReporterStdout.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\TestResults.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\TestRunner.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\TimeConstraint.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\XmlTestReporter.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\src\AssertException.h -# End Source File -# Begin Source File - -SOURCE=.\src\CheckMacros.h -# End Source File -# Begin Source File - -SOURCE=.\src\Checks.h -# End Source File -# Begin Source File - -SOURCE=.\src\Config.h -# End Source File -# Begin Source File - -SOURCE=.\src\CurrentTest.h -# End Source File -# Begin Source File - -SOURCE=.\src\DeferredTestReporter.h -# End Source File -# Begin Source File - -SOURCE=.\src\DeferredTestResult.h -# End Source File -# Begin Source File - -SOURCE=.\src\ExecuteTest.h -# End Source File -# Begin Source File - -SOURCE=.\src\MemoryOutStream.h -# End Source File -# Begin Source File - -SOURCE=.\src\ReportAssert.h -# End Source File -# Begin Source File - -SOURCE=.\src\Test.h -# End Source File -# Begin Source File - -SOURCE=.\src\TestDetails.h -# End Source File -# Begin Source File - -SOURCE=.\src\TestList.h -# End Source File -# Begin Source File - -SOURCE=.\src\TestMacros.h -# End Source File -# Begin Source File - -SOURCE=.\src\TestReporter.h -# End Source File -# Begin Source File - -SOURCE=.\src\TestReporterStdout.h -# End Source File -# Begin Source File - -SOURCE=.\src\TestResults.h -# End Source File -# Begin Source File - -SOURCE=.\src\TestRunner.h -# End Source File -# Begin Source File - -SOURCE=.\src\TestSuite.h -# End Source File -# Begin Source File - -SOURCE=.\src\TimeConstraint.h -# End Source File -# Begin Source File - -SOURCE=.\src\TimeHelpers.h -# End Source File -# Begin Source File - -SOURCE=".\src\unittestpp.h" -# End Source File -# Begin Source File - -SOURCE=.\src\XmlTestReporter.h -# End Source File -# End Group -# Begin Group "Win32" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\src\Win32\TimeHelpers.cpp -# End Source File -# Begin Source File - -SOURCE=.\src\Win32\TimeHelpers.h -# End Source File -# End Group -# End Target -# End Project diff --git a/UnitTestPP_vs6.dsw b/UnitTestPP_vs6.dsw deleted file mode 100644 index 58e105a..0000000 --- a/UnitTestPP_vs6.dsw +++ /dev/null @@ -1,44 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# x: ܰ߰ ̧ ҏW܂͍폜Ȃł! - -############################################################################### - -Project: "TestUnitTestPP_vs6"=".\TestUnitTestPP_vs6.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name UnitTestPP_vs6 - End Project Dependency -}}} - -############################################################################### - -Project: "UnitTestPP_vs6"=".\UnitTestPP_vs6.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..3a4637d --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,30 @@ +version: 2.1.0.{build} + +os: + - Windows Server 2012 R2 + +environment: + matrix: + + - CMAKE_GENERATOR: Visual Studio 9 2008 + - CMAKE_GENERATOR: Visual Studio 10 2010 + - CMAKE_GENERATOR: Visual Studio 11 2012 + - CMAKE_GENERATOR: Visual Studio 12 2013 + - CMAKE_GENERATOR: Visual Studio 14 2015 + +before_build: + # Generate solution files using cmake, in 'builds' directory. + # No need to create it because it's part of the repo. + - pushd builds && cmake -G "%CMAKE_GENERATOR%" ..\ && popd + +configuration: + - Debug + - Release + +build_script: + - pushd builds && cmake --build . && popd + +matrix: + fast_finish: true + + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..347366d --- /dev/null +++ b/autogen.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test -e ./.autotools_aux || mkdir .autotools_aux + +libtoolize -cq +aclocal -I m4 --install # Generate aclocal +autoconf # Generate configure script +autoheader # Generate config.h +automake --add-missing --copy # Generate Makefile.in and other scripts diff --git a/builds/.gitignore b/builds/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/builds/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/cmake/UnitTest++Config.cmake b/cmake/UnitTest++Config.cmake new file mode 100644 index 0000000..afe165c --- /dev/null +++ b/cmake/UnitTest++Config.cmake @@ -0,0 +1,2 @@ +include("${CMAKE_CURRENT_LIST_DIR}/UnitTest++Targets.cmake") +get_filename_component(UTPP_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../../include/" ABSOLUTE) diff --git a/config.h b/config.h deleted file mode 100644 index bb95a45..0000000 --- a/config.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef UNITTEST_CONFIG_H -#define UNITTEST_CONFIG_H - -// Standard defines documented here: http://predef.sourceforge.net - -#if defined(_MSC_VER) - #pragma warning(disable:4702) // unreachable code - #pragma warning(disable:4722) // destructor never returns, potential memory leak - - #if (_MSC_VER == 1200) // VC6 - #pragma warning(disable:4786) - #pragma warning(disable:4290) - #endif - - #ifdef _USRDLL - #define UNITTEST_WIN32_DLL - #endif - #define UNITTEST_WIN32 -#endif - -#if defined(unix) || defined(__unix__) || defined(__unix) || defined(linux) || \ - defined(__APPLE__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) - #define UNITTEST_POSIX -#endif - -#if defined(__MINGW32__) - #define UNITTEST_MINGW -#endif - - -// MemoryOutStream is a custom reimplementation of parts of std::ostringstream. -// Uncomment this line to have MemoryOutStream implemented in terms of std::ostringstream. -// This is useful if you are using the CHECK macros on objects that have something like this defined: -// std::ostringstream& operator<<(std::ostringstream& s, const YourObject& value) - -//#define UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - - -// DeferredTestReporter uses the STL to collect test results for subsequent export by reporters like -// XmlTestReporter. If you don't want to use this functionality, uncomment this line and no STL -// headers or code will be compiled into UnitTest++ - -//#define UNITTEST_NO_DEFERRED_REPORTER - - -// By default, asserts that you report via UnitTest::ReportAssert() abort the current test and -// continue to the next one by throwing an exception, which unwinds the stack naturally, destroying -// all auto variables on its way back down. If you don't want to (or can't) use exceptions for your -// platform/compiler, uncomment this line. All exception code will be removed from UnitTest++, -// assert recovery will be done via setjmp/longjmp, and NO correct stack unwinding will happen! - -//#define UNITTEST_NO_EXCEPTIONS - -#endif diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..372f576 --- /dev/null +++ b/configure.ac @@ -0,0 +1,48 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.69]) +AC_INIT([UnitTest++], + m4_esyscmd_s([git describe --tags | cut -c2-]), + [pjohnmeyer@gmail.com], + [unittest-cpp]) + +AC_CONFIG_SRCDIR([UnitTest++/TestDetails.cpp]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_FILES([UnitTest++.pc]) + +AM_INIT_AUTOMAKE([foreign subdir-objects]) +AM_SILENT_RULES([yes]) + +AC_CANONICAL_HOST + +dnl Detect Windows, as it doesn't implement UNIX signals and requires special code +AM_CONDITIONAL([WINDOWS], + [test "${host//mingw/}" != "${host}" -o "${host//msvc/}" != "${host}"]) + +LT_INIT() + +AC_SUBST([LIBUNITTEST_SO_VERSION], [2:1:0]) + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC + +AX_CXX_COMPILE_STDCXX_11(noext, optional) + +# Checks for libraries. + +# Checks for header files. +AC_CHECK_HEADERS([sys/time.h unistd.h setjmp.h signal.h cassert cstddef cstdio cstring exception iosfwd iostream sstream string vector]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_CHECK_HEADER_STDBOOL +AC_C_INLINE +AC_TYPE_SIZE_T + +# Checks for library functions. +AC_CHECK_FUNCS([gettimeofday strstr]) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/docs b/docs new file mode 160000 index 0000000..a6963b7 --- /dev/null +++ b/docs @@ -0,0 +1 @@ +Subproject commit a6963b798400df760e148a6e15e9c13db965a3ec diff --git a/docs/UnitTest++.html b/docs/UnitTest++.html deleted file mode 100644 index 1cb2ff9..0000000 --- a/docs/UnitTest++.html +++ /dev/null @@ -1,260 +0,0 @@ - - - UnitTest++ in brief - - -

UnitTest++ in brief

-

Introduction

-

This little document serves as bare-bones documentation for UnitTest++.

- -

For background, goals and license details, see:

- - - -

The documentation, while sparse, aims to be practical, so it should give you enough info to get started using UnitTest++ as fast as possible.

- -

Building UnitTest++

-

Building UnitTest++ will be specific to each platform and build environment, but it should be straightforward.

- -

Building with Visual Studio

-

If you are using Visual Studio, go for either of the provided .sln files, depending on version. There are no prefabricated solutions for versions earlier than VS.NET 2003, but we have had reports of people building UnitTest++ with at least VS.NET 2002.

- -

Building with Make

-

The bundled makefile is written to build with g++. It also needs sed installed in the path, and to be able to use the mv and rm shell commands. The makefile should be usable on most Posix-like platforms.

- -

Do "make all" to generate a library and test executable. A final build step runs all unit tests to make sure that the result works as expected.

- -

Packaging

-

You'll probably want to keep the generated library in a shared space in source control, so you can reuse it for multiple test projects. A redistributable package of UnitTest++ would consist of the generated library file, and all of the header files in UnitTest++/src/ and its per-platform subfolders. The tests directory only contains the unit tests for the library, and need not be included.

- -

Using UnitTest++

-

The source code for UnitTest++ comes with a full test suite written using UnitTest++. This is a great place to learn techniques for testing. There is one sample .cpp file: UnitTest++/src/tests/TestUnitTestPP.cpp. It covers most of UnitTest++'s features in an easy-to-grasp context, so start there if you want a quick overview of typical usage.

- -

Getting started

-

Listed below is a minimal C++ program to run a failing test through UnitTest++.

- -
-  // test.cpp
-  #include <unittestpp.h>
-
-  TEST(FailSpectacularly)
-  {
-    CHECK(false);
-  }
-
-  int main()
-  {
-    return UnitTest::RunAllTests();
-  }
-
- -

unittestpp.h is a facade header for UnitTest++, so including that should get you all features of the library. All classes and free functions are placed in namespace UnitTest, so you need to either qualify their full names (as with RunAllTests() in the example) or add a using namespace UnitTest; statement in your .cpp files. Note that any mention of UnitTest++ functions and classes in this document assume that the UnitTest namespace has been opened.

- -

Compiling and linking this program with UnitTest++'s static library into an executable, and running it, will produce the following output (details may vary):

- -
-  .\test.cpp(5): error: Failure in FailSpectacularly: false
-  FAILED: 1 out of 1 tests failed (1 failures).
-  Test time: 0.00 seconds.
-
- -

UnitTest++ attempts to report every failure in an IDE-friendly format, depending on platform (e.g. you can double-click it in Visual Studio's error list.) The exit code will be the number of failed tests, so that a failed test run always returns a non-zero exit code.

- -

Test macros

-

To add a test, simply put the following code in a .cpp file of your choice:

- -
-  TEST(YourTestName)
-  {
-  }
-
- -

The TEST macro contains enough machinery to turn this slightly odd-looking syntax into legal C++, and automatically register the test in a global list. This test list forms the basis of what is executed by RunAllTests().

- -

If you want to re-use a set of test data for more than one test, or provide setup/teardown for tests, you can use the TEST_FIXTURE macro instead. The macro requires that you pass it a class name that it will instantiate, so any setup and teardown code should be in its constructor and destructor.

- -
-  struct SomeFixture
-  {
-    SomeFixture() { /* some setup */ }
-    ~SomeFixture() { /* some teardown */ }
-
-    int testData;
-  };
- 
-  TEST_FIXTURE(SomeFixture, YourTestName)
-  {
-    int temp = testData;
-  }
-
- -

Note how members of the fixture are used as if they are a part of the test, since the macro-generated test class derives from the provided fixture class.

- -

Suite macros

-

Tests can be grouped into suites, using the SUITE macro. A suite serves as a namespace for test names, so that the same test name can be used in two difference contexts.

- -
-  SUITE(YourSuiteName)
-  {
-    TEST(YourTestName)
-    {
-    }
-
-    TEST(YourOtherTestName)
-    {
-    }
-  }
-
- -

This will place the tests into a C++ namespace called YourSuiteName, and make the suite name available to UnitTest++. RunAllTests() can be called for a specific suite name, so you can use this to build named groups of tests to be run together.

- -

Simple check macros

-

In test cases, we want to check the results of our system under test. UnitTest++ provides a number of check macros that handle comparison and proper failure reporting.

- -

The most basic variety is the boolean CHECK macro:

- -
-  CHECK(false); // fails
-
- -

It will fail if the boolean expression evaluates to false.

- -

For equality checks, it's generally better to use CHECK_EQUAL:

- -
-  CHECK_EQUAL(10, 20); // fails
-  CHECK_EQUAL("foo", "bar"); // fails
-
- -

Note how CHECK_EQUAL is overloaded for C strings, so you don't have to resort to strcmp or similar. There is no facility for case-insensitive comparison or string searches, so you may have to drop down to a plain boolean CHECK with help from the CRT:

- -
-  CHECK(std::strstr("zaza", "az") != 0); // succeeds
-
- -

For floating-point comparison, equality isn't necessarily well-defined, so you should prefer the CHECK_CLOSE macro:

- -
-  CHECK_CLOSE(3.14, 3.1415, 0.01); // succeeds
-
- -

All of the macros are tailored to avoid unintended side-effects, for example:

- -
-  TEST(CheckMacrosHaveNoSideEffects)
-  {
-    int i = 4;
-    CHECK_EQUAL(5, ++i); // succeeds
-    CHECK_EQUAL(5, i); // succeeds
-  }
-
- -

The check macros guarantee that the ++i expression isn't repeated internally, as demonstrated above.

- -

Array check macros

-

There is a set of check macros for array comparison as well:

- -
-  const float oned[2] = { 10, 20 };
-  CHECK_ARRAY_EQUAL(oned, oned, 2); // succeeds
-  CHECK_ARRAY_CLOSE(oned, oned, 2, 0.00); // succeeds
-
-  const float twod[2][3] = { {0, 1, 2}, {2, 3, 4} };
-  CHECK_ARRAY2D_CLOSE(twod, twod, 2, 3, 0.00); // succeeds
-
- -

The array equal macro compares elements using operator==, so CHECK_ARRAY_EQUAL won't work for an array of C strings, for example.

- -

The array close macros are similar to the regular CHECK_CLOSE macro, and are really only useful for scalar types, that can be compared in terms of a difference between two array elements.

- -

Note that the one-dimensional array macros work for std::vector as well, as it can be indexed just as a C array.

- -

Exception check macros

-

Finally, there's a CHECK_THROW macro, which asserts that its enclosed expression throws the specified type:

- -
-  struct TestException {};
-  CHECK_THROW(throw TestException(), TestException); // succeeds
-
- -

UnitTest++ natively catches exceptions if your test code doesn't. So if your code under test throws any exception UnitTest++ will fail the test and report either using the what() method for std::exception derivatives or just a plain message for unknown exception types.

- -

Should your test or code raise an irrecoverable error (an Access Violation on Win32, for example, or a signal on Linux), UnitTest++ will attempt to map them to an exception and fail the test, just as for other unhandled exceptions.

- -

Time constraints

-

UnitTest++ can fail a test if it takes too long to complete, using so-called time constraints.

- -

They come in two flavors; local and global time constraints.

- -

Local time constraints are limited to the current scope, like so:

- -
-  TEST(YourTimedTest)
-  {
-     // Lengthy setup...
-
-     {
-        UNITTEST_TIME_CONSTRAINT(50);
-
-        // Do time-critical stuff
-     }
-
-     // Lengthy teardown...
-  }
-
- -

The test will fail if the "Do time-critical stuff" block takes longer than 50 ms to complete. The time-consuming setup and teardown are not measured, since the time constraint is scope-bound. It's perfectly valid to have multiple local time constraints in the same test, as long as there is only one per block.

- -

A global time constraint, on the other hand, requires that all of the tests in a test run are faster than a specified amount of time. This allows you, when you run a suite of tests, to ask UnitTest++ to fail it entirely if any test exceeds the global constraint. The max time is passed as a parameter to an overload of RunAllTests().

- -

If you want to use a global time constraint, but have one test that is notoriously slow, you can exempt it from inspection by using the UNITTEST_TIME_CONSTRAINT_EXEMPT macro anywhere inside the test body.

- -
-  TEST(NotoriouslySlowTest)
-  {
-     UNITTEST_TIME_CONSTRAINT_EXEMPT();
-
-     // Oh boy, this is going to take a while
-     ...
-  }
-
- -

Test runners

-

The RunAllTests() function has an overload that lets you customize the behavior of the runner, such as global time constraints, custom reporters, which suite to run, etc.

- -
-  int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs);
-
- -

If you attempt to pass custom parameters to RunAllTests(), note that the list parameter should have the value Test::GetTestList().

- -

The parameterless RunAllTests() is a simple wrapper for this one, with sensible defaults.

- -

Example setup

-

How to create a new test project varies depending on your environment, but here are some directions on common file structure and usage.

- -

The general idea is that you keep one Main.cpp file with the entry-point which calls RunAllTests().

- -

Then you can simply compile and link new .cpp files at will, typically one per test suite.

- -
-   + ShaverTests/
-   |
-   +- Main.cpp
-   |
-   +- TestBrush.cpp   
-   +- TestEngine.cpp
-   +- TestRazor.cpp   
-
- -

Each of the Test*.cpp files will contain one or more TEST macro incantations with the associated test code. There are no source-level dependencies between Main.cpp and Test*.cpp, as the TEST macro handles the registration and setup necessary for RunAllTests() to find all tests compiled into the same final executable.

- -

UnitTest++ does not require this structure, even if this is how the library itself does it. As long as your test project contains one or more TESTs and calls RunAllTests() at one point or another, it will be handled by UnitTest++.

- -

It's common to make the generated executable start as a post-build step, so that merely building your test project will run the tests as well. Since the exit code is the count of failures, a failed test will generally break the build, as most build engines will fail a build if any step returns a non-zero exit code.

- - - \ No newline at end of file diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 0000000..66d41f5 --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,558 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXXFLAGS to +# enable support. VERSION may be '11' (for the C++11 standard) or '14' +# (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 1 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [], + [$1], [14], [], + [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++$1 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + else + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + + AC_SUBST(HAVE_CXX$1) + fi +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) \ No newline at end of file diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4 new file mode 100644 index 0000000..09db383 --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx_11.m4 @@ -0,0 +1,39 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++11 +# standard; if necessary, add switches to CXXFLAGS to enable support. +# +# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX +# macro with the version set to C++11. The two optional arguments are +# forwarded literally as the second and third argument respectively. +# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for +# more information. If you want to use this macro, you also need to +# download the ax_cxx_compile_stdcxx.m4 file. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 14 + +include([ax_cxx_compile_stdcxx.m4]) + +AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])]) diff --git a/src/AssertException.cpp b/src/AssertException.cpp deleted file mode 100644 index 634eb07..0000000 --- a/src/AssertException.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssertException.h" - -#ifndef UNITTEST_NO_EXCEPTIONS - -namespace UnitTest { - -AssertException::AssertException() -{ -} - -AssertException::~AssertException() throw() -{ -} - -} - -#endif diff --git a/src/CheckMacros.h b/src/CheckMacros.h deleted file mode 100644 index 1e73699..0000000 --- a/src/CheckMacros.h +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef UNITTEST_CHECKMACROS_H -#define UNITTEST_CHECKMACROS_H - -#include "HelperMacros.h" -#include "ExceptionMacros.h" -#include "Checks.h" -#include "AssertException.h" -#include "MemoryOutStream.h" -#include "TestDetails.h" -#include "CurrentTest.h" -#include "ReportAssertImpl.h" - -#ifdef CHECK - #error UnitTest++ redefines CHECK -#endif - -#ifdef CHECK_EQUAL - #error UnitTest++ redefines CHECK_EQUAL -#endif - -#ifdef CHECK_CLOSE - #error UnitTest++ redefines CHECK_CLOSE -#endif - -#ifdef CHECK_ARRAY_EQUAL - #error UnitTest++ redefines CHECK_ARRAY_EQUAL -#endif - -#ifdef CHECK_ARRAY_CLOSE - #error UnitTest++ redefines CHECK_ARRAY_CLOSE -#endif - -#ifdef CHECK_ARRAY2D_CLOSE - #error UnitTest++ redefines CHECK_ARRAY2D_CLOSE -#endif - -#define CHECK(value) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UT_TRY \ - ({ \ - if (!UnitTest::Check(value)) \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \ - }) \ - UT_CATCH_ALL \ - ({ \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Unhandled exception in CHECK(" #value ")"); \ - }) \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_EQUAL(expected, actual) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UT_TRY \ - ({ \ - UnitTest::CheckEqual(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - }) \ - UT_CATCH_ALL \ - ({ \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \ - }) \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_CLOSE(expected, actual, tolerance) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UT_TRY \ - ({ \ - UnitTest::CheckClose(*UnitTest::CurrentTest::Results(), expected, actual, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - }) \ - UT_CATCH_ALL \ - ({ \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \ - }) \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_ARRAY_EQUAL(expected, actual, count) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UT_TRY \ - ({ \ - UnitTest::CheckArrayEqual(*UnitTest::CurrentTest::Results(), expected, actual, count, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - }) \ - UT_CATCH_ALL \ - ({ \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \ - }) \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UT_TRY \ - ({ \ - UnitTest::CheckArrayClose(*UnitTest::CurrentTest::Results(), expected, actual, count, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - }) \ - UT_CATCH_ALL \ - ({ \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \ - }) \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UT_TRY \ - ({ \ - UnitTest::CheckArray2DClose(*UnitTest::CurrentTest::Results(), expected, actual, rows, columns, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - }) \ - UT_CATCH_ALL \ - ({ \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \ - }) \ - UNITTEST_MULTILINE_MACRO_END - - -// CHECK_THROW and CHECK_ASSERT only exist when UNITTEST_NO_EXCEPTIONS isn't defined (see config.h) -#ifndef UNITTEST_NO_EXCEPTIONS -#define CHECK_THROW(expression, ExpectedExceptionType) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - bool caught_ = false; \ - try { expression; } \ - catch (ExpectedExceptionType const&) { caught_ = true; } \ - catch (...) {} \ - if (!caught_) \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \ - UNITTEST_MULTILINE_MACRO_END - - -#define CHECK_ASSERT(expression) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UnitTest::Detail::ExpectAssert(true); \ - CHECK_THROW(expression, UnitTest::AssertException); \ - UnitTest::Detail::ExpectAssert(false); \ - UNITTEST_MULTILINE_MACRO_END -#endif -#endif diff --git a/src/Checks.cpp b/src/Checks.cpp deleted file mode 100644 index 0ccd698..0000000 --- a/src/Checks.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "Checks.h" -#include - -namespace UnitTest { - -namespace { - -void CheckStringsEqual(TestResults& results, char const* expected, char const* actual, - TestDetails const& details) -{ - using namespace std; - - if (strcmp(expected, actual)) - { - UnitTest::MemoryOutStream stream; - stream << "Expected " << expected << " but was " << actual; - - results.OnTestFailure(details, stream.GetText()); - } -} - -} - - -void CheckEqual(TestResults& results, char const* expected, char const* actual, - TestDetails const& details) -{ - CheckStringsEqual(results, expected, actual, details); -} - -void CheckEqual(TestResults& results, char* expected, char* actual, - TestDetails const& details) -{ - CheckStringsEqual(results, expected, actual, details); -} - -void CheckEqual(TestResults& results, char* expected, char const* actual, - TestDetails const& details) -{ - CheckStringsEqual(results, expected, actual, details); -} - -void CheckEqual(TestResults& results, char const* expected, char* actual, - TestDetails const& details) -{ - CheckStringsEqual(results, expected, actual, details); -} - - -} diff --git a/src/Checks.h b/src/Checks.h deleted file mode 100644 index c323244..0000000 --- a/src/Checks.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef UNITTEST_CHECKS_H -#define UNITTEST_CHECKS_H - -#include "../config.h" -#include "TestResults.h" -#include "MemoryOutStream.h" - -namespace UnitTest { - - -template< typename Value > -bool Check(Value const value) -{ - return !!value; // doing double negative to avoid silly VS warnings -} - - -template< typename Expected, typename Actual > -void CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) -{ - if (!(expected == actual)) - { - UnitTest::MemoryOutStream stream; - stream << "Expected " << expected << " but was " << actual; - - results.OnTestFailure(details, stream.GetText()); - } -} - -UNITTEST_LINKAGE void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details); - -UNITTEST_LINKAGE void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details); - -UNITTEST_LINKAGE void CheckEqual(TestResults& results, char* expected, char const* actual, TestDetails const& details); - -UNITTEST_LINKAGE void CheckEqual(TestResults& results, char const* expected, char* actual, TestDetails const& details); - -template< typename Expected, typename Actual, typename Tolerance > -bool AreClose(Expected const& expected, Actual const& actual, Tolerance const& tolerance) -{ - return (actual >= (expected - tolerance)) && (actual <= (expected + tolerance)); -} - -template< typename Expected, typename Actual, typename Tolerance > -void CheckClose(TestResults& results, Expected const& expected, Actual const& actual, Tolerance const& tolerance, - TestDetails const& details) -{ - if (!AreClose(expected, actual, tolerance)) - { - UnitTest::MemoryOutStream stream; - stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual; - - results.OnTestFailure(details, stream.GetText()); - } -} - - -template< typename Expected, typename Actual > -void CheckArrayEqual(TestResults& results, Expected const& expected, Actual const& actual, - int const count, TestDetails const& details) -{ - bool equal = true; - for (int i = 0; i < count; ++i) - equal &= (expected[i] == actual[i]); - - if (!equal) - { - UnitTest::MemoryOutStream stream; - - stream << "Expected [ "; - - for (int expectedIndex = 0; expectedIndex < count; ++expectedIndex) - stream << expected[expectedIndex] << " "; - - stream << "] but was [ "; - - for (int actualIndex = 0; actualIndex < count; ++actualIndex) - stream << actual[actualIndex] << " "; - - stream << "]"; - - results.OnTestFailure(details, stream.GetText()); - } -} - -template< typename Expected, typename Actual, typename Tolerance > -bool ArrayAreClose(Expected const& expected, Actual const& actual, int const count, Tolerance const& tolerance) -{ - bool equal = true; - for (int i = 0; i < count; ++i) - equal &= AreClose(expected[i], actual[i], tolerance); - return equal; -} - -template< typename Expected, typename Actual, typename Tolerance > -void CheckArrayClose(TestResults& results, Expected const& expected, Actual const& actual, - int const count, Tolerance const& tolerance, TestDetails const& details) -{ - bool equal = ArrayAreClose(expected, actual, count, tolerance); - - if (!equal) - { - UnitTest::MemoryOutStream stream; - - stream << "Expected [ "; - for (int expectedIndex = 0; expectedIndex < count; ++expectedIndex) - stream << expected[expectedIndex] << " "; - stream << "] +/- " << tolerance << " but was [ "; - - for (int actualIndex = 0; actualIndex < count; ++actualIndex) - stream << actual[actualIndex] << " "; - stream << "]"; - - results.OnTestFailure(details, stream.GetText()); - } -} - -template< typename Expected, typename Actual, typename Tolerance > -void CheckArray2DClose(TestResults& results, Expected const& expected, Actual const& actual, - int const rows, int const columns, Tolerance const& tolerance, TestDetails const& details) -{ - bool equal = true; - for (int i = 0; i < rows; ++i) - equal &= ArrayAreClose(expected[i], actual[i], columns, tolerance); - - if (!equal) - { - UnitTest::MemoryOutStream stream; - - stream << "Expected [ "; - - for (int expectedRow = 0; expectedRow < rows; ++expectedRow) - { - stream << "[ "; - for (int expectedColumn = 0; expectedColumn < columns; ++expectedColumn) - stream << expected[expectedRow][expectedColumn] << " "; - stream << "] "; - } - - stream << "] +/- " << tolerance << " but was [ "; - - for (int actualRow = 0; actualRow < rows; ++actualRow) - { - stream << "[ "; - for (int actualColumn = 0; actualColumn < columns; ++actualColumn) - stream << actual[actualRow][actualColumn] << " "; - stream << "] "; - } - - stream << "]"; - - results.OnTestFailure(details, stream.GetText()); - } -} - -} - -#endif diff --git a/src/CompositeTestReporter.cpp b/src/CompositeTestReporter.cpp deleted file mode 100644 index 2a3d22e..0000000 --- a/src/CompositeTestReporter.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "CompositeTestReporter.h" -#include - -namespace UnitTest { - -CompositeTestReporter::CompositeTestReporter() - : m_reporterCount(0) -{ -} - -int CompositeTestReporter::GetReporterCount() const -{ - return m_reporterCount; -} - -bool CompositeTestReporter::AddReporter(TestReporter* reporter) -{ - if (m_reporterCount == kMaxReporters) - return false; - - m_reporters[m_reporterCount++] = reporter; - return true; -} - -bool CompositeTestReporter::RemoveReporter(TestReporter* reporter) -{ - for (int index = 0; index < m_reporterCount; ++index) - { - if (m_reporters[index] == reporter) - { - m_reporters[index] = m_reporters[m_reporterCount - 1]; - --m_reporterCount; - return true; - } - } - - return false; -} - -void CompositeTestReporter::ReportFailure(TestDetails const& details, char const* failure) -{ - for (int index = 0; index < m_reporterCount; ++index) - m_reporters[index]->ReportFailure(details, failure); -} - -void CompositeTestReporter::ReportTestStart(TestDetails const& test) -{ - for (int index = 0; index < m_reporterCount; ++index) - m_reporters[index]->ReportTestStart(test); -} - -void CompositeTestReporter::ReportTestFinish(TestDetails const& test, float secondsElapsed) -{ - for (int index = 0; index < m_reporterCount; ++index) - m_reporters[index]->ReportTestFinish(test, secondsElapsed); -} - -void CompositeTestReporter::ReportSummary(int totalTestCount, - int failedTestCount, - int failureCount, - float secondsElapsed) -{ - for (int index = 0; index < m_reporterCount; ++index) - m_reporters[index]->ReportSummary(totalTestCount, failedTestCount, failureCount, secondsElapsed); -} - -} diff --git a/src/CompositeTestReporter.h b/src/CompositeTestReporter.h deleted file mode 100644 index a4806f4..0000000 --- a/src/CompositeTestReporter.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef UNITTEST_COMPOSITETESTREPORTER_H -#define UNITTEST_COMPOSITETESTREPORTER_H - -#include "TestReporter.h" - -namespace UnitTest { - -class UNITTEST_LINKAGE CompositeTestReporter : public TestReporter -{ -public: - CompositeTestReporter(); - - int GetReporterCount() const; - bool AddReporter(TestReporter* reporter); - bool RemoveReporter(TestReporter* reporter); - - virtual void ReportTestStart(TestDetails const& test); - virtual void ReportFailure(TestDetails const& test, char const* failure); - virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed); - virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); - -private: - enum { kMaxReporters = 16 }; - TestReporter* m_reporters[kMaxReporters]; - int m_reporterCount; - - // revoked - CompositeTestReporter(const CompositeTestReporter&); - CompositeTestReporter& operator =(const CompositeTestReporter&); -}; - -} - -#endif diff --git a/src/CurrentTest.cpp b/src/CurrentTest.cpp deleted file mode 100644 index 19eb9bf..0000000 --- a/src/CurrentTest.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "CurrentTest.h" -#include - -namespace UnitTest { - -UNITTEST_LINKAGE TestResults*& CurrentTest::Results() -{ - static TestResults* testResults = NULL; - return testResults; -} - -UNITTEST_LINKAGE const TestDetails*& CurrentTest::Details() -{ - static const TestDetails* testDetails = NULL; - return testDetails; -} - -} diff --git a/src/CurrentTest.h b/src/CurrentTest.h deleted file mode 100644 index 0d62fdc..0000000 --- a/src/CurrentTest.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef UNITTEST_CURRENTTESTRESULTS_H -#define UNITTEST_CURRENTTESTRESULTS_H - -#include "HelperMacros.h" - -namespace UnitTest { - -class TestResults; -class TestDetails; - -namespace CurrentTest -{ - UNITTEST_LINKAGE TestResults*& Results(); - UNITTEST_LINKAGE const TestDetails*& Details(); -} - -} - -#endif diff --git a/src/DeferredTestReporter.h b/src/DeferredTestReporter.h deleted file mode 100644 index d4947f4..0000000 --- a/src/DeferredTestReporter.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef UNITTEST_DEFERREDTESTREPORTER_H -#define UNITTEST_DEFERREDTESTREPORTER_H - -#include "../config.h" - -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "TestReporter.h" -#include "DeferredTestResult.h" - -#include - -UNITTEST_STDVECTOR_LINKAGE(UnitTest::DeferredTestResult); - -namespace UnitTest -{ - -class UNITTEST_LINKAGE DeferredTestReporter : public TestReporter -{ -public: - virtual void ReportTestStart(TestDetails const& details); - virtual void ReportFailure(TestDetails const& details, char const* failure); - virtual void ReportTestFinish(TestDetails const& details, float secondsElapsed); - - typedef std::vector< DeferredTestResult > DeferredTestResultList; - DeferredTestResultList& GetResults(); - -private: - DeferredTestResultList m_results; -}; - -} - -#endif -#endif diff --git a/src/DeferredTestResult.cpp b/src/DeferredTestResult.cpp deleted file mode 100644 index cbf0a8a..0000000 --- a/src/DeferredTestResult.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "../config.h" -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "DeferredTestResult.h" -#include - -namespace UnitTest -{ - -DeferredTestFailure::DeferredTestFailure() - : lineNumber(-1) -{ - failureStr[0] = '\0'; -} - -DeferredTestFailure::DeferredTestFailure(int lineNumber_, const char* failureStr_) - : lineNumber(lineNumber_) -{ - std::strcpy(failureStr, failureStr_); -} - -DeferredTestResult::DeferredTestResult() - : suiteName("") - , testName("") - , failureFile("") - , timeElapsed(0.0f) - , failed(false) -{ -} - -DeferredTestResult::DeferredTestResult(char const* suite, char const* test) - : suiteName(suite) - , testName(test) - , failureFile("") - , timeElapsed(0.0f) - , failed(false) -{ -} - -DeferredTestResult::~DeferredTestResult() -{ -} - -} - -#endif diff --git a/src/DeferredTestResult.h b/src/DeferredTestResult.h deleted file mode 100644 index e580d0c..0000000 --- a/src/DeferredTestResult.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef UNITTEST_DEFERREDTESTRESULT_H -#define UNITTEST_DEFERREDTESTRESULT_H - -#include "../config.h" -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "HelperMacros.h" -#include -#include - -namespace UnitTest -{ - -class UNITTEST_LINKAGE DeferredTestFailure -{ -public: - DeferredTestFailure(); - DeferredTestFailure(int lineNumber_, const char* failureStr_); - - int lineNumber; - char failureStr[1024]; -}; - -} - -UNITTEST_STDVECTOR_LINKAGE(UnitTest::DeferredTestFailure); - -namespace UnitTest -{ - -class UNITTEST_LINKAGE DeferredTestResult -{ -public: - DeferredTestResult(); - DeferredTestResult(char const* suite, char const* test); - ~DeferredTestResult(); - - std::string suiteName; - std::string testName; - std::string failureFile; - - typedef std::vector< DeferredTestFailure > FailureVec; - FailureVec failures; - - float timeElapsed; - bool failed; -}; - -} - -#endif -#endif diff --git a/src/ExceptionMacros.h b/src/ExceptionMacros.h deleted file mode 100644 index 4ddf5ec..0000000 --- a/src/ExceptionMacros.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef UNITTEST_EXCEPTIONMACROS_H -#define UNITTEST_EXCEPTIONMACROS_H - -#include "../config.h" - -#ifndef UNITTEST_NO_EXCEPTIONS - #define UT_TRY(x) try x - #define UT_THROW(x) throw x - #define UT_CATCH(ExceptionType, ExceptionName, CatchBody) catch(ExceptionType& ExceptionName) CatchBody - #define UT_CATCH_ALL(CatchBody) catch(...) CatchBody -#else - #define UT_TRY(x) x - #define UT_THROW(x) - #define UT_CATCH(ExceptionType, ExceptionName, CatchBody) - #define UT_CATCH_ALL(CatchBody) -#endif - -#endif diff --git a/src/ExecuteTest.h b/src/ExecuteTest.h deleted file mode 100644 index 2f47013..0000000 --- a/src/ExecuteTest.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef UNITTEST_EXECUTE_TEST_H -#define UNITTEST_EXECUTE_TEST_H - -#include "../config.h" -#include "ExceptionMacros.h" -#include "TestDetails.h" -#include "TestResults.h" -#include "MemoryOutStream.h" -#include "AssertException.h" -#include "CurrentTest.h" - -#ifdef UNITTEST_NO_EXCEPTIONS - #include "ReportAssertImpl.h" -#endif - -#ifdef UNITTEST_POSIX - #include "Posix/SignalTranslator.h" -#endif - -namespace UnitTest { - -template< typename T > -void ExecuteTest(T& testObject, TestDetails const& details, bool isMockTest) -{ - if (isMockTest == false) - CurrentTest::Details() = &details; - -#ifdef UNITTEST_NO_EXCEPTIONS - if (UNITTEST_SET_ASSERT_JUMP_TARGET() == 0) - { -#endif -#ifndef UNITTEST_POSIX - UT_TRY({ testObject.RunImpl(); }) -#else - UT_TRY - ({ - UNITTEST_THROW_SIGNALS_POSIX_ONLY - testObject.RunImpl(); - }) -#endif - UT_CATCH(AssertException, e, { (void)e; }) - UT_CATCH(std::exception, e, - { - MemoryOutStream stream; - stream << "Unhandled exception: " << e.what(); - CurrentTest::Results()->OnTestFailure(details, stream.GetText()); - }) - UT_CATCH_ALL - ({ - CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: test crashed"); - }) -#ifdef UNITTEST_NO_EXCEPTIONS - } -#endif -} - -} - -#endif diff --git a/src/HelperMacros.h b/src/HelperMacros.h deleted file mode 100644 index 68792da..0000000 --- a/src/HelperMacros.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef UNITTEST_HELPERMACROS_H -#define UNITTEST_HELPERMACROS_H - -#include "../config.h" - -#define UNITTEST_MULTILINE_MACRO_BEGIN do { - -#ifdef UNITTEST_WIN32 - #define UNITTEST_MULTILINE_MACRO_END \ - } __pragma(warning(push)) __pragma(warning(disable:4127)) while (0) __pragma(warning(pop)) -#else - #define UNITTEST_MULTILINE_MACRO_END } while(0) -#endif - - -#ifdef UNITTEST_WIN32_DLL - #define UNITTEST_IMPORT __declspec(dllimport) - #define UNITTEST_EXPORT __declspec(dllexport) - - #ifdef UNITTEST_DLL_EXPORT - #define UNITTEST_LINKAGE UNITTEST_EXPORT - #define UNITTEST_IMPEXP_TEMPLATE - #else - #define UNITTEST_LINKAGE UNITTEST_IMPORT - #define UNITTEST_IMPEXP_TEMPLATE extern - #endif - - #define UNITTEST_STDVECTOR_LINKAGE(T) \ - __pragma(warning(push)) \ - __pragma(warning(disable:4231)) \ - UNITTEST_IMPEXP_TEMPLATE template class UNITTEST_LINKAGE std::allocator< T >; \ - UNITTEST_IMPEXP_TEMPLATE template class UNITTEST_LINKAGE std::vector< T >; \ - __pragma(warning(pop)) -#else - #define UNITTEST_IMPORT - #define UNITTEST_EXPORT - #define UNITTEST_LINKAGE - #define UNITTEST_IMPEXP_TEMPLATE - #define UNITTEST_STDVECTOR_LINKAGE(T) -#endif - -#ifdef UNITTEST_WIN32 - #define UNITTEST_JMPBUF jmp_buf - #define UNITTEST_SETJMP setjmp - #define UNITTEST_LONGJMP longjmp -#elif defined UNITTEST_POSIX - #define UNITTEST_JMPBUF std::jmp_buf - #define UNITTEST_SETJMP setjmp - #define UNITTEST_LONGJMP std::longjmp -#endif - -#endif diff --git a/src/MemoryOutStream.cpp b/src/MemoryOutStream.cpp deleted file mode 100644 index 1e1e97d..0000000 --- a/src/MemoryOutStream.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "MemoryOutStream.h" - -#ifdef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - -namespace UnitTest { - -char const* MemoryOutStream::GetText() const -{ - m_text = this->str(); - return m_text.c_str(); -} - -void MemoryOutStream::Clear() -{ - this->str(std::string()); - m_text = this->str(); -} - -} - -#else - -#include -#include - -namespace UnitTest { - -namespace { - -template -void FormatToStream(MemoryOutStream& stream, char const* format, ValueType const& value) -{ - using namespace std; - - char txt[32]; - sprintf(txt, format, value); - stream << txt; -} - -int RoundUpToMultipleOfPow2Number (int n, int pow2Number) -{ - return (n + (pow2Number - 1)) & ~(pow2Number - 1); -} - -} - - -MemoryOutStream::MemoryOutStream(int const size) - : m_capacity (0) - , m_buffer (0) - -{ - GrowBuffer(size); -} - -MemoryOutStream::~MemoryOutStream() -{ - delete [] m_buffer; -} - -void MemoryOutStream::Clear() -{ - m_buffer[0] = '\0'; -} - -char const* MemoryOutStream::GetText() const -{ - return m_buffer; -} - -MemoryOutStream& MemoryOutStream::operator <<(char const* txt) -{ - using namespace std; - - int const bytesLeft = m_capacity - (int)strlen(m_buffer); - int const bytesRequired = (int)strlen(txt) + 1; - - if (bytesRequired > bytesLeft) - { - int const requiredCapacity = bytesRequired + m_capacity - bytesLeft; - GrowBuffer(requiredCapacity); - } - - strcat(m_buffer, txt); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator <<(int const n) -{ - FormatToStream(*this, "%i", n); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator <<(long const n) -{ - FormatToStream(*this, "%li", n); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator <<(unsigned long const n) -{ - FormatToStream(*this, "%lu", n); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator <<(long long const n) -{ -#ifdef UNITTEST_WIN32 - FormatToStream(*this, "%I64d", n); -#else - FormatToStream(*this, "%lld", n); -#endif - - return *this; -} - -MemoryOutStream& MemoryOutStream::operator <<(unsigned long long const n) -{ -#ifdef UNITTEST_WIN32 - FormatToStream(*this, "%I64u", n); -#else - FormatToStream(*this, "%llu", n); -#endif - - return *this; -} - -MemoryOutStream& MemoryOutStream::operator <<(float const f) -{ - FormatToStream(*this, "%ff", f); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator <<(void const* p) -{ - FormatToStream(*this, "%p", p); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator <<(unsigned int const s) -{ - FormatToStream(*this, "%u", s); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator <<(double const d) -{ - FormatToStream(*this, "%f", d); - return *this; -} - -int MemoryOutStream::GetCapacity() const -{ - return m_capacity; -} - - -void MemoryOutStream::GrowBuffer(int const desiredCapacity) -{ - int const newCapacity = RoundUpToMultipleOfPow2Number(desiredCapacity, GROW_CHUNK_SIZE); - - using namespace std; - - char* buffer = new char[newCapacity]; - if (m_buffer) - strcpy(buffer, m_buffer); - else - strcpy(buffer, ""); - - delete [] m_buffer; - m_buffer = buffer; - m_capacity = newCapacity; -} - -} - - -#endif diff --git a/src/MemoryOutStream.h b/src/MemoryOutStream.h deleted file mode 100644 index 380826a..0000000 --- a/src/MemoryOutStream.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef UNITTEST_MEMORYOUTSTREAM_H -#define UNITTEST_MEMORYOUTSTREAM_H - -#include "../config.h" -#include "HelperMacros.h" - -#ifdef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - -#include - -namespace UnitTest -{ - -class UNITTEST_LINKAGE MemoryOutStream : public std::ostringstream -{ -public: - MemoryOutStream() {} - ~MemoryOutStream() {} - void Clear(); - char const* GetText() const; - -private: - MemoryOutStream(MemoryOutStream const&); - void operator =(MemoryOutStream const&); - - mutable std::string m_text; -}; - -} - -#else - -#include - -namespace UnitTest -{ - -class UNITTEST_LINKAGE MemoryOutStream -{ -public: - explicit MemoryOutStream(int const size = 256); - ~MemoryOutStream(); - - void Clear(); - char const* GetText() const; - - MemoryOutStream& operator <<(char const* txt); - MemoryOutStream& operator <<(int n); - MemoryOutStream& operator <<(long n); - MemoryOutStream& operator <<(long long n); - MemoryOutStream& operator <<(unsigned long n); - MemoryOutStream& operator <<(unsigned long long n); - MemoryOutStream& operator <<(float f); - MemoryOutStream& operator <<(double d); - MemoryOutStream& operator <<(void const* p); - MemoryOutStream& operator <<(unsigned int s); - - enum { GROW_CHUNK_SIZE = 32 }; - int GetCapacity() const; - -private: - void operator= (MemoryOutStream const&); - void GrowBuffer(int capacity); - - int m_capacity; - char* m_buffer; -}; - -} - -#endif - -#endif diff --git a/src/Posix/SignalTranslator.cpp b/src/Posix/SignalTranslator.cpp deleted file mode 100644 index 014a771..0000000 --- a/src/Posix/SignalTranslator.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "SignalTranslator.h" - -namespace UnitTest { - -sigjmp_buf* SignalTranslator::s_jumpTarget = 0; - -namespace { - -void SignalHandler(int sig) -{ - siglongjmp(*SignalTranslator::s_jumpTarget, sig ); -} - -} - - -SignalTranslator::SignalTranslator() -{ - m_oldJumpTarget = s_jumpTarget; - s_jumpTarget = &m_currentJumpTarget; - - struct sigaction action; - action.sa_flags = 0; - action.sa_handler = SignalHandler; - sigemptyset( &action.sa_mask ); - - sigaction( SIGSEGV, &action, &m_old_SIGSEGV_action ); - sigaction( SIGFPE , &action, &m_old_SIGFPE_action ); - sigaction( SIGTRAP, &action, &m_old_SIGTRAP_action ); - sigaction( SIGBUS , &action, &m_old_SIGBUS_action ); - sigaction( SIGILL , &action, &m_old_SIGBUS_action ); -} - -SignalTranslator::~SignalTranslator() -{ - sigaction( SIGILL , &m_old_SIGBUS_action , 0 ); - sigaction( SIGBUS , &m_old_SIGBUS_action , 0 ); - sigaction( SIGTRAP, &m_old_SIGTRAP_action, 0 ); - sigaction( SIGFPE , &m_old_SIGFPE_action , 0 ); - sigaction( SIGSEGV, &m_old_SIGSEGV_action, 0 ); - - s_jumpTarget = m_oldJumpTarget; -} - - -} diff --git a/src/Posix/SignalTranslator.h b/src/Posix/SignalTranslator.h deleted file mode 100644 index 2152b9c..0000000 --- a/src/Posix/SignalTranslator.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef UNITTEST_SIGNALTRANSLATOR_H -#define UNITTEST_SIGNALTRANSLATOR_H - -#include -#include - -namespace UnitTest { - -class SignalTranslator -{ -public: - SignalTranslator(); - ~SignalTranslator(); - - static sigjmp_buf* s_jumpTarget; - -private: - sigjmp_buf m_currentJumpTarget; - sigjmp_buf* m_oldJumpTarget; - - struct sigaction m_old_SIGFPE_action; - struct sigaction m_old_SIGTRAP_action; - struct sigaction m_old_SIGSEGV_action; - struct sigaction m_old_SIGBUS_action; - struct sigaction m_old_SIGABRT_action; - struct sigaction m_old_SIGALRM_action; -}; - -#if !defined (__GNUC__) - #define UNITTEST_EXTENSION -#else - #define UNITTEST_EXTENSION __extension__ -#endif - -#define UNITTEST_THROW_SIGNALS_POSIX_ONLY \ - UnitTest::SignalTranslator sig; \ - if (UNITTEST_EXTENSION sigsetjmp(*UnitTest::SignalTranslator::s_jumpTarget, 1) != 0) \ - throw ("Unhandled system exception"); - -} - -#endif diff --git a/src/Posix/TimeHelpers.cpp b/src/Posix/TimeHelpers.cpp deleted file mode 100644 index 35e8136..0000000 --- a/src/Posix/TimeHelpers.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "TimeHelpers.h" -#include - -namespace UnitTest { - -Timer::Timer() -{ - m_startTime.tv_sec = 0; - m_startTime.tv_usec = 0; -} - -void Timer::Start() -{ - gettimeofday(&m_startTime, 0); -} - -double Timer::GetTimeInMs() const -{ - struct timeval currentTime; - gettimeofday(¤tTime, 0); - - double const dsecs = currentTime.tv_sec - m_startTime.tv_sec; - double const dus = currentTime.tv_usec - m_startTime.tv_usec; - - return (dsecs * 1000.0) + (dus / 1000.0); -} - -void TimeHelpers::SleepMs(int ms) -{ - usleep(ms * 1000); -} - -} diff --git a/src/Posix/TimeHelpers.h b/src/Posix/TimeHelpers.h deleted file mode 100644 index 5a5bd79..0000000 --- a/src/Posix/TimeHelpers.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef UNITTEST_TIMEHELPERS_H -#define UNITTEST_TIMEHELPERS_H - -#include - -namespace UnitTest { - -class Timer -{ -public: - Timer(); - void Start(); - double GetTimeInMs() const; - -private: - struct timeval m_startTime; -}; - - -namespace TimeHelpers -{ - void SleepMs(int ms); -} - - -} - -#endif diff --git a/src/ReportAssert.cpp b/src/ReportAssert.cpp deleted file mode 100644 index c38a518..0000000 --- a/src/ReportAssert.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "ReportAssert.h" -#include "ReportAssertImpl.h" -#include "AssertException.h" -#include "CurrentTest.h" -#include "TestResults.h" -#include "TestDetails.h" - -#ifdef UNITTEST_NO_EXCEPTIONS - #include "ReportAssertImpl.h" -#endif - -namespace UnitTest { - -namespace -{ - bool& AssertExpectedFlag() - { - static bool s_assertExpected = false; - return s_assertExpected; - } -} - -UNITTEST_LINKAGE void ReportAssert(char const* description, char const* filename, int lineNumber) -{ - Detail::ReportAssertEx(CurrentTest::Results(), CurrentTest::Details(), - description, filename, lineNumber); -} - -namespace Detail { - -#ifdef UNITTEST_NO_EXCEPTIONS -UNITTEST_JMPBUF* GetAssertJmpBuf() -{ - static UNITTEST_JMPBUF s_jmpBuf; - return &s_jmpBuf; -} -#endif - -UNITTEST_LINKAGE void ReportAssertEx(TestResults* testResults, - const TestDetails* testDetails, - char const* description, - char const* filename, - int lineNumber) -{ - if (AssertExpectedFlag() == false) - { - TestDetails assertDetails(testDetails->testName, testDetails->suiteName, filename, lineNumber); - testResults->OnTestFailure(assertDetails, description); - } - - ExpectAssert(false); - -#ifndef UNITTEST_NO_EXCEPTIONS - throw AssertException(); -#else - UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET(); -#endif -} - -UNITTEST_LINKAGE void ExpectAssert(bool expected) -{ - AssertExpectedFlag() = expected; -} - -UNITTEST_LINKAGE bool AssertExpected() -{ - return AssertExpectedFlag(); -} - -}} diff --git a/src/ReportAssertImpl.h b/src/ReportAssertImpl.h deleted file mode 100644 index aefc78d..0000000 --- a/src/ReportAssertImpl.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef UNITTEST_REPORTASSERTIMPL_H -#define UNITTEST_REPORTASSERTIMPL_H - -#include "../config.h" -#include "HelperMacros.h" - -#ifdef UNITTEST_NO_EXCEPTIONS - #include -#endif - -namespace UnitTest { - -class TestResults; -class TestDetails; - -namespace Detail { - -UNITTEST_LINKAGE void ExpectAssert(bool expected); - -UNITTEST_LINKAGE void ReportAssertEx(TestResults* testResults, - const TestDetails* testDetails, - char const* description, - char const* filename, - int lineNumber); - -UNITTEST_LINKAGE bool AssertExpected(); - -#ifdef UNITTEST_NO_EXCEPTIONS - UNITTEST_LINKAGE UNITTEST_JMPBUF* GetAssertJmpBuf(); - - #ifdef UNITTEST_WIN32 - #define UNITTEST_SET_ASSERT_JUMP_TARGET() \ - __pragma(warning(push)) __pragma(warning(disable:4611)) \ - UNITTEST_SETJMP(*UnitTest::Detail::GetAssertJmpBuf()) \ - __pragma(warning(pop)) - #else - #define UNITTEST_SET_ASSERT_JUMP_TARGET() UNITTEST_SETJMP(*UnitTest::Detail::GetAssertJmpBuf()) - #endif - - #define UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET() UNITTEST_LONGJMP(*UnitTest::Detail::GetAssertJmpBuf(), 1) -#endif - -} -} - -#endif diff --git a/src/Test.cpp b/src/Test.cpp deleted file mode 100644 index eaab9aa..0000000 --- a/src/Test.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "../config.h" -#include "Test.h" -#include "TestList.h" -#include "TestResults.h" -#include "AssertException.h" -#include "MemoryOutStream.h" -#include "ExecuteTest.h" - -#ifdef UNITTEST_POSIX - #include "Posix/SignalTranslator.h" -#endif - -namespace UnitTest { - -TestList& Test::GetTestList() -{ - static TestList s_list; - return s_list; -} - -Test::Test(char const* testName, char const* suiteName, char const* filename, int lineNumber) - : m_details(testName, suiteName, filename, lineNumber) - , m_nextTest(0) - , m_timeConstraintExempt(false) - , m_isMockTest(false) -{ -} - -Test::~Test() -{ -} - -void Test::Run() -{ - ExecuteTest(*this, m_details, m_isMockTest); -} - -void Test::RunImpl() const -{ -} - -} diff --git a/src/Test.h b/src/Test.h deleted file mode 100644 index 1e1dbb2..0000000 --- a/src/Test.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef UNITTEST_TEST_H -#define UNITTEST_TEST_H - -#include "TestDetails.h" - -namespace UnitTest { - -class TestResults; -class TestList; - -class UNITTEST_LINKAGE Test -{ -public: - explicit Test(char const* testName, char const* suiteName = "DefaultSuite", char const* filename = "", int lineNumber = 0); - virtual ~Test(); - void Run(); - - TestDetails const m_details; - Test* m_nextTest; - mutable bool m_timeConstraintExempt; - mutable bool m_isMockTest; - - static TestList& GetTestList(); - - virtual void RunImpl() const; - -private: - Test(Test const&); - Test& operator =(Test const&); -}; - - -} - -#endif diff --git a/src/TestDetails.cpp b/src/TestDetails.cpp deleted file mode 100644 index fdd7d1d..0000000 --- a/src/TestDetails.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "TestDetails.h" - -namespace UnitTest { - -TestDetails::TestDetails(char const* testName_, char const* suiteName_, char const* filename_, int lineNumber_) - : suiteName(suiteName_) - , testName(testName_) - , filename(filename_) - , lineNumber(lineNumber_) -{ -} - -TestDetails::TestDetails(const TestDetails& details, int lineNumber_) - : suiteName(details.suiteName) - , testName(details.testName) - , filename(details.filename) - , lineNumber(lineNumber_) -{ -} - - -} diff --git a/src/TestDetails.h b/src/TestDetails.h deleted file mode 100644 index 898f7f3..0000000 --- a/src/TestDetails.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef UNITTEST_TESTDETAILS_H -#define UNITTEST_TESTDETAILS_H - -#include "HelperMacros.h" - -namespace UnitTest { - -class UNITTEST_LINKAGE TestDetails -{ -public: - TestDetails(char const* testName, char const* suiteName, char const* filename, int lineNumber); - TestDetails(const TestDetails& details, int lineNumber); - - char const* const suiteName; - char const* const testName; - char const* const filename; - int const lineNumber; - - TestDetails(TestDetails const&); // Why is it public? --> http://gcc.gnu.org/bugs.html#cxx_rvalbind -private: - TestDetails& operator=(TestDetails const&); -}; - -} - -#endif diff --git a/src/TestList.cpp b/src/TestList.cpp deleted file mode 100644 index 38fbfec..0000000 --- a/src/TestList.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "TestList.h" -#include "Test.h" - -#include - -namespace UnitTest { - -TestList::TestList() - : m_head(0) - , m_tail(0) -{ -} - -void TestList::Add(Test* test) -{ - if (m_tail == 0) - { - assert(m_head == 0); - m_head = test; - m_tail = test; - } - else - { - m_tail->m_nextTest = test; - m_tail = test; - } -} - -Test* TestList::GetHead() const -{ - return m_head; -} - -ListAdder::ListAdder(TestList& list, Test* test) -{ - list.Add(test); -} - -} diff --git a/src/TestList.h b/src/TestList.h deleted file mode 100644 index ed190c2..0000000 --- a/src/TestList.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef UNITTEST_TESTLIST_H -#define UNITTEST_TESTLIST_H - -#include "HelperMacros.h" - -namespace UnitTest { - -class Test; - -class UNITTEST_LINKAGE TestList -{ -public: - TestList(); - void Add (Test* test); - - Test* GetHead() const; - -private: - Test* m_head; - Test* m_tail; -}; - - -class UNITTEST_LINKAGE ListAdder -{ -public: - ListAdder(TestList& list, Test* test); -}; - -} - - -#endif diff --git a/src/TestMacros.h b/src/TestMacros.h deleted file mode 100644 index 931d8e7..0000000 --- a/src/TestMacros.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef UNITTEST_TESTMACROS_H -#define UNITTEST_TESTMACROS_H - -#include "../config.h" -#include "TestSuite.h" -#include "ExceptionMacros.h" -#include "ExecuteTest.h" -#include "AssertException.h" -#include "TestDetails.h" -#include "MemoryOutStream.h" - -#ifndef UNITTEST_POSIX - #define UNITTEST_THROW_SIGNALS_POSIX_ONLY -#else - #include "Posix/SignalTranslator.h" -#endif - -#ifdef TEST - #error UnitTest++ redefines TEST -#endif - -#ifdef TEST_EX - #error UnitTest++ redefines TEST_EX -#endif - -#ifdef TEST_FIXTURE_EX - #error UnitTest++ redefines TEST_FIXTURE_EX -#endif - -#define SUITE(Name) \ - namespace Suite##Name { \ - namespace UnitTestSuite { \ - inline char const* GetSuiteName () { \ - return #Name ; \ - } \ - } \ - } \ - namespace Suite##Name - -#define TEST_EX(Name, List) \ - class Test##Name : public UnitTest::Test \ - { \ - public: \ - Test##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ - private: \ - virtual void RunImpl() const; \ - } test##Name##Instance; \ - \ - UnitTest::ListAdder adder##Name (List, &test##Name##Instance); \ - \ - void Test##Name::RunImpl() const - - -#define TEST(Name) TEST_EX(Name, UnitTest::Test::GetTestList()) - - -#define TEST_FIXTURE_EX(Fixture, Name, List) \ - class Fixture##Name##Helper : public Fixture \ - { \ - public: \ - explicit Fixture##Name##Helper(UnitTest::TestDetails const& details) : m_details(details) {} \ - void RunImpl(); \ - UnitTest::TestDetails const& m_details; \ - private: \ - Fixture##Name##Helper(Fixture##Name##Helper const&); \ - Fixture##Name##Helper& operator =(Fixture##Name##Helper const&); \ - }; \ - \ - class Test##Fixture##Name : public UnitTest::Test \ - { \ - public: \ - Test##Fixture##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ - private: \ - virtual void RunImpl() const; \ - } test##Fixture##Name##Instance; \ - \ - UnitTest::ListAdder adder##Fixture##Name (List, &test##Fixture##Name##Instance); \ - \ - void Test##Fixture##Name::RunImpl() const \ - { \ - volatile bool ctorOk = false; \ - UT_TRY \ - ({ \ - Fixture##Name##Helper fixtureHelper(m_details); \ - ctorOk = true; \ - UnitTest::ExecuteTest(fixtureHelper, m_details, false); \ - }) \ - UT_CATCH (UnitTest::AssertException, e, \ - { \ - (void)e; \ - }) \ - UT_CATCH (std::exception, e, \ - { \ - UnitTest::MemoryOutStream stream; \ - stream << "Unhandled exception: " << e.what(); \ - UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText()); \ - }) \ - UT_CATCH_ALL \ - ({ \ - if (ctorOk) \ - { \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ - "Unhandled exception while destroying fixture " #Fixture); \ - } \ - else \ - { \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ - "Unhandled exception while constructing fixture " #Fixture); \ - } \ - }) \ - } \ - void Fixture##Name##Helper::RunImpl() - -#define TEST_FIXTURE(Fixture,Name) TEST_FIXTURE_EX(Fixture, Name, UnitTest::Test::GetTestList()) - - -#endif diff --git a/src/TestReporter.h b/src/TestReporter.h deleted file mode 100644 index 99bfaa6..0000000 --- a/src/TestReporter.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef UNITTEST_TESTREPORTER_H -#define UNITTEST_TESTREPORTER_H - -#include "HelperMacros.h" - -namespace UnitTest { - -class TestDetails; - -class UNITTEST_LINKAGE TestReporter -{ -public: - virtual ~TestReporter(); - - virtual void ReportTestStart(TestDetails const& test) = 0; - virtual void ReportFailure(TestDetails const& test, char const* failure) = 0; - virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed) = 0; - virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) = 0; -}; - -} -#endif diff --git a/src/TestReporterStdout.cpp b/src/TestReporterStdout.cpp deleted file mode 100644 index cd2c131..0000000 --- a/src/TestReporterStdout.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "TestReporterStdout.h" -#include - -#include "TestDetails.h" - -// cstdio doesn't pull in namespace std on VC6, so we do it here. -#if defined(UNITTEST_WIN32) && (_MSC_VER == 1200) - namespace std {} -#endif - -namespace UnitTest { - -void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure) -{ -#if defined(__APPLE__) || defined(__GNUG__) - char const* const errorFormat = "%s:%d: error: Failure in %s: %s\n"; -#else - char const* const errorFormat = "%s(%d): error: Failure in %s: %s\n"; -#endif - - using namespace std; - printf(errorFormat, details.filename, details.lineNumber, details.testName, failure); -} - -void TestReporterStdout::ReportTestStart(TestDetails const& /*test*/) -{ -} - -void TestReporterStdout::ReportTestFinish(TestDetails const& /*test*/, float) -{ -} - -void TestReporterStdout::ReportSummary(int const totalTestCount, int const failedTestCount, - int const failureCount, float secondsElapsed) -{ - using namespace std; - - if (failureCount > 0) - printf("FAILURE: %d out of %d tests failed (%d failures).\n", failedTestCount, totalTestCount, failureCount); - else - printf("Success: %d tests passed.\n", totalTestCount); - - printf("Test time: %.2f seconds.\n", secondsElapsed); -} - -} diff --git a/src/TestReporterStdout.h b/src/TestReporterStdout.h deleted file mode 100644 index 4f52f8a..0000000 --- a/src/TestReporterStdout.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef UNITTEST_TESTREPORTERSTDOUT_H -#define UNITTEST_TESTREPORTERSTDOUT_H - -#include "TestReporter.h" - -namespace UnitTest { - -class UNITTEST_LINKAGE TestReporterStdout : public TestReporter -{ -private: - virtual void ReportTestStart(TestDetails const& test); - virtual void ReportFailure(TestDetails const& test, char const* failure); - virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed); - virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); -}; - -} - -#endif diff --git a/src/TestResults.cpp b/src/TestResults.cpp deleted file mode 100644 index 2368e20..0000000 --- a/src/TestResults.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "TestResults.h" -#include "TestReporter.h" - -#include "TestDetails.h" - -namespace UnitTest { - -TestResults::TestResults(TestReporter* testReporter) - : m_testReporter(testReporter) - , m_totalTestCount(0) - , m_failedTestCount(0) - , m_failureCount(0) - , m_currentTestFailed(false) -{ -} - -void TestResults::OnTestStart(TestDetails const& test) -{ - ++m_totalTestCount; - m_currentTestFailed = false; - if (m_testReporter) - m_testReporter->ReportTestStart(test); -} - -void TestResults::OnTestFailure(TestDetails const& test, char const* failure) -{ - ++m_failureCount; - if (!m_currentTestFailed) - { - ++m_failedTestCount; - m_currentTestFailed = true; - } - - if (m_testReporter) - m_testReporter->ReportFailure(test, failure); -} - -void TestResults::OnTestFinish(TestDetails const& test, float secondsElapsed) -{ - if (m_testReporter) - m_testReporter->ReportTestFinish(test, secondsElapsed); -} - -int TestResults::GetTotalTestCount() const -{ - return m_totalTestCount; -} - -int TestResults::GetFailedTestCount() const -{ - return m_failedTestCount; -} - -int TestResults::GetFailureCount() const -{ - return m_failureCount; -} - - -} diff --git a/src/TestResults.h b/src/TestResults.h deleted file mode 100644 index d4006a0..0000000 --- a/src/TestResults.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef UNITTEST_TESTRESULTS_H -#define UNITTEST_TESTRESULTS_H - -#include "HelperMacros.h" - -namespace UnitTest { - -class TestReporter; -class TestDetails; - -class UNITTEST_LINKAGE TestResults -{ -public: - explicit TestResults(TestReporter* reporter = 0); - - void OnTestStart(TestDetails const& test); - void OnTestFailure(TestDetails const& test, char const* failure); - void OnTestFinish(TestDetails const& test, float secondsElapsed); - - int GetTotalTestCount() const; - int GetFailedTestCount() const; - int GetFailureCount() const; - -private: - TestReporter* m_testReporter; - int m_totalTestCount; - int m_failedTestCount; - int m_failureCount; - - bool m_currentTestFailed; - - TestResults(TestResults const&); - TestResults& operator =(TestResults const&); -}; - -} - -#endif diff --git a/src/TestRunner.cpp b/src/TestRunner.cpp deleted file mode 100644 index 108348e..0000000 --- a/src/TestRunner.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "TestRunner.h" -#include "TestResults.h" -#include "TestReporter.h" -#include "TestReporterStdout.h" -#include "TimeHelpers.h" -#include "MemoryOutStream.h" - -#include - - -namespace UnitTest { - -int RunAllTests() -{ - TestReporterStdout reporter; - TestRunner runner(reporter); - return runner.RunTestsIf(Test::GetTestList(), NULL, True(), 0); -} - - -TestRunner::TestRunner(TestReporter& reporter) - : m_reporter(&reporter) - , m_result(new TestResults(&reporter)) - , m_timer(new Timer) -{ - m_timer->Start(); -} - -TestRunner::~TestRunner() -{ - delete m_result; - delete m_timer; -} - -TestResults* TestRunner::GetTestResults() -{ - return m_result; -} - -int TestRunner::Finish() const -{ - float const secondsElapsed = static_cast(m_timer->GetTimeInMs() / 1000.0); - m_reporter->ReportSummary(m_result->GetTotalTestCount(), - m_result->GetFailedTestCount(), - m_result->GetFailureCount(), - secondsElapsed); - - return m_result->GetFailureCount(); -} - -bool TestRunner::IsTestInSuite(const Test* const curTest, char const* suiteName) const -{ - using namespace std; - return (suiteName == NULL) || !strcmp(curTest->m_details.suiteName, suiteName); -} - -void TestRunner::RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const -{ - if (curTest->m_isMockTest == false) - CurrentTest::Results() = result; - - Timer testTimer; - testTimer.Start(); - - result->OnTestStart(curTest->m_details); - - curTest->Run(); - - double const testTimeInMs = testTimer.GetTimeInMs(); - if (maxTestTimeInMs > 0 && testTimeInMs > maxTestTimeInMs && !curTest->m_timeConstraintExempt) - { - MemoryOutStream stream; - stream << "Global time constraint failed. Expected under " << maxTestTimeInMs << - "ms but took " << testTimeInMs << "ms."; - - result->OnTestFailure(curTest->m_details, stream.GetText()); - } - - result->OnTestFinish(curTest->m_details, static_cast< float >(testTimeInMs / 1000.0)); -} - -} diff --git a/src/TestRunner.h b/src/TestRunner.h deleted file mode 100644 index 0253ae2..0000000 --- a/src/TestRunner.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef UNITTEST_TESTRUNNER_H -#define UNITTEST_TESTRUNNER_H - -#include "Test.h" -#include "TestList.h" -#include "CurrentTest.h" - -namespace UnitTest { - -class TestReporter; -class TestResults; -class Timer; - -UNITTEST_LINKAGE int RunAllTests(); - -struct True -{ - bool operator()(const Test* const) const - { - return true; - } -}; - -class UNITTEST_LINKAGE TestRunner -{ -public: - explicit TestRunner(TestReporter& reporter); - ~TestRunner(); - - template< class Predicate > - int RunTestsIf(TestList const& list, char const* suiteName, - const Predicate& predicate, int maxTestTimeInMs) const - { - Test* curTest = list.GetHead(); - - while (curTest != 0) - { - if (IsTestInSuite(curTest, suiteName) && predicate(curTest)) - RunTest(m_result, curTest, maxTestTimeInMs); - - curTest = curTest->m_nextTest; - } - - return Finish(); - } - - TestResults* GetTestResults(); - -private: - TestReporter* m_reporter; - TestResults* m_result; - Timer* m_timer; - - int Finish() const; - bool IsTestInSuite(const Test* const curTest, char const* suiteName) const; - void RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const; -}; - -} - -#endif diff --git a/src/TestSuite.h b/src/TestSuite.h deleted file mode 100644 index 02067fd..0000000 --- a/src/TestSuite.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef UNITTEST_TESTSUITE_H -#define UNITTEST_TESTSUITE_H - -namespace UnitTestSuite -{ - inline char const* GetSuiteName () - { - return "DefaultSuite"; - } -} - -#endif diff --git a/src/TimeConstraint.cpp b/src/TimeConstraint.cpp deleted file mode 100644 index 89f1b87..0000000 --- a/src/TimeConstraint.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "TimeConstraint.h" -#include "TestResults.h" -#include "MemoryOutStream.h" -#include "CurrentTest.h" - -namespace UnitTest { - - -TimeConstraint::TimeConstraint(int ms, TestDetails const& details) - : m_details(details) - , m_maxMs(ms) -{ - m_timer.Start(); -} - -TimeConstraint::~TimeConstraint() -{ - double const totalTimeInMs = m_timer.GetTimeInMs(); - if (totalTimeInMs > m_maxMs) - { - MemoryOutStream stream; - stream << "Time constraint failed. Expected to run test under " << m_maxMs << - "ms but took " << totalTimeInMs << "ms."; - - CurrentTest::Results()->OnTestFailure(m_details, stream.GetText()); - } -} - -} diff --git a/src/TimeConstraint.h b/src/TimeConstraint.h deleted file mode 100644 index fe14461..0000000 --- a/src/TimeConstraint.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef UNITTEST_TIMECONSTRAINT_H -#define UNITTEST_TIMECONSTRAINT_H - -#include "TimeHelpers.h" -#include "HelperMacros.h" - -namespace UnitTest { - -class TestResults; -class TestDetails; - -class UNITTEST_LINKAGE TimeConstraint -{ -public: - TimeConstraint(int ms, TestDetails const& details); - ~TimeConstraint(); - -private: - void operator=(TimeConstraint const&); - TimeConstraint(TimeConstraint const&); - - Timer m_timer; - TestDetails const& m_details; - int const m_maxMs; -}; - -#define UNITTEST_TIME_CONSTRAINT(ms) \ - UnitTest::TimeConstraint unitTest__timeConstraint__(ms, UnitTest::TestDetails(m_details, __LINE__)) - -#define UNITTEST_TIME_CONSTRAINT_EXEMPT() \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - m_timeConstraintExempt = true; \ - UNITTEST_MULTILINE_MACRO_END - -} - -#endif diff --git a/src/TimeHelpers.h b/src/TimeHelpers.h deleted file mode 100644 index 24f0efd..0000000 --- a/src/TimeHelpers.h +++ /dev/null @@ -1,7 +0,0 @@ -#include "../config.h" - -#if defined UNITTEST_POSIX - #include "Posix/TimeHelpers.h" -#else - #include "Win32/TimeHelpers.h" -#endif diff --git a/src/Win32/TimeHelpers.cpp b/src/Win32/TimeHelpers.cpp deleted file mode 100644 index 1b39cab..0000000 --- a/src/Win32/TimeHelpers.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "TimeHelpers.h" - -#define WIN32_LEAN_AND_MEAN -#include - -namespace UnitTest { - -Timer::Timer() - : m_threadHandle(::GetCurrentThread()) - , m_startTime(0) -{ -#if defined(UNITTEST_WIN32) && (_MSC_VER == 1200) // VC6 doesn't have DWORD_PTR - typedef unsigned long DWORD_PTR; -#endif - - DWORD_PTR systemMask; - ::GetProcessAffinityMask(GetCurrentProcess(), &m_processAffinityMask, &systemMask); - ::SetThreadAffinityMask(m_threadHandle, 1); - ::QueryPerformanceFrequency(reinterpret_cast< LARGE_INTEGER* >(&m_frequency)); - ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask); -} - -void Timer::Start() -{ - m_startTime = GetTime(); -} - -double Timer::GetTimeInMs() const -{ - __int64 const elapsedTime = GetTime() - m_startTime; - double const seconds = double(elapsedTime) / double(m_frequency); - return seconds * 1000.0; -} - -__int64 Timer::GetTime() const -{ - LARGE_INTEGER curTime; - ::SetThreadAffinityMask(m_threadHandle, 1); - ::QueryPerformanceCounter(&curTime); - ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask); - return curTime.QuadPart; -} - -void TimeHelpers::SleepMs(int ms) -{ - ::Sleep(ms); -} - -} diff --git a/src/Win32/TimeHelpers.h b/src/Win32/TimeHelpers.h deleted file mode 100644 index 80c9118..0000000 --- a/src/Win32/TimeHelpers.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef UNITTEST_TIMEHELPERS_H -#define UNITTEST_TIMEHELPERS_H - -#include "../../config.h" -#include "../HelperMacros.h" - -#ifdef UNITTEST_MINGW - #ifndef __int64 - #define __int64 long long - #endif -#endif - -namespace UnitTest { - -class UNITTEST_LINKAGE Timer -{ -public: - Timer(); - void Start(); - double GetTimeInMs() const; - -private: - __int64 GetTime() const; - - void* m_threadHandle; - -#if defined(_WIN64) - unsigned __int64 m_processAffinityMask; -#else - unsigned long m_processAffinityMask; -#endif - - __int64 m_startTime; - __int64 m_frequency; -}; - - -namespace TimeHelpers -{ - UNITTEST_LINKAGE void SleepMs(int ms); -} - -} - -#endif diff --git a/src/XmlTestReporter.cpp b/src/XmlTestReporter.cpp deleted file mode 100644 index 09f0f24..0000000 --- a/src/XmlTestReporter.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include "../config.h" -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "XmlTestReporter.h" - -#include -#include -#include - -using std::string; -using std::ostringstream; -using std::ostream; - -namespace { - -void ReplaceChar(string& str, char c, string const& replacement) -{ - for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1)) - str.replace(pos, 1, replacement); -} - -string XmlEscape(string const& value) -{ - string escaped = value; - - ReplaceChar(escaped, '&', "&"); - ReplaceChar(escaped, '<', "<"); - ReplaceChar(escaped, '>', ">"); - ReplaceChar(escaped, '\'', "'"); - ReplaceChar(escaped, '\"', """); - - return escaped; -} - -string BuildFailureMessage(string const& file, int line, string const& message) -{ - ostringstream failureMessage; - failureMessage << file << "(" << line << ") : " << message; - return failureMessage.str(); -} - -} - -namespace UnitTest { - -XmlTestReporter::XmlTestReporter(ostream& ostream) - : m_ostream(ostream) -{ -} - -void XmlTestReporter::ReportSummary(int totalTestCount, int failedTestCount, - int failureCount, float secondsElapsed) -{ - AddXmlElement(m_ostream, NULL); - - BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed); - - DeferredTestResultList const& results = GetResults(); - for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i) - { - BeginTest(m_ostream, *i); - - if (i->failed) - AddFailure(m_ostream, *i); - - EndTest(m_ostream, *i); - } - - EndResults(m_ostream); -} - -void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding) -{ - os << ""; -} - -void XmlTestReporter::BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, - int failureCount, float secondsElapsed) -{ - os << ""; -} - -void XmlTestReporter::EndResults(std::ostream& os) -{ - os << ""; -} - -void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result) -{ - os << ""; - else - os << "/>"; -} - -void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result) -{ - os << ">"; // close element - - for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin(); - it != result.failures.end(); - ++it) - { - string const escapedMessage = XmlEscape(std::string(it->failureStr)); - string const message = BuildFailureMessage(result.failureFile, it->lineNumber, escapedMessage); - - os << ""; - } -} - -} - -#endif diff --git a/src/XmlTestReporter.h b/src/XmlTestReporter.h deleted file mode 100644 index 2adf298..0000000 --- a/src/XmlTestReporter.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef UNITTEST_XMLTESTREPORTER_H -#define UNITTEST_XMLTESTREPORTER_H - -#include "../config.h" -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "DeferredTestReporter.h" - -#include - -namespace UnitTest -{ - -class UNITTEST_LINKAGE XmlTestReporter : public DeferredTestReporter -{ -public: - explicit XmlTestReporter(std::ostream& ostream); - - virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); - -private: - XmlTestReporter(XmlTestReporter const&); - XmlTestReporter& operator=(XmlTestReporter const&); - - void AddXmlElement(std::ostream& os, char const* encoding); - void BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); - void EndResults(std::ostream& os); - void BeginTest(std::ostream& os, DeferredTestResult const& result); - void AddFailure(std::ostream& os, DeferredTestResult const& result); - void EndTest(std::ostream& os, DeferredTestResult const& result); - - std::ostream& m_ostream; -}; - -} - -#endif -#endif diff --git a/src/tests/Main.cpp b/src/tests/Main.cpp deleted file mode 100644 index 963ad7b..0000000 --- a/src/tests/Main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "../../unittestpp.h" - -int main(int, char const *[]) -{ - return UnitTest::RunAllTests(); -} diff --git a/src/tests/RecordingReporter.h b/src/tests/RecordingReporter.h deleted file mode 100644 index df46fdf..0000000 --- a/src/tests/RecordingReporter.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef UNITTEST_RECORDINGREPORTER_H -#define UNITTEST_RECORDINGREPORTER_H - -#include "../TestReporter.h" -#include - -#include "../TestDetails.h" - -struct RecordingReporter : public UnitTest::TestReporter -{ -private: - enum { kMaxStringLength = 256 }; - -public: - RecordingReporter() - : testRunCount(0) - , testFailedCount(0) - , lastFailedLine(0) - , testFinishedCount(0) - , lastFinishedTestTime(0) - , summaryTotalTestCount(0) - , summaryFailedTestCount(0) - , summaryFailureCount(0) - , summarySecondsElapsed(0) - { - lastStartedSuite[0] = '\0'; - lastStartedTest[0] = '\0'; - lastFailedFile[0] = '\0'; - lastFailedSuite[0] = '\0'; - lastFailedTest[0] = '\0'; - lastFailedMessage[0] = '\0'; - lastFinishedSuite[0] = '\0'; - lastFinishedTest[0] = '\0'; - } - - virtual void ReportTestStart(UnitTest::TestDetails const& test) - { - using namespace std; - - ++testRunCount; - strcpy(lastStartedSuite, test.suiteName); - strcpy(lastStartedTest, test.testName); - } - - virtual void ReportFailure(UnitTest::TestDetails const& test, char const* failure) - { - using namespace std; - - ++testFailedCount; - strcpy(lastFailedFile, test.filename); - lastFailedLine = test.lineNumber; - strcpy(lastFailedSuite, test.suiteName); - strcpy(lastFailedTest, test.testName); - strcpy(lastFailedMessage, failure); - } - - virtual void ReportTestFinish(UnitTest::TestDetails const& test, float testDuration) - { - using namespace std; - - ++testFinishedCount; - strcpy(lastFinishedSuite, test.suiteName); - strcpy(lastFinishedTest, test.testName); - lastFinishedTestTime = testDuration; - } - - virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) - { - summaryTotalTestCount = totalTestCount; - summaryFailedTestCount = failedTestCount; - summaryFailureCount = failureCount; - summarySecondsElapsed = secondsElapsed; - } - - int testRunCount; - char lastStartedSuite[kMaxStringLength]; - char lastStartedTest[kMaxStringLength]; - - int testFailedCount; - char lastFailedFile[kMaxStringLength]; - int lastFailedLine; - char lastFailedSuite[kMaxStringLength]; - char lastFailedTest[kMaxStringLength]; - char lastFailedMessage[kMaxStringLength]; - - int testFinishedCount; - char lastFinishedSuite[kMaxStringLength]; - char lastFinishedTest[kMaxStringLength]; - float lastFinishedTestTime; - - int summaryTotalTestCount; - int summaryFailedTestCount; - int summaryFailureCount; - float summarySecondsElapsed; -}; - - -#endif diff --git a/src/tests/ScopedCurrentTest.h b/src/tests/ScopedCurrentTest.h deleted file mode 100644 index 68ae7f5..0000000 --- a/src/tests/ScopedCurrentTest.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef UNITTEST_SCOPEDCURRENTTEST_H -#define UNITTEST_SCOPEDCURRENTTEST_H - -#include "../CurrentTest.h" -#include - -class ScopedCurrentTest -{ -public: - ScopedCurrentTest() - : m_oldTestResults(UnitTest::CurrentTest::Results()) - , m_oldTestDetails(UnitTest::CurrentTest::Details()) - { - } - - explicit ScopedCurrentTest(UnitTest::TestResults& newResults, const UnitTest::TestDetails* newDetails = NULL) - : m_oldTestResults(UnitTest::CurrentTest::Results()) - , m_oldTestDetails(UnitTest::CurrentTest::Details()) - { - UnitTest::CurrentTest::Results() = &newResults; - - if (newDetails != NULL) - UnitTest::CurrentTest::Details() = newDetails; - } - - ~ScopedCurrentTest() - { - UnitTest::CurrentTest::Results() = m_oldTestResults; - UnitTest::CurrentTest::Details() = m_oldTestDetails; - } - -private: - UnitTest::TestResults* m_oldTestResults; - const UnitTest::TestDetails* m_oldTestDetails; -}; - -#endif diff --git a/src/tests/TestAssertHandler.cpp b/src/tests/TestAssertHandler.cpp deleted file mode 100644 index 3b28c5f..0000000 --- a/src/tests/TestAssertHandler.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include "../../config.h" -#include "../../unittestpp.h" - -#include "../ReportAssert.h" -#include "../ReportAssertImpl.h" -#include "../AssertException.h" - -#include "RecordingReporter.h" -#include - -using namespace UnitTest; - -namespace { - -TEST(CanSetAssertExpected) -{ - Detail::ExpectAssert(true); - CHECK(Detail::AssertExpected()); - - Detail::ExpectAssert(false); - CHECK(!Detail::AssertExpected()); -} - -#ifndef UNITTEST_NO_EXCEPTIONS - -TEST(ReportAssertThrowsAssertException) -{ - bool caught = false; - - try - { - TestResults testResults; - TestDetails testDetails("", "", "", 0); - Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0); - } - catch(AssertException const&) - { - caught = true; - } - - CHECK(true == caught); -} - -TEST(ReportAssertClearsExpectAssertFlag) -{ - RecordingReporter reporter; - TestResults testResults(&reporter); - TestDetails testDetails("", "", "", 0); - - try - { - Detail::ExpectAssert(true); - Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0); - } - catch(AssertException const&) - { - } - - CHECK(Detail::AssertExpected() == false); - CHECK_EQUAL(0, reporter.testFailedCount); -} - -TEST(ReportAssertWritesFailureToResultsAndDetailsWhenAssertIsNotExpected) -{ - const int lineNumber = 12345; - const char* description = "description"; - const char* filename = "filename"; - - RecordingReporter reporter; - TestResults testResults(&reporter); - TestDetails testDetails("", "", "", 0); - - try - { - Detail::ReportAssertEx(&testResults, &testDetails, description, filename, lineNumber); - } - catch(AssertException const&) - { - } - - CHECK_EQUAL(description, reporter.lastFailedMessage); - CHECK_EQUAL(filename, reporter.lastFailedFile); - CHECK_EQUAL(lineNumber, reporter.lastFailedLine); -} - -TEST(ReportAssertReportsNoErrorsWhenAssertIsExpected) -{ - Detail::ExpectAssert(true); - - RecordingReporter reporter; - TestResults testResults(&reporter); - TestDetails testDetails("", "", "", 0); - - try - { - Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0); - } - catch(AssertException const&) - { - } - - CHECK_EQUAL(0, reporter.testFailedCount); -} - -TEST(CheckAssertMacroSetsAssertExpectationToFalseAfterRunning) -{ - Detail::ExpectAssert(true); - CHECK_ASSERT(ReportAssert("", "", 0)); - CHECK(!Detail::AssertExpected()); - Detail::ExpectAssert(false); -} - -#else - -TEST(SetAssertJumpTargetReturnsFalseWhenSettingJumpTarget) -{ - CHECK(UNITTEST_SET_ASSERT_JUMP_TARGET() == false); -} - -TEST(JumpToAssertJumpTarget_JumpsToSetPoint_ReturnsTrue) -{ - const volatile bool taken = !!UNITTEST_SET_ASSERT_JUMP_TARGET(); - - volatile bool set = false; - if (taken == false) - { - UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET(); - set = true; - } - - CHECK(set == false); -} - -#endif - -} diff --git a/src/tests/TestCheckMacros.cpp b/src/tests/TestCheckMacros.cpp deleted file mode 100644 index 6b9fb66..0000000 --- a/src/tests/TestCheckMacros.cpp +++ /dev/null @@ -1,518 +0,0 @@ -#include "../../unittestpp.h" -#include "../CurrentTest.h" -#include "RecordingReporter.h" -#include "ScopedCurrentTest.h" - -using namespace std; - -namespace { - -TEST(CheckSucceedsOnTrue) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - - ScopedCurrentTest scopedResults(testResults); - CHECK(true); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckFailsOnFalse) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK(false); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(FailureReportsCorrectTestName) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK(false); - } - - CHECK_EQUAL(m_details.testName, reporter.lastFailedTest); -} - -TEST(CheckFailureIncludesCheckContents) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - const bool yaddayadda = false; - CHECK(yaddayadda); - } - - CHECK(strstr(reporter.lastFailedMessage, "yaddayadda")); -} - -TEST(CheckEqualSucceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(1, 1); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckEqualFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(1, 2); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckEqualFailureContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - CHECK_EQUAL(1, 123); line = __LINE__; - } - - CHECK_EQUAL("testName", reporter.lastFailedTest); - CHECK_EQUAL("suiteName", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -int g_sideEffect = 0; -int FunctionWithSideEffects() -{ - ++g_sideEffect; - return 1; -} - -TEST(CheckEqualDoesNotHaveSideEffectsWhenPassing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(1, FunctionWithSideEffects()); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckEqualDoesNotHaveSideEffectsWhenFailing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(2, FunctionWithSideEffects()); - } - CHECK_EQUAL(1, g_sideEffect); -} - - -TEST(CheckCloseSucceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE (1.0f, 1.001f, 0.01f); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckCloseFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE (1.0f, 1.1f, 0.01f); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckCloseFailureContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails testDetails("test", "suite", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - CHECK_CLOSE (1.0f, 1.1f, 0.01f); line = __LINE__; - } - - CHECK_EQUAL("test", reporter.lastFailedTest); - CHECK_EQUAL("suite", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckCloseDoesNotHaveSideEffectsWhenPassing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE (1, FunctionWithSideEffects(), 0.1f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckCloseDoesNotHaveSideEffectsWhenFailing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE (2, FunctionWithSideEffects(), 0.1f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckArrayCloseSucceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - const float data[4] = { 0, 1, 2, 3 }; - CHECK_ARRAY_CLOSE (data, data, 4, 0.01f); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckArrayCloseFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = { 0, 1, 2, 3 }; - int const data2[4] = { 0, 1, 3, 3 }; - CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckArrayCloseFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = { 0, 1, 2, 3 }; - int const data2[4] = { 0, 1, 3, 3 }; - CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); - CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); -} - -TEST(CheckArrayCloseFailureContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - int const data1[4] = { 0, 1, 2, 3 }; - int const data2[4] = { 0, 1, 3, 3 }; - CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); line = __LINE__; - } - - CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckArrayCloseFailureIncludesTolerance) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - float const data1[4] = { 0, 1, 2, 3 }; - float const data2[4] = { 0, 1, 3, 3 }; - CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "0.01")); -} - -TEST(CheckArrayEqualSuceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[4] = { 0, 1, 2, 3 }; - CHECK_ARRAY_EQUAL (data, data, 4); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckArrayEqualFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = { 0, 1, 2, 3 }; - int const data2[4] = { 0, 1, 3, 3 }; - CHECK_ARRAY_EQUAL (data1, data2, 4); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckArrayEqualFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = { 0, 1, 2, 3 }; - int const data2[4] = { 0, 1, 3, 3 }; - CHECK_ARRAY_EQUAL (data1, data2, 4); - } - - CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); - CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); -} - -TEST(CheckArrayEqualFailureContainsCorrectInfo) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = { 0, 1, 2, 3 }; - int const data2[4] = { 0, 1, 3, 3 }; - CHECK_ARRAY_EQUAL (data1, data2, 4); line = __LINE__; - } - - CHECK_EQUAL("CheckArrayEqualFailureContainsCorrectInfo", reporter.lastFailedTest); - CHECK_EQUAL(__FILE__, reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -float const* FunctionWithSideEffects2() -{ - ++g_sideEffect; - static float const data[] = {1,2,3,4}; - return data; -} - -TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenPassing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - - const float data[] = { 0, 1, 2, 3 }; - CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenFailing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - - const float data[] = { 0, 1, 3, 3 }; - CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); - } - - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckArray2DCloseSucceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[2][2] = { {0, 1}, {2, 3} }; - CHECK_ARRAY2D_CLOSE (data, data, 2, 2, 0.01f); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckArray2DCloseFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[2][2] = { {0, 1}, {2, 3} }; - int const data2[2][2] = { {0, 1}, {3, 3} }; - CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckArray2DCloseFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[2][2] = { {0, 1}, {2, 3} }; - int const data2[2][2] = { {0, 1}, {3, 3} }; - - CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "xpected [ [ 0 1 ] [ 2 3 ] ]")); - CHECK(strstr(reporter.lastFailedMessage, "was [ [ 0 1 ] [ 3 3 ] ]")); -} - -TEST(CheckArray2DCloseFailureContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - int const data1[2][2] = { {0, 1}, {2, 3} }; - int const data2[2][2] = { {0, 1}, {3, 3} }; - CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); line = __LINE__; - } - - CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckArray2DCloseFailureIncludesTolerance) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - float const data1[2][2] = { {0, 1}, {2, 3} }; - float const data2[2][2] = { {0, 1}, {3, 3} }; - CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "0.01")); -} - -float const* const* FunctionWithSideEffects3() -{ - ++g_sideEffect; - static float const data1[] = {0,1}; - static float const data2[] = {2,3}; - static const float* const data[] = {data1, data2}; - return data; -} - -TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenPassing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - - const float data[2][2] = { {0, 1}, {2, 3} }; - CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenFailing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - - const float data[2][2] = { {0, 1}, {3, 3} }; - CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -} diff --git a/src/tests/TestChecks.cpp b/src/tests/TestChecks.cpp deleted file mode 100644 index 10b3071..0000000 --- a/src/tests/TestChecks.cpp +++ /dev/null @@ -1,291 +0,0 @@ -#include "../../unittestpp.h" -#include "RecordingReporter.h" - -#include - -using namespace UnitTest; - - -namespace { - - -TEST(CheckEqualWithUnsignedLong) -{ - TestResults results; - unsigned long something = 2; - CHECK_EQUAL(something, something); -} - -TEST(CheckEqualsWithStringsFailsOnDifferentStrings) -{ - char txt1[] = "Hello"; - char txt2[] = "Hallo"; - TestResults results; - CheckEqual(results, txt1, txt2, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -char txt1[] = "Hello"; // non-const on purpose so no folding of duplicate data -char txt2[] = "Hello"; - -TEST(CheckEqualsWithStringsWorksOnContentsNonConstNonConst) -{ - char const* const p1 = txt1; - char const* const p2 = txt2; - TestResults results; - CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualsWithStringsWorksOnContentsConstConst) -{ - char* const p1 = txt1; - char* const p2 = txt2; - TestResults results; - CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualsWithStringsWorksOnContentsNonConstConst) -{ - char* const p1 = txt1; - char const* const p2 = txt2; - TestResults results; - CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualsWithStringsWorksOnContentsConstNonConst) -{ - char const* const p1 = txt1; - char* const p2 = txt2; - TestResults results; - CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualsWithStringsWorksOnContentsWithALiteral) -{ - char const* const p1 = txt1; - TestResults results; - CheckEqual(results, "Hello", p1, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - TestResults results(&reporter); - const int something = 2; - CheckEqual(results, 1, something, TestDetails("", "", "", 0)); - - using namespace std; - CHECK(strstr(reporter.lastFailedMessage, "xpected 1")); - CHECK(strstr(reporter.lastFailedMessage, "was 2")); -} - -TEST(CheckEqualFailureIncludesDetails) -{ - RecordingReporter reporter; - TestResults results(&reporter); - TestDetails const details("mytest", "mysuite", "file.h", 101); - - CheckEqual(results, 1, 2, details); - - CHECK_EQUAL("mytest", reporter.lastFailedTest); - CHECK_EQUAL("mysuite", reporter.lastFailedSuite); - CHECK_EQUAL("file.h", reporter.lastFailedFile); - CHECK_EQUAL(101, reporter.lastFailedLine); -} - -TEST(CheckCloseTrue) -{ - TestResults results; - CheckClose(results, 3.001f, 3.0f, 0.1f, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckCloseFalse) -{ - TestResults results; - CheckClose(results, 3.12f, 3.0f, 0.1f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckCloseWithZeroEpsilonWorksForSameNumber) -{ - TestResults results; - CheckClose(results, 0.1f, 0.1f, 0, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckCloseWithNaNFails) -{ - const unsigned int bitpattern = 0xFFFFFFFF; - float nan; - std::memcpy(&nan, &bitpattern, sizeof(bitpattern)); - - TestResults results; - CheckClose(results, 3.0f, nan, 0.1f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckCloseWithNaNAgainstItselfFails) -{ - const unsigned int bitpattern = 0xFFFFFFFF; - float nan; - std::memcpy(&nan, &bitpattern, sizeof(bitpattern)); - - TestResults results; - CheckClose(results, nan, nan, 0.1f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckCloseFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - TestResults results(&reporter); - const float expected = 0.9f; - const float actual = 1.1f; - CheckClose(results, expected, actual, 0.01f, TestDetails("", "", "", 0)); - - using namespace std; - CHECK(strstr(reporter.lastFailedMessage, "xpected 0.9")); - CHECK(strstr(reporter.lastFailedMessage, "was 1.1")); -} - -TEST(CheckCloseFailureIncludesTolerance) -{ - RecordingReporter reporter; - TestResults results(&reporter); - CheckClose(results, 2, 3, 0.01f, TestDetails("", "", "", 0)); - - using namespace std; - CHECK(strstr(reporter.lastFailedMessage, "0.01")); -} - -TEST(CheckCloseFailureIncludesDetails) -{ - RecordingReporter reporter; - TestResults results(&reporter); - TestDetails const details("mytest", "mysuite", "header.h", 10); - - CheckClose(results, 2, 3, 0.01f, details); - - CHECK_EQUAL("mytest", reporter.lastFailedTest); - CHECK_EQUAL("mysuite", reporter.lastFailedSuite); - CHECK_EQUAL("header.h", reporter.lastFailedFile); - CHECK_EQUAL(10, reporter.lastFailedLine); -} - - -TEST(CheckArrayEqualTrue) -{ - TestResults results; - - int const array[3] = { 1, 2, 3 }; - CheckArrayEqual(results, array, array, 3, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckArrayEqualFalse) -{ - TestResults results; - - int const array1[3] = { 1, 2, 3 }; - int const array2[3] = { 1, 2, 2 }; - CheckArrayEqual(results, array1, array2, 3, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckArrayCloseTrue) -{ - TestResults results; - - float const array1[3] = { 1.0f, 1.5f, 2.0f }; - float const array2[3] = { 1.01f, 1.51f, 2.01f }; - CheckArrayClose(results, array1, array2, 3, 0.02f, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckArrayCloseFalse) -{ - TestResults results; - - float const array1[3] = { 1.0f, 1.5f, 2.0f }; - float const array2[3] = { 1.01f, 1.51f, 2.01f }; - CheckArrayClose(results, array1, array2, 3, 0.001f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckArrayCloseFailureIncludesDetails) -{ - RecordingReporter reporter; - TestResults results(&reporter); - TestDetails const details("arrayCloseTest", "arrayCloseSuite", "file", 1337); - - float const array1[3] = { 1.0f, 1.5f, 2.0f }; - float const array2[3] = { 1.01f, 1.51f, 2.01f }; - CheckArrayClose(results, array1, array2, 3, 0.001f, details); - - CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("file", reporter.lastFailedFile); - CHECK_EQUAL(1337, reporter.lastFailedLine); -} - - -TEST(CheckArray2DCloseTrue) -{ - TestResults results; - - float const array1[3][3] = { { 1.0f, 1.5f, 2.0f }, - { 2.0f, 2.5f, 3.0f }, - { 3.0f, 3.5f, 4.0f } }; - float const array2[3][3] = { { 1.01f, 1.51f, 2.01f }, - { 2.01f, 2.51f, 3.01f }, - { 3.01f, 3.51f, 4.01f } }; - CheckArray2DClose(results, array1, array2, 3, 3, 0.02f, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckArray2DCloseFalse) -{ - TestResults results; - - float const array1[3][3] = { { 1.0f, 1.5f, 2.0f }, - { 2.0f, 2.5f, 3.0f }, - { 3.0f, 3.5f, 4.0f } }; - float const array2[3][3] = { { 1.01f, 1.51f, 2.01f }, - { 2.01f, 2.51f, 3.01f }, - { 3.01f, 3.51f, 4.01f } }; - CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckCloseWithDoublesSucceeds) -{ - CHECK_CLOSE(0.5, 0.5, 0.0001); -} - -TEST(CheckArray2DCloseFailureIncludesDetails) -{ - RecordingReporter reporter; - TestResults results(&reporter); - TestDetails const details("array2DCloseTest", "array2DCloseSuite", "file", 1234); - - float const array1[3][3] = { { 1.0f, 1.5f, 2.0f }, - { 2.0f, 2.5f, 3.0f }, - { 3.0f, 3.5f, 4.0f } }; - float const array2[3][3] = { { 1.01f, 1.51f, 2.01f }, - { 2.01f, 2.51f, 3.01f }, - { 3.01f, 3.51f, 4.01f } }; - CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, details); - - CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("file", reporter.lastFailedFile); - CHECK_EQUAL(1234, reporter.lastFailedLine); -} - -} diff --git a/src/tests/TestCompositeTestReporter.cpp b/src/tests/TestCompositeTestReporter.cpp deleted file mode 100644 index d302577..0000000 --- a/src/tests/TestCompositeTestReporter.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#include "../../unittestpp.h" -#include "../CompositeTestReporter.h" - -using namespace UnitTest; - -namespace { - -TEST(ZeroReportersByDefault) -{ - CHECK_EQUAL(0, CompositeTestReporter().GetReporterCount()); -} - -struct MockReporter : TestReporter -{ - MockReporter() - : testStartCalled(false) - , testStartDetails(NULL) - , failureCalled(false) - , failureDetails(NULL) - , failureStr(NULL) - , testFinishCalled(false) - , testFinishDetails(NULL) - , testFinishSecondsElapsed(-1.0f) - , summaryCalled(false) - , summaryTotalTestCount(-1) - , summaryFailureCount(-1) - , summarySecondsElapsed(-1.0f) - { - } - - virtual void ReportTestStart(TestDetails const& test) - { - testStartCalled = true; - testStartDetails = &test; - } - - virtual void ReportFailure(TestDetails const& test, char const* failure) - { - failureCalled = true; - failureDetails = &test; - failureStr = failure; - } - - virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed) - { - testFinishCalled = true; - testFinishDetails = &test; - testFinishSecondsElapsed = secondsElapsed; - } - - virtual void ReportSummary(int totalTestCount, - int failedTestCount, - int failureCount, - float secondsElapsed) - { - summaryCalled = true; - summaryTotalTestCount = totalTestCount; - summaryFailedTestCount = failedTestCount; - summaryFailureCount = failureCount; - summarySecondsElapsed = secondsElapsed; - } - - bool testStartCalled; - TestDetails const* testStartDetails; - - bool failureCalled; - TestDetails const* failureDetails; - const char* failureStr; - - bool testFinishCalled; - TestDetails const* testFinishDetails; - float testFinishSecondsElapsed; - - bool summaryCalled; - int summaryTotalTestCount; - int summaryFailedTestCount; - int summaryFailureCount; - float summarySecondsElapsed; -}; - -TEST(AddReporter) -{ - MockReporter r; - CompositeTestReporter c; - - CHECK(c.AddReporter(&r)); - CHECK_EQUAL(1, c.GetReporterCount()); -} - -TEST(RemoveReporter) -{ - MockReporter r; - CompositeTestReporter c; - - c.AddReporter(&r); - CHECK(c.RemoveReporter(&r)); - CHECK_EQUAL(0, c.GetReporterCount()); -} - -struct Fixture -{ - Fixture() - { - c.AddReporter(&r0); - c.AddReporter(&r1); - } - - MockReporter r0, r1; - CompositeTestReporter c; -}; - -TEST_FIXTURE(Fixture, ReportTestStartCallsReportTestStartOnAllAggregates) -{ - TestDetails t("", "", "", 0); - c.ReportTestStart(t); - - CHECK(r0.testStartCalled); - CHECK_EQUAL(&t, r0.testStartDetails); - CHECK(r1.testStartCalled); - CHECK_EQUAL(&t, r1.testStartDetails); -} - -TEST_FIXTURE(Fixture, ReportFailureCallsReportFailureOnAllAggregates) -{ - TestDetails t("", "", "", 0); - const char* failStr = "fail"; - c.ReportFailure(t, failStr); - - CHECK(r0.failureCalled); - CHECK_EQUAL(&t, r0.failureDetails); - CHECK_EQUAL(failStr, r0.failureStr); - - CHECK(r1.failureCalled); - CHECK_EQUAL(&t, r1.failureDetails); - CHECK_EQUAL(failStr, r1.failureStr); -} - -TEST_FIXTURE(Fixture, ReportTestFinishCallsReportTestFinishOnAllAggregates) -{ - TestDetails t("", "", "", 0); - const float s = 1.2345f; - c.ReportTestFinish(t, s); - - CHECK(r0.testFinishCalled); - CHECK_EQUAL(&t, r0.testFinishDetails); - CHECK_CLOSE(s, r0.testFinishSecondsElapsed, 0.00001f); - - CHECK(r1.testFinishCalled); - CHECK_EQUAL(&t, r1.testFinishDetails); - CHECK_CLOSE(s, r1.testFinishSecondsElapsed, 0.00001f); -} - -TEST_FIXTURE(Fixture, ReportSummaryCallsReportSummaryOnAllAggregates) -{ - TestDetails t("", "", "", 0); - const int testCount = 3; - const int failedTestCount = 4; - const int failureCount = 5; - const float secondsElapsed = 3.14159f; - - c.ReportSummary(testCount, failedTestCount, failureCount, secondsElapsed); - - CHECK(r0.summaryCalled); - CHECK_EQUAL(testCount, r0.summaryTotalTestCount); - CHECK_EQUAL(failedTestCount, r0.summaryFailedTestCount); - CHECK_EQUAL(failureCount, r0.summaryFailureCount); - CHECK_CLOSE(secondsElapsed, r0.summarySecondsElapsed, 0.00001f); - - CHECK(r1.summaryCalled); - CHECK_EQUAL(testCount, r1.summaryTotalTestCount); - CHECK_EQUAL(failedTestCount, r1.summaryFailedTestCount); - CHECK_EQUAL(failureCount, r1.summaryFailureCount); - CHECK_CLOSE(secondsElapsed, r1.summarySecondsElapsed, 0.00001f); -} - -} diff --git a/src/tests/TestCurrentTest.cpp b/src/tests/TestCurrentTest.cpp deleted file mode 100644 index 766539f..0000000 --- a/src/tests/TestCurrentTest.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "../../unittestpp.h" -#include "../CurrentTest.h" -#include "ScopedCurrentTest.h" - -namespace -{ - -TEST(CanSetandGetDetails) -{ - bool ok = false; - { - ScopedCurrentTest scopedTest; - - const UnitTest::TestDetails* details = reinterpret_cast< const UnitTest::TestDetails* >(12345); - UnitTest::CurrentTest::Details() = details; - - ok = (UnitTest::CurrentTest::Details() == details); - } - - CHECK(ok); -} - -TEST(CanSetAndGetResults) -{ - bool ok = false; - { - ScopedCurrentTest scopedTest; - - UnitTest::TestResults results; - UnitTest::CurrentTest::Results() = &results; - - ok = (UnitTest::CurrentTest::Results() == &results); - } - - CHECK(ok); -} - -} diff --git a/src/tests/TestDeferredTestReporter.cpp b/src/tests/TestDeferredTestReporter.cpp deleted file mode 100644 index 7550ab4..0000000 --- a/src/tests/TestDeferredTestReporter.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "../../config.h" - -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "../../unittestpp.h" -#include "../DeferredTestReporter.h" -#include - -namespace UnitTest -{ - -namespace -{ - -#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - MemoryOutStream& operator <<(MemoryOutStream& lhs, const std::string& rhs) - { - lhs << rhs.c_str(); - return lhs; - } -#endif - -struct MockDeferredTestReporter : public DeferredTestReporter -{ - virtual void ReportSummary(int, int, int, float) - { - } -}; - -struct DeferredTestReporterFixture -{ - DeferredTestReporterFixture() - : testName("UniqueTestName") - , testSuite("UniqueTestSuite") - , fileName("filename.h") - , lineNumber(12) - , details(testName.c_str(), testSuite.c_str(), fileName.c_str(), lineNumber) - { - } - - MockDeferredTestReporter reporter; - std::string const testName; - std::string const testSuite; - std::string const fileName; - int const lineNumber; - TestDetails const details; -}; - -TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCreatesANewDeferredTest) -{ - reporter.ReportTestStart(details); - CHECK_EQUAL(1, (int)reporter.GetResults().size()); -} - -TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCapturesTestNameAndSuite) -{ - reporter.ReportTestStart(details); - - DeferredTestResult const& result = reporter.GetResults().at(0); - CHECK_EQUAL(testName.c_str(), result.testName); - CHECK_EQUAL(testSuite.c_str(), result.suiteName); -} - -TEST_FIXTURE(DeferredTestReporterFixture, ReportTestEndCapturesTestTime) -{ - float const elapsed = 123.45f; - reporter.ReportTestStart(details); - reporter.ReportTestFinish(details, elapsed); - - DeferredTestResult const& result = reporter.GetResults().at(0); - CHECK_CLOSE(elapsed, result.timeElapsed, 0.0001f); -} - -TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetails) -{ - char const* failure = "failure"; - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, failure); - - DeferredTestResult const& result = reporter.GetResults().at(0); - CHECK(result.failed == true); - CHECK_EQUAL(fileName.c_str(), result.failureFile); -} - -TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetailsForMultipleFailures) -{ - char const* failure1 = "failure 1"; - char const* failure2 = "failure 2"; - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, failure1); - reporter.ReportFailure(details, failure2); - - DeferredTestResult const& result = reporter.GetResults().at(0); - CHECK_EQUAL(2, (int)result.failures.size()); - CHECK_EQUAL(failure1, result.failures[0].failureStr); - CHECK_EQUAL(failure2, result.failures[1].failureStr); -} - -TEST_FIXTURE(DeferredTestReporterFixture, DeferredTestReporterTakesCopyOfFailureMessage) -{ - reporter.ReportTestStart(details); - - char failureMessage[128]; - char const* goodStr = "Real failure message"; - char const* badStr = "Bogus failure message"; - - using namespace std; - - strcpy(failureMessage, goodStr); - reporter.ReportFailure(details, failureMessage); - strcpy(failureMessage, badStr); - - DeferredTestResult const& result = reporter.GetResults().at(0); - DeferredTestFailure const& failure = result.failures.at(0); - CHECK_EQUAL(goodStr, failure.failureStr); -} - -}} - -#endif diff --git a/src/tests/TestExceptions.cpp b/src/tests/TestExceptions.cpp deleted file mode 100644 index 6f55c9a..0000000 --- a/src/tests/TestExceptions.cpp +++ /dev/null @@ -1,293 +0,0 @@ -#include "../../config.h" -#ifndef UNITTEST_NO_EXCEPTIONS - -#include "../../unittestpp.h" -#include "../CurrentTest.h" -#include "RecordingReporter.h" -#include "ScopedCurrentTest.h" - -using namespace std; - -namespace { - -int ThrowingFunction() -{ - throw "Doh"; -} - -TEST(CheckFailsOnException) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK(ThrowingFunction() == 1); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckFailureBecauseOfExceptionIncludesCheckContents) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK(ThrowingFunction() == 1); - } - - CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1")); -} - -TEST(CheckEqualFailsOnException) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(ThrowingFunction(), 1); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckEqualFailureBecauseOfExceptionContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - CHECK_EQUAL(ThrowingFunction(), 123); line = __LINE__; - } - - CHECK_EQUAL("testName", reporter.lastFailedTest); - CHECK_EQUAL("suiteName", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckEqualFailureBecauseOfExceptionIncludesCheckContents) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(ThrowingFunction(), 123); - } - - CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction()")); - CHECK(strstr(reporter.lastFailedMessage, "123")); -} - -TEST(CheckCloseFailsOnException) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckCloseFailureBecauseOfExceptionContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails testDetails("closeTest", "closeSuite", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f); line = __LINE__; - } - - CHECK_EQUAL("closeTest", reporter.lastFailedTest); - CHECK_EQUAL("closeSuite", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckCloseFailureBecauseOfExceptionIncludesCheckContents) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f); - } - - CHECK(strstr(reporter.lastFailedMessage, "(float)ThrowingFunction()")); - CHECK(strstr(reporter.lastFailedMessage, "1.0001f")); -} - -class ThrowingObject -{ -public: - float operator[](int) const - { - throw "Test throw"; - } -}; - -TEST(CheckArrayCloseFailureBecauseOfExceptionContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - int const data[4] = { 0, 1, 2, 3 }; - CHECK_ARRAY_CLOSE(data, ThrowingObject(), 4, 0.01f); line = __LINE__; - } - - CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckArrayCloseFailsOnException) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[4] = { 0, 1, 2, 3 }; - ThrowingObject obj; - CHECK_ARRAY_CLOSE(data, obj, 3, 0.01f); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckArrayCloseFailureOnExceptionIncludesCheckContents) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[4] = { 0, 1, 2, 3 }; - ThrowingObject obj; - CHECK_ARRAY_CLOSE(data, obj, 3, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "data")); - CHECK(strstr(reporter.lastFailedMessage, "obj")); -} - -TEST(CheckArrayEqualFailsOnException) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[4] = { 0, 1, 2, 3 }; - ThrowingObject obj; - CHECK_ARRAY_EQUAL (data, obj, 3); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckArrayEqualFailureOnExceptionIncludesCheckContents) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[4] = { 0, 1, 2, 3 }; - ThrowingObject obj; - CHECK_ARRAY_EQUAL (data, obj, 3); - } - - CHECK(strstr(reporter.lastFailedMessage, "data")); - CHECK(strstr(reporter.lastFailedMessage, "obj")); -} - -class ThrowingObject2D -{ -public: - float* operator[](int) const - { - throw "Test throw"; - } -}; - -TEST(CheckArray2DCloseFailureBecauseOfExceptionContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - const float data[2][2] = { {0, 1}, {2, 3} }; - CHECK_ARRAY2D_CLOSE(data, ThrowingObject2D(), 2, 2, 0.01f); line = __LINE__; - } - - CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckArray2DCloseFailsOnException) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[2][2] = { {0, 1}, {2, 3} }; - ThrowingObject2D obj; - CHECK_ARRAY2D_CLOSE(data, obj, 2, 2, 0.01f); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckArray2DCloseFailureOnExceptionIncludesCheckContents) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[2][2] = { {0, 1}, {2, 3} }; - ThrowingObject2D obj; - CHECK_ARRAY2D_CLOSE(data, obj, 2, 2, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "data")); - CHECK(strstr(reporter.lastFailedMessage, "obj")); -} - -} - -#endif diff --git a/src/tests/TestMemoryOutStream.cpp b/src/tests/TestMemoryOutStream.cpp deleted file mode 100644 index f83b10c..0000000 --- a/src/tests/TestMemoryOutStream.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "../../unittestpp.h" - -#include "../MemoryOutStream.h" -#include -#include -#include - -using namespace UnitTest; -using namespace std; - -namespace { - -TEST(DefaultIsEmptyString) -{ - MemoryOutStream const stream; - CHECK(stream.GetText() != 0); - CHECK_EQUAL("", stream.GetText()); -} - -TEST(StreamingTextCopiesCharacters) -{ - MemoryOutStream stream; - stream << "Lalala"; - CHECK_EQUAL("Lalala", stream.GetText()); -} - -TEST(StreamingMultipleTimesConcatenatesResult) -{ - MemoryOutStream stream; - stream << "Bork" << "Foo" << "Bar"; - CHECK_EQUAL("BorkFooBar", stream.GetText()); -} - -TEST(StreamingIntWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (int)123; - CHECK_EQUAL("123", stream.GetText()); -} - -TEST(StreamingUnsignedIntWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (unsigned int)123; - CHECK_EQUAL("123", stream.GetText()); -} - -TEST(StreamingLongWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (long)(-123); - CHECK_EQUAL("-123", stream.GetText()); -} - -TEST(StreamingUnsignedLongWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (unsigned long)123; - CHECK_EQUAL("123", stream.GetText()); -} - -TEST(StreamingLongLongWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (long long)8589934590ll; - CHECK_EQUAL("8589934590", stream.GetText()); -} - -TEST(StreamingUnsignedLongLongWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (unsigned long long)8589934590ull; - CHECK_EQUAL("8589934590", stream.GetText()); -} - -TEST(StreamingFloatWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << 3.1415f; - CHECK(strstr(stream.GetText(), "3.1415")); -} - -TEST(StreamingDoubleWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << 3.1415; - CHECK(strstr(stream.GetText(), "3.1415")); -} - -TEST(StreamingPointerWritesCorrectCharacters) -{ - MemoryOutStream stream; - int* p = (int*)0x1234; - stream << p; - CHECK(strstr(stream.GetText(), "1234")); -} - -TEST(StreamingSizeTWritesCorrectCharacters) -{ - MemoryOutStream stream; - size_t const s = 53124; - stream << s; - CHECK_EQUAL("53124", stream.GetText()); -} - -TEST(ClearEmptiesMemoryOutStreamContents) -{ - MemoryOutStream stream; - stream << "Hello world"; - stream.Clear(); - CHECK_EQUAL("", stream.GetText()); -} - -#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - -TEST(StreamInitialCapacityIsCorrect) -{ - MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE); - CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE, stream.GetCapacity()); -} - -TEST(StreamInitialCapacityIsMultipleOfGrowChunkSize) -{ - MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE + 1); - CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity()); -} - - -TEST(ExceedingCapacityGrowsBuffer) -{ - MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE); - stream << "012345678901234567890123456789"; - char const* const oldBuffer = stream.GetText(); - stream << "0123456789"; - CHECK(oldBuffer != stream.GetText()); -} - -TEST(ExceedingCapacityGrowsBufferByGrowChunk) -{ - MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE); - stream << "0123456789012345678901234567890123456789"; - CHECK_EQUAL(MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity()); -} - -TEST(WritingStringLongerThanCapacityFitsInNewBuffer) -{ - MemoryOutStream stream(8); - stream << "0123456789ABCDEF"; - CHECK_EQUAL("0123456789ABCDEF", stream.GetText()); -} - -TEST(WritingIntLongerThanCapacityFitsInNewBuffer) -{ - MemoryOutStream stream(8); - stream << "aaaa" << 123456;; - CHECK_EQUAL("aaaa123456", stream.GetText()); -} - -TEST(WritingFloatLongerThanCapacityFitsInNewBuffer) -{ - MemoryOutStream stream(8); - stream << "aaaa" << 123456.0f;; - CHECK_EQUAL("aaaa123456.000000f", stream.GetText()); -} - -TEST(WritingSizeTLongerThanCapacityFitsInNewBuffer) -{ - MemoryOutStream stream(8); - stream << "aaaa" << size_t(32145); - CHECK_EQUAL("aaaa32145", stream.GetText()); -} - -#endif - -} diff --git a/src/tests/TestTest.cpp b/src/tests/TestTest.cpp deleted file mode 100644 index 2ae2192..0000000 --- a/src/tests/TestTest.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "../../unittestpp.h" -#include "../TestReporter.h" -#include "../TimeHelpers.h" -#include "ScopedCurrentTest.h" - -using namespace UnitTest; - -namespace { - -TEST(PassingTestHasNoFailures) -{ - class PassingTest : public Test - { - public: - PassingTest() : Test("passing") {} - virtual void RunImpl() const - { - CHECK(true); - } - }; - - TestResults results; - { - ScopedCurrentTest scopedResults(results); - PassingTest().Run(); - } - - CHECK_EQUAL(0, results.GetFailureCount()); -} - - -TEST(FailingTestHasFailures) -{ - class FailingTest : public Test - { - public: - FailingTest() : Test("failing") {} - virtual void RunImpl() const - { - CHECK(false); - } - }; - - TestResults results; - { - ScopedCurrentTest scopedResults(results); - FailingTest().Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} - -#ifndef UNITTEST_NO_EXCEPTIONS -TEST(ThrowingTestsAreReportedAsFailures) -{ - class CrashingTest : public Test - { - public: - CrashingTest() : Test("throwing") {} - virtual void RunImpl() const - { - throw "Blah"; - } - }; - - TestResults results; - { - ScopedCurrentTest scopedResult(results); - CrashingTest().Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} - -#ifndef UNITTEST_MINGW -TEST(CrashingTestsAreReportedAsFailures) -{ - class CrashingTest : public Test - { - public: - CrashingTest() : Test("crashing") {} - virtual void RunImpl() const - { - reinterpret_cast< void (*)() >(0)(); - } - }; - - TestResults results; - { - ScopedCurrentTest scopedResult(results); - CrashingTest().Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} -#endif -#endif - -TEST(TestWithUnspecifiedSuiteGetsDefaultSuite) -{ - Test test("test"); - CHECK(test.m_details.suiteName != NULL); - CHECK_EQUAL("DefaultSuite", test.m_details.suiteName); -} - -TEST(TestReflectsSpecifiedSuiteName) -{ - Test test("test", "testSuite"); - CHECK(test.m_details.suiteName != NULL); - CHECK_EQUAL("testSuite", test.m_details.suiteName); -} - -void Fail() -{ - CHECK(false); -} - -TEST(OutOfCoreCHECKMacrosCanFailTests) -{ - TestResults results; - { - ScopedCurrentTest scopedResult(results); - Fail(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} - -} diff --git a/src/tests/TestTestList.cpp b/src/tests/TestTestList.cpp deleted file mode 100644 index fdeba34..0000000 --- a/src/tests/TestTestList.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "../../unittestpp.h" -#include "../TestList.h" - -using namespace UnitTest; - -namespace { - - -TEST(TestListIsEmptyByDefault) -{ - TestList list; - CHECK(list.GetHead() == 0); -} - -TEST(AddingTestSetsHeadToTest) -{ - Test test("test"); - TestList list; - list.Add(&test); - - CHECK(list.GetHead() == &test); - CHECK(test.m_nextTest == 0); -} - -TEST(AddingSecondTestAddsItToEndOfList) -{ - Test test1("test1"); - Test test2("test2"); - - TestList list; - list.Add(&test1); - list.Add(&test2); - - CHECK(list.GetHead() == &test1); - CHECK(test1.m_nextTest == &test2); - CHECK(test2.m_nextTest == 0); -} - -TEST(ListAdderAddsTestToList) -{ - TestList list; - - Test test(""); - ListAdder adder(list, &test); - - CHECK(list.GetHead() == &test); - CHECK(test.m_nextTest == 0); -} - -} diff --git a/src/tests/TestTestMacros.cpp b/src/tests/TestTestMacros.cpp deleted file mode 100644 index b057e4f..0000000 --- a/src/tests/TestTestMacros.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include "../../unittestpp.h" -#include "../TestMacros.h" -#include "../TestList.h" -#include "../TestResults.h" -#include "../TestReporter.h" -#include "../ReportAssert.h" -#include "RecordingReporter.h" -#include "ScopedCurrentTest.h" - -using namespace UnitTest; -using namespace std; - -namespace { - -TestList list1; -TEST_EX(DummyTest, list1) -{ -} - -TEST (TestsAreAddedToTheListThroughMacro) -{ - CHECK(list1.GetHead() != 0); - CHECK(list1.GetHead()->m_nextTest == 0); -} - -#ifndef UNITTEST_NO_EXCEPTIONS - -struct ThrowingThingie -{ - ThrowingThingie() : dummy(false) - { - if (!dummy) - throw "Oops"; - } - - bool dummy; -}; - -TestList list2; -TEST_FIXTURE_EX(ThrowingThingie, DummyTestName, list2) -{ -} - -TEST (ExceptionsInFixtureAreReportedAsHappeningInTheFixture) -{ - RecordingReporter reporter; - TestResults result(&reporter); - { - ScopedCurrentTest scopedResults(result); - list2.GetHead()->Run(); - } - - CHECK(strstr(reporter.lastFailedMessage, "xception")); - CHECK(strstr(reporter.lastFailedMessage, "fixture")); - CHECK(strstr(reporter.lastFailedMessage, "ThrowingThingie")); -} - -#endif - -struct DummyFixture -{ - int x; -}; - -// We're really testing the macros so we just want them to compile and link -SUITE(TestSuite1) -{ - TEST(SimilarlyNamedTestsInDifferentSuitesWork) - { - } - - TEST_FIXTURE(DummyFixture, SimilarlyNamedFixtureTestsInDifferentSuitesWork) - { - } -} - -SUITE(TestSuite2) -{ - TEST(SimilarlyNamedTestsInDifferentSuitesWork) - { - } - - TEST_FIXTURE(DummyFixture,SimilarlyNamedFixtureTestsInDifferentSuitesWork) - { - } -} - -TestList macroTestList1; -TEST_EX(MacroTestHelper1, macroTestList1) -{ -} - -TEST(TestAddedWithTEST_EXMacroGetsDefaultSuite) -{ - CHECK(macroTestList1.GetHead() != NULL); - CHECK_EQUAL ("MacroTestHelper1", macroTestList1.GetHead()->m_details.testName); - CHECK_EQUAL ("DefaultSuite", macroTestList1.GetHead()->m_details.suiteName); -} - -TestList macroTestList2; -TEST_FIXTURE_EX(DummyFixture, MacroTestHelper2, macroTestList2) -{ -} - -TEST(TestAddedWithTEST_FIXTURE_EXMacroGetsDefaultSuite) -{ - CHECK(macroTestList2.GetHead() != NULL); - CHECK_EQUAL ("MacroTestHelper2", macroTestList2.GetHead()->m_details.testName); - CHECK_EQUAL ("DefaultSuite", macroTestList2.GetHead()->m_details.suiteName); -} - -#ifndef UNITTEST_NO_EXCEPTIONS - -struct FixtureCtorThrows -{ - FixtureCtorThrows() { throw "exception"; } -}; - -TestList throwingFixtureTestList1; -TEST_FIXTURE_EX(FixtureCtorThrows, FixtureCtorThrowsTestName, throwingFixtureTestList1) -{ -} - -TEST(FixturesWithThrowingCtorsAreFailures) -{ - CHECK(throwingFixtureTestList1.GetHead() != NULL); - RecordingReporter reporter; - TestResults result(&reporter); - { - ScopedCurrentTest scopedResult(result); - throwingFixtureTestList1.GetHead()->Run(); - } - - int const failureCount = result.GetFailedTestCount(); - CHECK_EQUAL(1, failureCount); - CHECK(strstr(reporter.lastFailedMessage, "while constructing fixture")); -} - -struct FixtureDtorThrows -{ - ~FixtureDtorThrows() { throw "exception"; } -}; - -TestList throwingFixtureTestList2; -TEST_FIXTURE_EX(FixtureDtorThrows, FixtureDtorThrowsTestName, throwingFixtureTestList2) -{ -} - -TEST(FixturesWithThrowingDtorsAreFailures) -{ - CHECK(throwingFixtureTestList2.GetHead() != NULL); - - RecordingReporter reporter; - TestResults result(&reporter); - { - ScopedCurrentTest scopedResult(result); - throwingFixtureTestList2.GetHead()->Run(); - } - - int const failureCount = result.GetFailedTestCount(); - CHECK_EQUAL(1, failureCount); - CHECK(strstr(reporter.lastFailedMessage, "while destroying fixture")); -} - -const int FailingLine = 123; - -struct FixtureCtorAsserts -{ - FixtureCtorAsserts() - { - UnitTest::ReportAssert("assert failure", "file", FailingLine); - } -}; - -TestList ctorAssertFixtureTestList; -TEST_FIXTURE_EX(FixtureCtorAsserts, CorrectlyReportsAssertFailureInCtor, ctorAssertFixtureTestList) -{ -} - -TEST(CorrectlyReportsFixturesWithCtorsThatAssert) -{ - RecordingReporter reporter; - TestResults result(&reporter); - { - ScopedCurrentTest scopedResults(result); - ctorAssertFixtureTestList.GetHead()->Run(); - } - - const int failureCount = result.GetFailedTestCount(); - CHECK_EQUAL(1, failureCount); - CHECK_EQUAL(FailingLine, reporter.lastFailedLine); - CHECK(strstr(reporter.lastFailedMessage, "assert failure")); -} - -#endif - -} - -// We're really testing if it's possible to use the same suite in two files -// to compile and link successfuly (TestTestSuite.cpp has suite with the same name) -// Note: we are outside of the anonymous namespace -SUITE(SameTestSuite) -{ - TEST(DummyTest1) - { - } -} - -#define CUR_TEST_NAME CurrentTestDetailsContainCurrentTestInfo -#define INNER_STRINGIFY(X) #X -#define STRINGIFY(X) INNER_STRINGIFY(X) - -TEST(CUR_TEST_NAME) -{ - const UnitTest::TestDetails* details = CurrentTest::Details(); - CHECK_EQUAL(STRINGIFY(CUR_TEST_NAME), details->testName); -} - -#undef CUR_TEST_NAME -#undef INNER_STRINGIFY -#undef STRINGIFY diff --git a/src/tests/TestTestResults.cpp b/src/tests/TestTestResults.cpp deleted file mode 100644 index 15fff1e..0000000 --- a/src/tests/TestTestResults.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "../../unittestpp.h" -#include "../TestResults.h" -#include "RecordingReporter.h" - -using namespace UnitTest; - -namespace { - -TestDetails const details("testname", "suitename", "filename", 123); - - -TEST(StartsWithNoTestsRun) -{ - TestResults results; - CHECK_EQUAL (0, results.GetTotalTestCount()); -} - -TEST(RecordsNumbersOfTests) -{ - TestResults results; - results.OnTestStart(details); - results.OnTestStart(details); - results.OnTestStart(details); - CHECK_EQUAL(3, results.GetTotalTestCount()); -} - -TEST(StartsWithNoTestsFailing) -{ - TestResults results; - CHECK_EQUAL (0, results.GetFailureCount()); -} - -TEST(RecordsNumberOfFailures) -{ - TestResults results; - results.OnTestFailure(details, ""); - results.OnTestFailure(details, ""); - CHECK_EQUAL(2, results.GetFailureCount()); -} - -TEST(RecordsNumberOfFailedTests) -{ - TestResults results; - - results.OnTestStart(details); - results.OnTestFailure(details, ""); - results.OnTestFinish(details, 0); - - results.OnTestStart(details); - results.OnTestFailure(details, ""); - results.OnTestFailure(details, ""); - results.OnTestFailure(details, ""); - results.OnTestFinish(details, 0); - - CHECK_EQUAL (2, results.GetFailedTestCount()); -} - -TEST(NotifiesReporterOfTestStartWithCorrectInfo) -{ - RecordingReporter reporter; - TestResults results(&reporter); - results.OnTestStart(details); - - CHECK_EQUAL (1, reporter.testRunCount); - CHECK_EQUAL ("suitename", reporter.lastStartedSuite); - CHECK_EQUAL ("testname", reporter.lastStartedTest); -} - -TEST(NotifiesReporterOfTestFailureWithCorrectInfo) -{ - RecordingReporter reporter; - TestResults results(&reporter); - - results.OnTestFailure(details, "failurestring"); - CHECK_EQUAL (1, reporter.testFailedCount); - CHECK_EQUAL ("filename", reporter.lastFailedFile); - CHECK_EQUAL (123, reporter.lastFailedLine); - CHECK_EQUAL ("suitename", reporter.lastFailedSuite); - CHECK_EQUAL ("testname", reporter.lastFailedTest); - CHECK_EQUAL ("failurestring", reporter.lastFailedMessage); -} - -TEST(NotifiesReporterOfCheckFailureWithCorrectInfo) -{ - RecordingReporter reporter; - TestResults results(&reporter); - - results.OnTestFailure(details, "failurestring"); - CHECK_EQUAL (1, reporter.testFailedCount); - - CHECK_EQUAL ("filename", reporter.lastFailedFile); - CHECK_EQUAL (123, reporter.lastFailedLine); - CHECK_EQUAL ("testname", reporter.lastFailedTest); - CHECK_EQUAL ("suitename", reporter.lastFailedSuite); - CHECK_EQUAL ("failurestring", reporter.lastFailedMessage); -} - -TEST(NotifiesReporterOfTestEnd) -{ - RecordingReporter reporter; - TestResults results(&reporter); - - results.OnTestFinish(details, 0.1234f); - CHECK_EQUAL (1, reporter.testFinishedCount); - CHECK_EQUAL ("testname", reporter.lastFinishedTest); - CHECK_EQUAL ("suitename", reporter.lastFinishedSuite); - CHECK_CLOSE (0.1234f, reporter.lastFinishedTestTime, 0.0001f); -} - - -} diff --git a/src/tests/TestTestRunner.cpp b/src/tests/TestTestRunner.cpp deleted file mode 100644 index 0aeec11..0000000 --- a/src/tests/TestTestRunner.cpp +++ /dev/null @@ -1,322 +0,0 @@ -#include "../../unittestpp.h" -#include "RecordingReporter.h" -#include "../ReportAssert.h" -#include "../TestList.h" -#include "../TimeHelpers.h" -#include "../TimeConstraint.h" -#include "../ReportAssertImpl.h" - -using namespace UnitTest; - -namespace -{ - -struct TestRunnerFixture -{ - TestRunnerFixture() - : runner(reporter) - { - s_testRunnerFixtureTestResults = runner.GetTestResults(); - } - - static TestResults* s_testRunnerFixtureTestResults; - - RecordingReporter reporter; - TestList list; - TestRunner runner; -}; - -TestResults* TestRunnerFixture::s_testRunnerFixtureTestResults = NULL; - -struct MockTest : public Test -{ - MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1) - : Test(testName) - , success(success_) - , asserted(assert_) - , count(count_) - { - m_isMockTest = true; - } - - virtual void RunImpl() const - { - TestResults* testResults = TestRunnerFixture::s_testRunnerFixtureTestResults; - - for (int i=0; i < count; ++i) - { - if (asserted) - Detail::ReportAssertEx(testResults, &m_details, "desc", "file", 0); - else if (!success) - testResults->OnTestFailure(m_details, "message"); - } - } - - bool const success; - bool const asserted; - int const count; -}; - -TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly) -{ - MockTest test("goodtest", true, false); - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(1, reporter.testRunCount); - CHECK_EQUAL("goodtest", reporter.lastStartedTest); -} - -TEST_FIXTURE(TestRunnerFixture, TestFinishIsReportedCorrectly) -{ - MockTest test("goodtest", true, false); - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(1, reporter.testFinishedCount); - CHECK_EQUAL("goodtest", reporter.lastFinishedTest); -} - -class SlowTest : public Test -{ -public: - SlowTest() : Test("slow", "somesuite", "filename", 123) {} - virtual void RunImpl() const - { - TimeHelpers::SleepMs(20); - } -}; - -TEST_FIXTURE(TestRunnerFixture, TestFinishIsCalledWithCorrectTime) -{ - SlowTest test; - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK(reporter.lastFinishedTestTime >= 0.005f && reporter.lastFinishedTestTime <= 0.050f); -} - -TEST_FIXTURE(TestRunnerFixture, FailureCountIsZeroWhenNoTestsAreRun) -{ - CHECK_EQUAL(0, runner.RunTestsIf(list, NULL, True(), 0)); - CHECK_EQUAL(0, reporter.testRunCount); - CHECK_EQUAL(0, reporter.testFailedCount); -} - -TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest) -{ - MockTest test1("test", false, false); - list.Add(&test1); - MockTest test2("test", true, false); - list.Add(&test2); - MockTest test3("test", false, false); - list.Add(&test3); - - CHECK_EQUAL(2, runner.RunTestsIf(list, NULL, True(), 0)); - CHECK_EQUAL(2, reporter.testFailedCount); -} - -TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing) -{ - MockTest test("test", true, true); - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(1, reporter.testFailedCount); -} - -TEST_FIXTURE(TestRunnerFixture, AssertingTestAbortsAsSoonAsAssertIsHit) -{ - MockTest test("test", false, true, 3); - list.Add(&test); - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(1, reporter.summaryFailureCount); -} - -TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount) -{ - MockTest test1("test", true, false); - MockTest test2("test", true, false); - MockTest test3("test", true, false); - list.Add(&test1); - list.Add(&test2); - list.Add(&test3); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(3, reporter.summaryTotalTestCount); -} - -TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailedTests) -{ - MockTest test1("test", false, false, 2); - MockTest test2("test", true, false); - MockTest test3("test", false, false, 3); - list.Add(&test1); - list.Add(&test2); - list.Add(&test3); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(2, reporter.summaryFailedTestCount); -} - -TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailures) -{ - MockTest test1("test", false, false, 2); - MockTest test2("test", true, false); - MockTest test3("test", false, false, 3); - list.Add(&test1); - list.Add(&test2); - list.Add(&test3); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(5, reporter.summaryFailureCount); -} - -TEST_FIXTURE(TestRunnerFixture, SlowTestPassesForHighTimeThreshold) -{ - SlowTest test; - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(0, reporter.testFailedCount); -} - -TEST_FIXTURE(TestRunnerFixture, SlowTestFailsForLowTimeThreshold) -{ - SlowTest test; - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 3); - CHECK_EQUAL(1, reporter.testFailedCount); -} - -TEST_FIXTURE(TestRunnerFixture, SlowTestHasCorrectFailureInformation) -{ - SlowTest test; - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 3); - - using namespace std; - - CHECK_EQUAL(test.m_details.testName, reporter.lastFailedTest); - CHECK(strstr(test.m_details.filename, reporter.lastFailedFile)); - CHECK_EQUAL(test.m_details.lineNumber, reporter.lastFailedLine); - - CHECK(strstr(reporter.lastFailedMessage, "Global time constraint failed")); - CHECK(strstr(reporter.lastFailedMessage, "3ms")); -} - -TEST_FIXTURE(TestRunnerFixture, SlowTestWithTimeExemptionPasses) -{ - class SlowExemptedTest : public Test - { - public: - SlowExemptedTest() : Test("slowexempted", "", 0) {} - virtual void RunImpl() const - { - UNITTEST_TIME_CONSTRAINT_EXEMPT(); - TimeHelpers::SleepMs(20); - } - }; - - SlowExemptedTest test; - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 3); - CHECK_EQUAL(0, reporter.testFailedCount); -} - -struct TestSuiteFixture -{ - TestSuiteFixture() - : test1("TestInDefaultSuite") - , test2("TestInOtherSuite", "OtherSuite") - , test3("SecondTestInDefaultSuite") - , runner(reporter) - { - list.Add(&test1); - list.Add(&test2); - } - - Test test1; - Test test2; - Test test3; - RecordingReporter reporter; - TestList list; - TestRunner runner; -}; - -TEST_FIXTURE(TestSuiteFixture, TestRunnerRunsAllSuitesIfNullSuiteIsPassed) -{ - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(2, reporter.summaryTotalTestCount); -} - -TEST_FIXTURE(TestSuiteFixture,TestRunnerRunsOnlySpecifiedSuite) -{ - runner.RunTestsIf(list, "OtherSuite", True(), 0); - CHECK_EQUAL(1, reporter.summaryTotalTestCount); - CHECK_EQUAL("TestInOtherSuite", reporter.lastFinishedTest); -} - -struct RunTestIfNameIs -{ - RunTestIfNameIs(char const* name_) - : name(name_) - { - } - - bool operator()(const Test* const test) const - { - using namespace std; - return (0 == strcmp(test->m_details.testName, name)); - } - - char const* name; -}; - -TEST(TestMockPredicateBehavesCorrectly) -{ - RunTestIfNameIs predicate("pass"); - - Test pass("pass"); - Test fail("fail"); - - CHECK(predicate(&pass)); - CHECK(!predicate(&fail)); -} - -TEST_FIXTURE(TestRunnerFixture, TestRunnerRunsTestsThatPassPredicate) -{ - Test should_run("goodtest"); - list.Add(&should_run); - - Test should_not_run("badtest"); - list.Add(&should_not_run); - - runner.RunTestsIf(list, NULL, RunTestIfNameIs("goodtest"), 0); - CHECK_EQUAL(1, reporter.testRunCount); - CHECK_EQUAL("goodtest", reporter.lastStartedTest); -} - -TEST_FIXTURE(TestRunnerFixture, TestRunnerOnlyRunsTestsInSpecifiedSuiteAndThatPassPredicate) -{ - Test runningTest1("goodtest", "suite"); - Test skippedTest2("goodtest"); - Test skippedTest3("badtest", "suite"); - Test skippedTest4("badtest"); - - list.Add(&runningTest1); - list.Add(&skippedTest2); - list.Add(&skippedTest3); - list.Add(&skippedTest4); - - runner.RunTestsIf(list, "suite", RunTestIfNameIs("goodtest"), 0); - - CHECK_EQUAL(1, reporter.testRunCount); - CHECK_EQUAL("goodtest", reporter.lastStartedTest); - CHECK_EQUAL("suite", reporter.lastStartedSuite); -} - -} diff --git a/src/tests/TestTimeConstraint.cpp b/src/tests/TestTimeConstraint.cpp deleted file mode 100644 index 96f880c..0000000 --- a/src/tests/TestTimeConstraint.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "../../unittestpp.h" -#include "../TestResults.h" -#include "../TimeHelpers.h" -#include "RecordingReporter.h" -#include "ScopedCurrentTest.h" - -using namespace UnitTest; - -namespace -{ - -TEST(TimeConstraintSucceedsWithFastTest) -{ - TestResults result; - { - ScopedCurrentTest scopedResult(result); - TimeConstraint t(200, TestDetails("", "", "", 0)); - TimeHelpers::SleepMs(5); - } - CHECK_EQUAL(0, result.GetFailureCount()); -} - -TEST(TimeConstraintFailsWithSlowTest) -{ - TestResults result; - { - ScopedCurrentTest scopedResult(result); - TimeConstraint t(10, TestDetails("", "", "", 0)); - TimeHelpers::SleepMs(20); - } - CHECK_EQUAL(1, result.GetFailureCount()); -} - -TEST(TimeConstraintFailureIncludesCorrectData) -{ - RecordingReporter reporter; - TestResults result(&reporter); - { - ScopedCurrentTest scopedResult(result); - - TestDetails const details("testname", "suitename", "filename", 10); - TimeConstraint t(10, details); - TimeHelpers::SleepMs(20); - } - - using namespace std; - - CHECK(strstr(reporter.lastFailedFile, "filename")); - CHECK_EQUAL(10, reporter.lastFailedLine); - CHECK(strstr(reporter.lastFailedTest, "testname")); -} - -TEST(TimeConstraintFailureIncludesTimeoutInformation) -{ - RecordingReporter reporter; - TestResults result(&reporter); - { - ScopedCurrentTest scopedResult(result); - TimeConstraint t(10, TestDetails("", "", "", 0)); - TimeHelpers::SleepMs(20); - } - - using namespace std; - - CHECK(strstr(reporter.lastFailedMessage, "ime constraint")); - CHECK(strstr(reporter.lastFailedMessage, "under 10ms")); -} - -} diff --git a/src/tests/TestTimeConstraintMacro.cpp b/src/tests/TestTimeConstraintMacro.cpp deleted file mode 100644 index 76f15c3..0000000 --- a/src/tests/TestTimeConstraintMacro.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "../../unittestpp.h" -#include "../TimeHelpers.h" - -#include "RecordingReporter.h" -#include "ScopedCurrentTest.h" - -namespace { - -TEST(TimeConstraintMacroQualifiesNamespace) -{ - // If this compiles without a "using namespace UnitTest;", all is well. - UNITTEST_TIME_CONSTRAINT(1); -} - -TEST(TimeConstraintMacroUsesCorrectInfo) -{ - int testLine = 0; - RecordingReporter reporter; - - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - UNITTEST_TIME_CONSTRAINT(10); testLine = __LINE__; - UnitTest::TimeHelpers::SleepMs(20); - } - - using namespace std; - - CHECK_EQUAL(1, reporter.testFailedCount); - CHECK(strstr(reporter.lastFailedFile, __FILE__)); - CHECK_EQUAL(testLine, reporter.lastFailedLine); - CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroUsesCorrectInfo")); -} - -TEST(TimeConstraintMacroComparesAgainstPreciseActual) -{ - int testLine = 0; - RecordingReporter reporter; - - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - UNITTEST_TIME_CONSTRAINT(1); testLine = __LINE__; - - // start a new timer and run until we're as little over the 1 msec - // threshold as we can achieve; this should guarantee that the "test" - // runs in some very small amount of time > 1 msec - UnitTest::Timer myTimer; - myTimer.Start(); - - while (myTimer.GetTimeInMs() < 1.001) - UnitTest::TimeHelpers::SleepMs(0); - } - - using namespace std; - - CHECK_EQUAL(1, reporter.testFailedCount); - CHECK(strstr(reporter.lastFailedFile, __FILE__)); - CHECK_EQUAL(testLine, reporter.lastFailedLine); - CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroComparesAgainstPreciseActual")); -} - -} diff --git a/src/tests/TestUnitTestPP.cpp b/src/tests/TestUnitTestPP.cpp deleted file mode 100644 index e6a00bf..0000000 --- a/src/tests/TestUnitTestPP.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include "../../unittestpp.h" -#include "ScopedCurrentTest.h" - -// These are sample tests that show the different features of the framework - -namespace { - -TEST(ValidCheckSucceeds) -{ - bool const b = true; - CHECK(b); -} - -TEST(CheckWorksWithPointers) -{ - void* p = (void *)0x100; - CHECK(p); - CHECK(p != 0); -} - -TEST(ValidCheckEqualSucceeds) -{ - int const x = 3; - int const y = 3; - CHECK_EQUAL(x, y); -} - -TEST(CheckEqualWorksWithPointers) -{ - void* p = (void *)0; - CHECK_EQUAL((void*)0, p); -} - -TEST(ValidCheckCloseSucceeds) -{ - CHECK_CLOSE(2.0f, 2.001f, 0.01f); - CHECK_CLOSE(2.001f, 2.0f, 0.01f); -} - -TEST(ArrayCloseSucceeds) -{ - float const a1[] = {1, 2, 3}; - float const a2[] = {1, 2.01f, 3}; - CHECK_ARRAY_CLOSE(a1, a2, 3, 0.1f); -} - -#ifndef UNITTEST_NO_EXCEPTIONS - -TEST(CheckThrowMacroSucceedsOnCorrectException) -{ - struct TestException {}; - CHECK_THROW(throw TestException(), TestException); -} - -TEST(CheckAssertSucceeds) -{ - CHECK_ASSERT(UnitTest::ReportAssert("desc", "file", 0)); -} - -TEST(CheckThrowMacroFailsOnMissingException) -{ - class NoThrowTest : public UnitTest::Test - { - public: - NoThrowTest() : Test("nothrow") {} - void DontThrow() const - { - } - - virtual void RunImpl() const - { - CHECK_THROW(DontThrow(), int); - } - }; - - UnitTest::TestResults results; - { - ScopedCurrentTest scopedResults(results); - - NoThrowTest test; - test.Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckThrowMacroFailsOnWrongException) -{ - class WrongThrowTest : public UnitTest::Test - { - public: - WrongThrowTest() : Test("wrongthrow") {} - virtual void RunImpl() const - { - CHECK_THROW(throw "oops", int); - } - }; - - UnitTest::TestResults results; - { - ScopedCurrentTest scopedResults(results); - - WrongThrowTest test; - test.Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} - -#endif - -struct SimpleFixture -{ - SimpleFixture() - { - ++instanceCount; - } - ~SimpleFixture() - { - --instanceCount; - } - - static int instanceCount; -}; - -int SimpleFixture::instanceCount = 0; - -TEST_FIXTURE(SimpleFixture, DefaultFixtureCtorIsCalled) -{ - CHECK(SimpleFixture::instanceCount > 0); -} - -TEST_FIXTURE(SimpleFixture, OnlyOneFixtureAliveAtATime) -{ - CHECK_EQUAL(1, SimpleFixture::instanceCount); -} - -void CheckBool(const bool b) -{ - CHECK(b); -} - -TEST(CanCallCHECKOutsideOfTestFunction) -{ - CheckBool(true); -} - -} diff --git a/src/tests/TestXmlTestReporter.cpp b/src/tests/TestXmlTestReporter.cpp deleted file mode 100644 index dde5759..0000000 --- a/src/tests/TestXmlTestReporter.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include "../../config.h" -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "../../unittestpp.h" -#include "../XmlTestReporter.h" - -#include - -using namespace UnitTest; -using std::ostringstream; - -namespace -{ - -#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - -// Overload to let MemoryOutStream accept std::string -MemoryOutStream& operator<<(MemoryOutStream& s, const std::string& value) -{ - s << value.c_str(); - return s; -} - -#endif - -struct XmlTestReporterFixture -{ - XmlTestReporterFixture() - : reporter(output) - { - } - - ostringstream output; - XmlTestReporter reporter; -}; - -TEST_FIXTURE(XmlTestReporterFixture, MultipleCharactersAreEscaped) -{ - TestDetails const details("TestName", "suite", "filename.h", 4321); - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, "\"\"\'\'&&<<>>"); - reporter.ReportTestFinish(details, 0.1f); - reporter.ReportSummary(1, 2, 3, 0.1f); - - char const* expected = - "" - "" - "" - "" - "" - ""; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, OutputIsCachedUntilReportSummaryIsCalled) -{ - TestDetails const details("", "", "", 0); - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, "message"); - reporter.ReportTestFinish(details, 1.0F); - CHECK(output.str().empty()); - - reporter.ReportSummary(1, 1, 1, 1.0f); - CHECK(!output.str().empty()); -} - -TEST_FIXTURE(XmlTestReporterFixture, EmptyReportSummaryFormat) -{ - reporter.ReportSummary(0, 0, 0, 0.1f); - - const char *expected = - "" - "" - ""; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, SingleSuccessfulTestReportSummaryFormat) -{ - TestDetails const details("TestName", "DefaultSuite", "", 0); - - reporter.ReportTestStart(details); - reporter.ReportSummary(1, 0, 0, 0.1f); - - const char *expected = - "" - "" - "" - ""; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, SingleFailedTestReportSummaryFormat) -{ - TestDetails const details("A Test", "suite", "A File", 4321); - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, "A Failure"); - reporter.ReportSummary(1, 1, 1, 0.1f); - - const char *expected = - "" - "" - "" - "" - "" - ""; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, FailureMessageIsXMLEscaped) -{ - TestDetails const details("TestName", "suite", "filename.h", 4321); - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, "\"\'&<>"); - reporter.ReportTestFinish(details, 0.1f); - reporter.ReportSummary(1, 1, 1, 0.1f); - - char const* expected = - "" - "" - "" - "" - "" - ""; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, OneFailureAndOneSuccess) -{ - TestDetails const failedDetails("FailedTest", "suite", "fail.h", 1); - reporter.ReportTestStart(failedDetails); - reporter.ReportFailure(failedDetails, "expected 1 but was 2"); - reporter.ReportTestFinish(failedDetails, 0.1f); - - TestDetails const succeededDetails("SucceededTest", "suite", "", 0); - reporter.ReportTestStart(succeededDetails); - reporter.ReportTestFinish(succeededDetails, 1.0f); - reporter.ReportSummary(2, 1, 1, 1.1f); - - char const* expected = - "" - "" - "" - "" - "" - "" - ""; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, MultipleFailures) -{ - TestDetails const failedDetails1("FailedTest", "suite", "fail.h", 1); - TestDetails const failedDetails2("FailedTest", "suite", "fail.h", 31); - - reporter.ReportTestStart(failedDetails1); - reporter.ReportFailure(failedDetails1, "expected 1 but was 2"); - reporter.ReportFailure(failedDetails2, "expected one but was two"); - reporter.ReportTestFinish(failedDetails1, 0.1f); - - reporter.ReportSummary(1, 1, 2, 1.1f); - - char const* expected = - "" - "" - "" - "" - "" - "" - ""; - - CHECK_EQUAL(expected, output.str()); -} - -} - -#endif diff --git a/src/tests/test-unittestpp_vs2005.vcproj b/src/tests/test-unittestpp_vs2005.vcproj deleted file mode 100644 index 50d9fa3..0000000 --- a/src/tests/test-unittestpp_vs2005.vcproj +++ /dev/null @@ -1,580 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tests/test-unittestpp_vs2008.vcproj b/src/tests/test-unittestpp_vs2008.vcproj deleted file mode 100644 index e6cfbee..0000000 --- a/src/tests/test-unittestpp_vs2008.vcproj +++ /dev/null @@ -1,569 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/unittestpp_vs2005.vcproj b/src/unittestpp_vs2005.vcproj deleted file mode 100644 index b69882c..0000000 --- a/src/unittestpp_vs2005.vcproj +++ /dev/null @@ -1,614 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/unittestpp_vs2008.vcproj b/src/unittestpp_vs2008.vcproj deleted file mode 100644 index b695cab..0000000 --- a/src/unittestpp_vs2008.vcproj +++ /dev/null @@ -1,607 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/Main.cpp b/tests/Main.cpp new file mode 100644 index 0000000..4a0f402 --- /dev/null +++ b/tests/Main.cpp @@ -0,0 +1,6 @@ +#include "UnitTest++/UnitTestPP.h" + +int main(int, char const *[]) +{ + return UnitTest::RunAllTests(); +} diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..06cc26c --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,5 @@ +check_PROGRAMS = UnitTest++/TestUnitTest++ + +UnitTest___TestUnitTest___SOURCES = tests/Main.cpp tests/TestAssertHandler.cpp tests/TestCheckMacros.cpp tests/TestChecks.cpp tests/TestCompositeTestReporter.cpp tests/TestCurrentTest.cpp tests/TestDeferredTestReporter.cpp tests/TestExceptions.cpp tests/TestMemoryOutStream.cpp tests/TestRequireMacrosWithExceptionsOff.cpp tests/TestRequireMacrosWithExceptionsOn.cpp tests/TestTest.cpp tests/TestTestList.cpp tests/TestTestMacros.cpp tests/TestTestResults.cpp tests/TestTestRunner.cpp tests/TestTestSuite.cpp tests/TestTimeConstraint.cpp tests/TestTimeConstraintMacro.cpp tests/TestUnitTestPP.cpp tests/TestXmlTestReporter.cpp tests/RecordingReporter.h tests/ScopedCurrentTest.h +UnitTest___TestUnitTest___LDADD = UnitTest++/libUnitTest++.la +TESTS = UnitTest++/TestUnitTest++ diff --git a/tests/RecordingReporter.h b/tests/RecordingReporter.h new file mode 100644 index 0000000..a2e4839 --- /dev/null +++ b/tests/RecordingReporter.h @@ -0,0 +1,98 @@ +#ifndef UNITTEST_RECORDINGREPORTER_H +#define UNITTEST_RECORDINGREPORTER_H + +#include "UnitTest++/TestReporter.h" +#include + +#include "UnitTest++/TestDetails.h" + +struct RecordingReporter : public UnitTest::TestReporter +{ +private: + enum { kMaxStringLength = 256 }; + +public: + RecordingReporter() + : testRunCount(0) + , testFailedCount(0) + , lastFailedLine(0) + , testFinishedCount(0) + , lastFinishedTestTime(0) + , summaryTotalTestCount(0) + , summaryFailedTestCount(0) + , summaryFailureCount(0) + , summarySecondsElapsed(0) + { + lastStartedSuite[0] = '\0'; + lastStartedTest[0] = '\0'; + lastFailedFile[0] = '\0'; + lastFailedSuite[0] = '\0'; + lastFailedTest[0] = '\0'; + lastFailedMessage[0] = '\0'; + lastFinishedSuite[0] = '\0'; + lastFinishedTest[0] = '\0'; + } + + virtual void ReportTestStart(UnitTest::TestDetails const& test) + { + using namespace std; + + ++testRunCount; + strcpy(lastStartedSuite, test.suiteName); + strcpy(lastStartedTest, test.testName); + } + + virtual void ReportFailure(UnitTest::TestDetails const& test, char const* failure) + { + using namespace std; + + ++testFailedCount; + strcpy(lastFailedFile, test.filename); + lastFailedLine = test.lineNumber; + strcpy(lastFailedSuite, test.suiteName); + strcpy(lastFailedTest, test.testName); + strcpy(lastFailedMessage, failure); + } + + virtual void ReportTestFinish(UnitTest::TestDetails const& test, float testDuration) + { + using namespace std; + + ++testFinishedCount; + strcpy(lastFinishedSuite, test.suiteName); + strcpy(lastFinishedTest, test.testName); + lastFinishedTestTime = testDuration; + } + + virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) + { + summaryTotalTestCount = totalTestCount; + summaryFailedTestCount = failedTestCount; + summaryFailureCount = failureCount; + summarySecondsElapsed = secondsElapsed; + } + + int testRunCount; + char lastStartedSuite[kMaxStringLength]; + char lastStartedTest[kMaxStringLength]; + + int testFailedCount; + char lastFailedFile[kMaxStringLength]; + int lastFailedLine; + char lastFailedSuite[kMaxStringLength]; + char lastFailedTest[kMaxStringLength]; + char lastFailedMessage[kMaxStringLength]; + + int testFinishedCount; + char lastFinishedSuite[kMaxStringLength]; + char lastFinishedTest[kMaxStringLength]; + float lastFinishedTestTime; + + int summaryTotalTestCount; + int summaryFailedTestCount; + int summaryFailureCount; + float summarySecondsElapsed; +}; + + +#endif diff --git a/tests/ScopedCurrentTest.h b/tests/ScopedCurrentTest.h new file mode 100644 index 0000000..4070252 --- /dev/null +++ b/tests/ScopedCurrentTest.h @@ -0,0 +1,38 @@ +#ifndef UNITTEST_SCOPEDCURRENTTEST_H +#define UNITTEST_SCOPEDCURRENTTEST_H + +#include "UnitTest++/CurrentTest.h" +#include + +class ScopedCurrentTest +{ +public: + ScopedCurrentTest() + : m_oldTestResults(UnitTest::CurrentTest::Results()) + , m_oldTestDetails(UnitTest::CurrentTest::Details()) + {} + + explicit ScopedCurrentTest(UnitTest::TestResults& newResults, const UnitTest::TestDetails* newDetails = NULL) + : m_oldTestResults(UnitTest::CurrentTest::Results()) + , m_oldTestDetails(UnitTest::CurrentTest::Details()) + { + UnitTest::CurrentTest::Results() = &newResults; + + if (newDetails != NULL) + { + UnitTest::CurrentTest::Details() = newDetails; + } + } + + ~ScopedCurrentTest() + { + UnitTest::CurrentTest::Results() = m_oldTestResults; + UnitTest::CurrentTest::Details() = m_oldTestDetails; + } + +private: + UnitTest::TestResults* m_oldTestResults; + const UnitTest::TestDetails* m_oldTestDetails; +}; + +#endif diff --git a/tests/TestAssertHandler.cpp b/tests/TestAssertHandler.cpp new file mode 100644 index 0000000..4c7f2b5 --- /dev/null +++ b/tests/TestAssertHandler.cpp @@ -0,0 +1,133 @@ +#include "UnitTest++/Config.h" +#include "UnitTest++/UnitTestPP.h" + +#include "UnitTest++/ReportAssert.h" +#include "UnitTest++/ReportAssertImpl.h" +#include "UnitTest++/AssertException.h" + +#include "RecordingReporter.h" +#include + +using namespace UnitTest; + +namespace { + + TEST(CanSetAssertExpected) + { + Detail::ExpectAssert(true); + CHECK(Detail::AssertExpected()); + + Detail::ExpectAssert(false); + CHECK(!Detail::AssertExpected()); + } + +#ifndef UNITTEST_NO_EXCEPTIONS + + TEST(ReportAssertThrowsAssertException) + { + bool caught = false; + + try + { + TestResults testResults; + TestDetails testDetails("", "", "", 0); + Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0); + } + catch(AssertException const&) + { + caught = true; + } + + CHECK(true == caught); + } + + TEST(ReportAssertClearsExpectAssertFlag) + { + RecordingReporter reporter; + TestResults testResults(&reporter); + TestDetails testDetails("", "", "", 0); + + try + { + Detail::ExpectAssert(true); + Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0); + } + catch(AssertException const&) + {} + + CHECK(Detail::AssertExpected() == false); + CHECK_EQUAL(0, reporter.testFailedCount); + } + + TEST(ReportAssertWritesFailureToResultsAndDetailsWhenAssertIsNotExpected) + { + const int lineNumber = 12345; + const char* description = "description"; + const char* filename = "filename"; + + RecordingReporter reporter; + TestResults testResults(&reporter); + TestDetails testDetails("", "", "", 0); + + try + { + Detail::ReportAssertEx(&testResults, &testDetails, description, filename, lineNumber); + } + catch(AssertException const&) + {} + + CHECK_EQUAL(description, reporter.lastFailedMessage); + CHECK_EQUAL(filename, reporter.lastFailedFile); + CHECK_EQUAL(lineNumber, reporter.lastFailedLine); + } + + TEST(ReportAssertReportsNoErrorsWhenAssertIsExpected) + { + Detail::ExpectAssert(true); + + RecordingReporter reporter; + TestResults testResults(&reporter); + TestDetails testDetails("", "", "", 0); + + try + { + Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0); + } + catch(AssertException const&) + {} + + CHECK_EQUAL(0, reporter.testFailedCount); + } + + TEST(CheckAssertMacroSetsAssertExpectationToFalseAfterRunning) + { + Detail::ExpectAssert(true); + CHECK_ASSERT(ReportAssert("", "", 0)); + CHECK(!Detail::AssertExpected()); + Detail::ExpectAssert(false); + } + +#else + + TEST(SetAssertJumpTargetReturnsFalseWhenSettingJumpTarget) + { + CHECK(UNITTEST_SET_ASSERT_JUMP_TARGET() == false); + } + + TEST(JumpToAssertJumpTarget_JumpsToSetPoint_ReturnsTrue) + { + const volatile bool taken = !!UNITTEST_SET_ASSERT_JUMP_TARGET(); + + volatile bool set = false; + if (taken == false) + { + UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET(); + set = true; + } + + CHECK(set == false); + } + +#endif + +} diff --git a/tests/TestCheckMacros.cpp b/tests/TestCheckMacros.cpp new file mode 100644 index 0000000..f9c46c4 --- /dev/null +++ b/tests/TestCheckMacros.cpp @@ -0,0 +1,518 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/CurrentTest.h" +#include "RecordingReporter.h" +#include "ScopedCurrentTest.h" + +using namespace std; + +namespace { + + TEST(CheckSucceedsOnTrue) + { + bool failure = true; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + + ScopedCurrentTest scopedResults(testResults); + CHECK(true); + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + } + + TEST(CheckFailsOnFalse) + { + bool failure = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + CHECK(false); + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + } + + TEST(FailureReportsCorrectTestName) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + CHECK(false); + } + + CHECK_EQUAL(m_details.testName, reporter.lastFailedTest); + } + + TEST(CheckFailureIncludesCheckContents) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + const bool yaddayadda = false; + CHECK(yaddayadda); + } + + CHECK(strstr(reporter.lastFailedMessage, "yaddayadda")); + } + + TEST(CheckEqualSucceedsOnEqual) + { + bool failure = true; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + CHECK_EQUAL(1, 1); + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + } + + TEST(CheckEqualFailsOnNotEqual) + { + bool failure = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + CHECK_EQUAL(1, 2); + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + } + + TEST(CheckEqualFailureContainsCorrectDetails) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + CHECK_EQUAL(1, 123); line = __LINE__; + } + + CHECK_EQUAL("testName", reporter.lastFailedTest); + CHECK_EQUAL("suiteName", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + int g_sideEffect = 0; + int FunctionWithSideEffects() + { + ++g_sideEffect; + return 1; + } + + TEST(CheckEqualDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + CHECK_EQUAL(1, FunctionWithSideEffects()); + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(CheckEqualDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + CHECK_EQUAL(2, FunctionWithSideEffects()); + } + CHECK_EQUAL(1, g_sideEffect); + } + + + TEST(CheckCloseSucceedsOnEqual) + { + bool failure = true; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + CHECK_CLOSE (1.0f, 1.001f, 0.01f); + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + } + + TEST(CheckCloseFailsOnNotEqual) + { + bool failure = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + CHECK_CLOSE (1.0f, 1.1f, 0.01f); + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + } + + TEST(CheckCloseFailureContainsCorrectDetails) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails testDetails("test", "suite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + CHECK_CLOSE (1.0f, 1.1f, 0.01f); line = __LINE__; + } + + CHECK_EQUAL("test", reporter.lastFailedTest); + CHECK_EQUAL("suite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST(CheckCloseDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + CHECK_CLOSE (1, FunctionWithSideEffects(), 0.1f); + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(CheckCloseDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + CHECK_CLOSE (2, FunctionWithSideEffects(), 0.1f); + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(CheckArrayCloseSucceedsOnEqual) + { + bool failure = true; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + const float data[4] = { 0, 1, 2, 3 }; + CHECK_ARRAY_CLOSE (data, data, 4, 0.01f); + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + } + + TEST(CheckArrayCloseFailsOnNotEqual) + { + bool failure = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + } + + TEST(CheckArrayCloseFailureIncludesCheckExpectedAndActual) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); + } + + CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); + CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); + } + + TEST(CheckArrayCloseFailureContainsCorrectDetails) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); line = __LINE__; + } + + CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST(CheckArrayCloseFailureIncludesTolerance) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + float const data1[4] = { 0, 1, 2, 3 }; + float const data2[4] = { 0, 1, 3, 3 }; + CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); + } + + CHECK(strstr(reporter.lastFailedMessage, "0.01")); + } + + TEST(CheckArrayEqualSuceedsOnEqual) + { + bool failure = true; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + const float data[4] = { 0, 1, 2, 3 }; + CHECK_ARRAY_EQUAL (data, data, 4); + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + } + + TEST(CheckArrayEqualFailsOnNotEqual) + { + bool failure = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + CHECK_ARRAY_EQUAL (data1, data2, 4); + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + } + + TEST(CheckArrayEqualFailureIncludesCheckExpectedAndActual) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + CHECK_ARRAY_EQUAL (data1, data2, 4); + } + + CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); + CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); + } + + TEST(CheckArrayEqualFailureContainsCorrectInfo) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + CHECK_ARRAY_EQUAL (data1, data2, 4); line = __LINE__; + } + + CHECK_EQUAL("CheckArrayEqualFailureContainsCorrectInfo", reporter.lastFailedTest); + CHECK_EQUAL(__FILE__, reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + float const* FunctionWithSideEffects2() + { + ++g_sideEffect; + static float const data[] = {1,2,3,4}; + return data; + } + + TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[] = { 0, 1, 2, 3 }; + CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[] = { 0, 1, 3, 3 }; + CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); + } + + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(CheckArray2DCloseSucceedsOnEqual) + { + bool failure = true; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + const float data[2][2] = { {0, 1}, {2, 3} }; + CHECK_ARRAY2D_CLOSE (data, data, 2, 2, 0.01f); + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + } + + TEST(CheckArray2DCloseFailsOnNotEqual) + { + bool failure = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[2][2] = { {0, 1}, {2, 3} }; + int const data2[2][2] = { {0, 1}, {3, 3} }; + CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + } + + TEST(CheckArray2DCloseFailureIncludesCheckExpectedAndActual) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[2][2] = { {0, 1}, {2, 3} }; + int const data2[2][2] = { {0, 1}, {3, 3} }; + + CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + } + + CHECK(strstr(reporter.lastFailedMessage, "xpected [ [ 0 1 ] [ 2 3 ] ]")); + CHECK(strstr(reporter.lastFailedMessage, "was [ [ 0 1 ] [ 3 3 ] ]")); + } + + TEST(CheckArray2DCloseFailureContainsCorrectDetails) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + int const data1[2][2] = { {0, 1}, {2, 3} }; + int const data2[2][2] = { {0, 1}, {3, 3} }; + CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); line = __LINE__; + } + + CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST(CheckArray2DCloseFailureIncludesTolerance) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + float const data1[2][2] = { {0, 1}, {2, 3} }; + float const data2[2][2] = { {0, 1}, {3, 3} }; + CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + } + + CHECK(strstr(reporter.lastFailedMessage, "0.01")); + } + + float const* const* FunctionWithSideEffects3() + { + ++g_sideEffect; + static float const data1[] = {0,1}; + static float const data2[] = {2,3}; + static const float* const data[] = {data1, data2}; + return data; + } + + TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[2][2] = { {0, 1}, {2, 3} }; + CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[2][2] = { {0, 1}, {3, 3} }; + CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); + } + CHECK_EQUAL(1, g_sideEffect); + } + +} diff --git a/tests/TestChecks.cpp b/tests/TestChecks.cpp new file mode 100644 index 0000000..2c0ac04 --- /dev/null +++ b/tests/TestChecks.cpp @@ -0,0 +1,346 @@ +#include "UnitTest++/UnitTestPP.h" +#include "RecordingReporter.h" + +#include + +using namespace UnitTest; + + +namespace { + + + TEST(CheckEqualWithUnsignedLong) + { + TestResults results; + unsigned long something = 2; + CHECK_EQUAL(something, something); + } + + TEST(CheckEqualsWithStringsFailsOnDifferentStrings) + { + char txt1[] = "Hello"; + char txt2[] = "Hallo"; + TestResults results; + CheckEqual(results, txt1, txt2, TestDetails("", "", "", 0)); + CHECK_EQUAL(1, results.GetFailureCount()); + } + + char txt1[] = "Hello"; // non-const on purpose so no folding of duplicate data + char txt2[] = "Hello"; + + TEST(CheckEqualsWithStringsWorksOnContentsNonConstNonConst) + { + char const* const p1 = txt1; + char const* const p2 = txt2; + TestResults results; + CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckEqualsWithStringsWorksOnContentsConstConst) + { + char* const p1 = txt1; + char* const p2 = txt2; + TestResults results; + CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckEqualsWithStringsWorksOnContentsNonConstConst) + { + char* const p1 = txt1; + char const* const p2 = txt2; + TestResults results; + CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckEqualsWithStringsWorksOnContentsConstNonConst) + { + char const* const p1 = txt1; + char* const p2 = txt2; + TestResults results; + CheckEqual(results, p1, p2, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckEqualsWithStringsWorksOnContentsWithALiteral) + { + char const* const p1 = txt1; + TestResults results; + CheckEqual(results, "Hello", p1, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckEqualsWithStringsWorksOnNullExpected) + { + char const* const expected = "hi"; + char const* const actual = NULL; + TestResults results; + CheckEqual(results, expected, actual, TestDetails("", "", "", 0)); + CHECK_EQUAL (1, results.GetFailureCount()); + } + + TEST(CheckEqualsWithStringsWorksOnNullActual) + { + char const* const expected = NULL; + char const* const actual = "hi"; + TestResults results; + CheckEqual(results, expected, actual, TestDetails("", "", "", 0)); + CHECK_EQUAL (1, results.GetFailureCount()); + } + + TEST(CheckEqualsWithStringsWorksOnNullExpectedAndActual) + { + char const* const expected = NULL; + char const* const actual = NULL; + TestResults results; + CheckEqual(results, expected, actual, TestDetails("", "", "", 0)); + CHECK_EQUAL (0, results.GetFailureCount()); + } + + TEST(CheckEqualFailureIncludesCheckExpectedAndActual) + { + RecordingReporter reporter; + TestResults results(&reporter); + const int something = 2; + CheckEqual(results, 1, something, TestDetails("", "", "", 0)); + + using namespace std; + CHECK(strstr(reporter.lastFailedMessage, "xpected 1")); + CHECK(strstr(reporter.lastFailedMessage, "was 2")); + } + + TEST(CheckEqualFailureIncludesDetails) + { + RecordingReporter reporter; + TestResults results(&reporter); + TestDetails const details("mytest", "mysuite", "file.h", 101); + + CheckEqual(results, 1, 2, details); + + CHECK_EQUAL("mytest", reporter.lastFailedTest); + CHECK_EQUAL("mysuite", reporter.lastFailedSuite); + CHECK_EQUAL("file.h", reporter.lastFailedFile); + CHECK_EQUAL(101, reporter.lastFailedLine); + } + + TEST(CheckCloseTrue) + { + TestResults results; + CheckClose(results, 3.001f, 3.0f, 0.1f, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckCloseFalse) + { + TestResults results; + CheckClose(results, 3.12f, 3.0f, 0.1f, TestDetails("", "", "", 0)); + CHECK_EQUAL(1, results.GetFailureCount()); + } + + TEST(CheckCloseWithZeroEpsilonWorksForSameNumber) + { + TestResults results; + CheckClose(results, 0.1f, 0.1f, 0, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckCloseWithNaNFails) + { + const unsigned int bitpattern = 0xFFFFFFFF; + float nan; + UNIITEST_NS_QUAL_STD(memcpy)(&nan, &bitpattern, sizeof(bitpattern)); + + TestResults results; + CheckClose(results, 3.0f, nan, 0.1f, TestDetails("", "", "", 0)); + CHECK_EQUAL(1, results.GetFailureCount()); + } + + TEST(CheckCloseWithNaNAgainstItselfFails) + { + const unsigned int bitpattern = 0xFFFFFFFF; + float nan; + UNIITEST_NS_QUAL_STD(memcpy)(&nan, &bitpattern, sizeof(bitpattern)); + + TestResults results; + CheckClose(results, nan, nan, 0.1f, TestDetails("", "", "", 0)); + CHECK_EQUAL(1, results.GetFailureCount()); + } + + TEST(CheckCloseFailureIncludesCheckExpectedAndActual) + { + RecordingReporter reporter; + TestResults results(&reporter); + const float expected = 0.9f; + const float actual = 1.1f; + CheckClose(results, expected, actual, 0.01f, TestDetails("", "", "", 0)); + + using namespace std; + CHECK(strstr(reporter.lastFailedMessage, "xpected 0.9")); + CHECK(strstr(reporter.lastFailedMessage, "was 1.1")); + } + + TEST(CheckCloseFailureIncludesTolerance) + { + RecordingReporter reporter; + TestResults results(&reporter); + CheckClose(results, 2, 3, 0.01f, TestDetails("", "", "", 0)); + + using namespace std; + CHECK(strstr(reporter.lastFailedMessage, "0.01")); + } + + TEST(CheckCloseFailureIncludesDetails) + { + RecordingReporter reporter; + TestResults results(&reporter); + TestDetails const details("mytest", "mysuite", "header.h", 10); + + CheckClose(results, 2, 3, 0.01f, details); + + CHECK_EQUAL("mytest", reporter.lastFailedTest); + CHECK_EQUAL("mysuite", reporter.lastFailedSuite); + CHECK_EQUAL("header.h", reporter.lastFailedFile); + CHECK_EQUAL(10, reporter.lastFailedLine); + } + + + TEST(CheckArrayEqualTrue) + { + TestResults results; + + int const array[3] = { 1, 2, 3 }; + CheckArrayEqual(results, array, array, 3, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckArrayEqualFalse) + { + TestResults results; + + int const array1[3] = { 1, 2, 3 }; + int const array2[3] = { 1, 2, 2 }; + CheckArrayEqual(results, array1, array2, 3, TestDetails("", "", "", 0)); + CHECK_EQUAL(1, results.GetFailureCount()); + } + + TEST(CheckArrayCloseTrue) + { + TestResults results; + + float const array1[3] = { 1.0f, 1.5f, 2.0f }; + float const array2[3] = { 1.01f, 1.51f, 2.01f }; + CheckArrayClose(results, array1, array2, 3, 0.02f, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckArrayCloseFalse) + { + TestResults results; + + float const array1[3] = { 1.0f, 1.5f, 2.0f }; + float const array2[3] = { 1.01f, 1.51f, 2.01f }; + CheckArrayClose(results, array1, array2, 3, 0.001f, TestDetails("", "", "", 0)); + CHECK_EQUAL(1, results.GetFailureCount()); + } + + TEST(CheckArrayCloseFailureIncludesDetails) + { + RecordingReporter reporter; + TestResults results(&reporter); + TestDetails const details("arrayCloseTest", "arrayCloseSuite", "file", 1337); + + float const array1[3] = { 1.0f, 1.5f, 2.0f }; + float const array2[3] = { 1.01f, 1.51f, 2.01f }; + CheckArrayClose(results, array1, array2, 3, 0.001f, details); + + CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("file", reporter.lastFailedFile); + CHECK_EQUAL(1337, reporter.lastFailedLine); + } + + + TEST(CheckArray2DCloseTrue) + { + TestResults results; + + float const array1[3][3] = { { 1.0f, 1.5f, 2.0f }, + { 2.0f, 2.5f, 3.0f }, + { 3.0f, 3.5f, 4.0f } }; + float const array2[3][3] = { { 1.01f, 1.51f, 2.01f }, + { 2.01f, 2.51f, 3.01f }, + { 3.01f, 3.51f, 4.01f } }; + CheckArray2DClose(results, array1, array2, 3, 3, 0.02f, TestDetails("", "", "", 0)); + CHECK_EQUAL(0, results.GetFailureCount()); + } + + TEST(CheckArray2DCloseFalse) + { + TestResults results; + + float const array1[3][3] = { { 1.0f, 1.5f, 2.0f }, + { 2.0f, 2.5f, 3.0f }, + { 3.0f, 3.5f, 4.0f } }; + float const array2[3][3] = { { 1.01f, 1.51f, 2.01f }, + { 2.01f, 2.51f, 3.01f }, + { 3.01f, 3.51f, 4.01f } }; + CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, TestDetails("", "", "", 0)); + CHECK_EQUAL(1, results.GetFailureCount()); + } + + TEST(CheckCloseWithDoublesSucceeds) + { + CHECK_CLOSE(0.5, 0.5, 0.0001); + } + + TEST(CheckArray2DCloseFailureIncludesDetails) + { + RecordingReporter reporter; + TestResults results(&reporter); + TestDetails const details("array2DCloseTest", "array2DCloseSuite", "file", 1234); + + float const array1[3][3] = { { 1.0f, 1.5f, 2.0f }, + { 2.0f, 2.5f, 3.0f }, + { 3.0f, 3.5f, 4.0f } }; + float const array2[3][3] = { { 1.01f, 1.51f, 2.01f }, + { 2.01f, 2.51f, 3.01f }, + { 3.01f, 3.51f, 4.01f } }; + CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, details); + + CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("file", reporter.lastFailedFile); + CHECK_EQUAL(1234, reporter.lastFailedLine); + } + + class TruthyUnlessCopied + { + public: + TruthyUnlessCopied() + : truthy_(true) + { + } + + TruthyUnlessCopied(const TruthyUnlessCopied&) + : truthy_(false) + { + } + + operator bool() const + { + return truthy_; + } + + private: + bool truthy_; + }; + + TEST(CheckProperlyDealsWithOperatorBoolOverrides) + { + TruthyUnlessCopied objectThatShouldBeTruthy; + CHECK(objectThatShouldBeTruthy); + } + +} diff --git a/tests/TestCompositeTestReporter.cpp b/tests/TestCompositeTestReporter.cpp new file mode 100644 index 0000000..d2be918 --- /dev/null +++ b/tests/TestCompositeTestReporter.cpp @@ -0,0 +1,175 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/CompositeTestReporter.h" + +using namespace UnitTest; + +namespace { + + TEST(ZeroReportersByDefault) + { + CHECK_EQUAL(0, CompositeTestReporter().GetReporterCount()); + } + + struct MockReporter : TestReporter + { + MockReporter() + : testStartCalled(false) + , testStartDetails(NULL) + , failureCalled(false) + , failureDetails(NULL) + , failureStr(NULL) + , testFinishCalled(false) + , testFinishDetails(NULL) + , testFinishSecondsElapsed(-1.0f) + , summaryCalled(false) + , summaryTotalTestCount(-1) + , summaryFailureCount(-1) + , summarySecondsElapsed(-1.0f) + {} + + virtual void ReportTestStart(TestDetails const& test) + { + testStartCalled = true; + testStartDetails = &test; + } + + virtual void ReportFailure(TestDetails const& test, char const* failure) + { + failureCalled = true; + failureDetails = &test; + failureStr = failure; + } + + virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed) + { + testFinishCalled = true; + testFinishDetails = &test; + testFinishSecondsElapsed = secondsElapsed; + } + + virtual void ReportSummary(int totalTestCount, + int failedTestCount, + int failureCount, + float secondsElapsed) + { + summaryCalled = true; + summaryTotalTestCount = totalTestCount; + summaryFailedTestCount = failedTestCount; + summaryFailureCount = failureCount; + summarySecondsElapsed = secondsElapsed; + } + + bool testStartCalled; + TestDetails const* testStartDetails; + + bool failureCalled; + TestDetails const* failureDetails; + const char* failureStr; + + bool testFinishCalled; + TestDetails const* testFinishDetails; + float testFinishSecondsElapsed; + + bool summaryCalled; + int summaryTotalTestCount; + int summaryFailedTestCount; + int summaryFailureCount; + float summarySecondsElapsed; + }; + + TEST(AddReporter) + { + MockReporter r; + CompositeTestReporter c; + + CHECK(c.AddReporter(&r)); + CHECK_EQUAL(1, c.GetReporterCount()); + } + + TEST(RemoveReporter) + { + MockReporter r; + CompositeTestReporter c; + + c.AddReporter(&r); + CHECK(c.RemoveReporter(&r)); + CHECK_EQUAL(0, c.GetReporterCount()); + } + + struct Fixture + { + Fixture() + { + c.AddReporter(&r0); + c.AddReporter(&r1); + } + + MockReporter r0, r1; + CompositeTestReporter c; + }; + + TEST_FIXTURE(Fixture, ReportTestStartCallsReportTestStartOnAllAggregates) + { + TestDetails t("", "", "", 0); + c.ReportTestStart(t); + + CHECK(r0.testStartCalled); + CHECK_EQUAL(&t, r0.testStartDetails); + CHECK(r1.testStartCalled); + CHECK_EQUAL(&t, r1.testStartDetails); + } + + TEST_FIXTURE(Fixture, ReportFailureCallsReportFailureOnAllAggregates) + { + TestDetails t("", "", "", 0); + const char* failStr = "fail"; + c.ReportFailure(t, failStr); + + CHECK(r0.failureCalled); + CHECK_EQUAL(&t, r0.failureDetails); + CHECK_EQUAL(failStr, r0.failureStr); + + CHECK(r1.failureCalled); + CHECK_EQUAL(&t, r1.failureDetails); + CHECK_EQUAL(failStr, r1.failureStr); + } + + TEST_FIXTURE(Fixture, ReportTestFinishCallsReportTestFinishOnAllAggregates) + { + TestDetails t("", "", "", 0); + const float s = 1.2345f; + c.ReportTestFinish(t, s); + + CHECK(r0.testFinishCalled); + CHECK_EQUAL(&t, r0.testFinishDetails); + CHECK_CLOSE(s, r0.testFinishSecondsElapsed, 0.00001f); + + CHECK(r1.testFinishCalled); + CHECK_EQUAL(&t, r1.testFinishDetails); + CHECK_CLOSE(s, r1.testFinishSecondsElapsed, 0.00001f); + } + + TEST_FIXTURE(Fixture, ReportSummaryCallsReportSummaryOnAllAggregates) + { + TestDetails t("", "", "", 0); + const int testCount = 3; + const int failedTestCount = 4; + const int failureCount = 5; + const float secondsElapsed = 3.14159f; + + c.ReportSummary(testCount, failedTestCount, failureCount, secondsElapsed); + + CHECK(r0.summaryCalled); + CHECK_EQUAL(testCount, r0.summaryTotalTestCount); + CHECK_EQUAL(failedTestCount, r0.summaryFailedTestCount); + CHECK_EQUAL(failureCount, r0.summaryFailureCount); + CHECK_CLOSE(secondsElapsed, r0.summarySecondsElapsed, 0.00001f); + + CHECK(r1.summaryCalled); + CHECK_EQUAL(testCount, r1.summaryTotalTestCount); + CHECK_EQUAL(failedTestCount, r1.summaryFailedTestCount); + CHECK_EQUAL(failureCount, r1.summaryFailureCount); + CHECK_CLOSE(secondsElapsed, r1.summarySecondsElapsed, 0.00001f); + } + +} diff --git a/tests/TestCurrentTest.cpp b/tests/TestCurrentTest.cpp new file mode 100644 index 0000000..6cfb99d --- /dev/null +++ b/tests/TestCurrentTest.cpp @@ -0,0 +1,38 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/CurrentTest.h" +#include "ScopedCurrentTest.h" + +namespace +{ + + TEST(CanSetandGetDetails) + { + bool ok = false; + { + ScopedCurrentTest scopedTest; + + const UnitTest::TestDetails* details = reinterpret_cast< const UnitTest::TestDetails* >(12345); + UnitTest::CurrentTest::Details() = details; + + ok = (UnitTest::CurrentTest::Details() == details); + } + + CHECK(ok); + } + + TEST(CanSetAndGetResults) + { + bool ok = false; + { + ScopedCurrentTest scopedTest; + + UnitTest::TestResults results; + UnitTest::CurrentTest::Results() = &results; + + ok = (UnitTest::CurrentTest::Results() == &results); + } + + CHECK(ok); + } + +} diff --git a/tests/TestDeferredTestReporter.cpp b/tests/TestDeferredTestReporter.cpp new file mode 100644 index 0000000..46b4d63 --- /dev/null +++ b/tests/TestDeferredTestReporter.cpp @@ -0,0 +1,121 @@ +#include "UnitTest++/Config.h" + +#ifndef UNITTEST_NO_DEFERRED_REPORTER + +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/DeferredTestReporter.h" +#include + +namespace UnitTest +{ + + namespace + { + +#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM + MemoryOutStream& operator <<(MemoryOutStream& lhs, const std::string& rhs) + { + lhs << rhs.c_str(); + return lhs; + } +#endif + + struct MockDeferredTestReporter : public DeferredTestReporter + { + virtual void ReportSummary(int, int, int, float) + {} + }; + + struct DeferredTestReporterFixture + { + DeferredTestReporterFixture() + : testName("UniqueTestName") + , testSuite("UniqueTestSuite") + , fileName("filename.h") + , lineNumber(12) + , details(testName.c_str(), testSuite.c_str(), fileName.c_str(), lineNumber) + {} + + MockDeferredTestReporter reporter; + std::string const testName; + std::string const testSuite; + std::string const fileName; + int const lineNumber; + TestDetails const details; + }; + + TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCreatesANewDeferredTest) + { + reporter.ReportTestStart(details); + CHECK_EQUAL(1, (int)reporter.GetResults().size()); + } + + TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCapturesTestNameAndSuite) + { + reporter.ReportTestStart(details); + + DeferredTestResult const& result = reporter.GetResults().at(0); + CHECK_EQUAL(testName.c_str(), result.testName.c_str()); + CHECK_EQUAL(testSuite.c_str(), result.suiteName.c_str()); + } + + TEST_FIXTURE(DeferredTestReporterFixture, ReportTestEndCapturesTestTime) + { + float const elapsed = 123.45f; + reporter.ReportTestStart(details); + reporter.ReportTestFinish(details, elapsed); + + DeferredTestResult const& result = reporter.GetResults().at(0); + CHECK_CLOSE(elapsed, result.timeElapsed, 0.0001f); + } + + TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetails) + { + char const* failure = "failure"; + + reporter.ReportTestStart(details); + reporter.ReportFailure(details, failure); + + DeferredTestResult const& result = reporter.GetResults().at(0); + CHECK(result.failed == true); + CHECK_EQUAL(fileName.c_str(), result.failureFile.c_str()); + } + + TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetailsForMultipleFailures) + { + char const* failure1 = "failure 1"; + char const* failure2 = "failure 2"; + + reporter.ReportTestStart(details); + reporter.ReportFailure(details, failure1); + reporter.ReportFailure(details, failure2); + + DeferredTestResult const& result = reporter.GetResults().at(0); + CHECK_EQUAL(2, (int)result.failures.size()); + CHECK_EQUAL(failure1, result.failures[0].failureStr); + CHECK_EQUAL(failure2, result.failures[1].failureStr); + } + + TEST_FIXTURE(DeferredTestReporterFixture, DeferredTestReporterTakesCopyOfFailureMessage) + { + reporter.ReportTestStart(details); + + char failureMessage[128]; + char const* goodStr = "Real failure message"; + char const* badStr = "Bogus failure message"; + + using namespace std; + + strcpy(failureMessage, goodStr); + reporter.ReportFailure(details, failureMessage); + strcpy(failureMessage, badStr); + + DeferredTestResult const& result = reporter.GetResults().at(0); + DeferredTestFailure const& failure = result.failures.at(0); + CHECK_EQUAL(goodStr, failure.failureStr); + } + + } +} + +#endif diff --git a/tests/TestExceptions.cpp b/tests/TestExceptions.cpp new file mode 100644 index 0000000..08f6547 --- /dev/null +++ b/tests/TestExceptions.cpp @@ -0,0 +1,557 @@ +#include "UnitTest++/Config.h" +#ifndef UNITTEST_NO_EXCEPTIONS + +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/CurrentTest.h" +#include "RecordingReporter.h" +#include "ScopedCurrentTest.h" + +#include + +using namespace std; + +namespace { + + int ThrowingFunction() + { + throw "Doh"; + } + + int ThrowingStdExceptionFunction() + { + throw std::logic_error("Doh"); + } + + SUITE(CheckExceptionTests) + { + struct CheckFixture + { + CheckFixture() + : reporter() + , testResults(&reporter) + {} + + void PerformCheckWithNonStdThrow() + { + ScopedCurrentTest scopedResults(testResults); + CHECK(ThrowingFunction() == 1); + } + + void PerformCheckWithStdThrow() + { + ScopedCurrentTest scopedResults(testResults); + CHECK(ThrowingStdExceptionFunction() == 1); + } + + RecordingReporter reporter; + UnitTest::TestResults testResults; + }; + + TEST_FIXTURE(CheckFixture, CheckFailsOnException) + { + PerformCheckWithNonStdThrow(); + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckFixture, CheckFailsOnStdException) + { + PerformCheckWithStdThrow(); + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfExceptionIncludesCheckContents) + { + PerformCheckWithNonStdThrow(); + CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1")); + } + + TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStdExceptionIncludesCheckContents) + { + PerformCheckWithStdThrow(); + CHECK(strstr(reporter.lastFailedMessage, "ThrowingStdExceptionFunction() == 1")); + } + + TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStandardExceptionIncludesWhat) + { + PerformCheckWithStdThrow(); + CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)")); + } + } + + SUITE(CheckEqualExceptionTests) + { + struct CheckEqualFixture + { + CheckEqualFixture() + : reporter() + , testResults(&reporter) + , line(-1) + {} + + void PerformCheckWithNonStdThrow() + { + UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + CHECK_EQUAL(ThrowingFunction(), 123); line = __LINE__; + } + + void PerformCheckWithStdThrow() + { + UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + CHECK_EQUAL(ThrowingStdExceptionFunction(), 123); line = __LINE__; + } + + RecordingReporter reporter; + UnitTest::TestResults testResults; + int line; + }; + + TEST_FIXTURE(CheckEqualFixture, CheckEqualFailsOnException) + { + PerformCheckWithNonStdThrow(); + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckEqualFixture, CheckEqualFailsOnStdException) + { + PerformCheckWithStdThrow(); + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfExceptionContainsCorrectDetails) + { + PerformCheckWithNonStdThrow(); + + CHECK_EQUAL("testName", reporter.lastFailedTest); + CHECK_EQUAL("suiteName", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfStdExceptionContainsCorrectDetails) + { + PerformCheckWithStdThrow(); + + CHECK_EQUAL("testName", reporter.lastFailedTest); + CHECK_EQUAL("suiteName", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfExceptionIncludesCheckContents) + { + PerformCheckWithNonStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction()")); + CHECK(strstr(reporter.lastFailedMessage, "123")); + } + + TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfStdExceptionIncludesCheckContents) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "ThrowingStdExceptionFunction()")); + CHECK(strstr(reporter.lastFailedMessage, "123")); + } + + TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfStandardExceptionIncludesWhat) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)")); + } + } + + SUITE(CheckCloseExceptionTests) + { + struct CheckCloseFixture + { + CheckCloseFixture() + : reporter() + , testResults(&reporter) + , line(-1) + {} + + void PerformCheckWithNonStdThrow() + { + UnitTest::TestDetails const testDetails("closeTest", "closeSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + CHECK_CLOSE(static_cast(ThrowingFunction()), 1.0001f, 0.1f); line = __LINE__; + } + + void PerformCheckWithStdThrow() + { + UnitTest::TestDetails const testDetails("closeTest", "closeSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + CHECK_CLOSE(static_cast(ThrowingStdExceptionFunction()), 1.0001f, 0.1f); line = __LINE__; + } + + RecordingReporter reporter; + UnitTest::TestResults testResults; + int line; + }; + + TEST_FIXTURE(CheckCloseFixture, CheckCloseFailsOnException) + { + PerformCheckWithNonStdThrow(); + + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckCloseFixture, CheckCloseFailsOnStdException) + { + PerformCheckWithStdThrow(); + + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfExceptionContainsCorrectDetails) + { + PerformCheckWithNonStdThrow(); + + CHECK_EQUAL("closeTest", reporter.lastFailedTest); + CHECK_EQUAL("closeSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfStdExceptionContainsCorrectDetails) + { + PerformCheckWithStdThrow(); + + CHECK_EQUAL("closeTest", reporter.lastFailedTest); + CHECK_EQUAL("closeSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfExceptionIncludesCheckContents) + { + PerformCheckWithNonStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "static_cast(ThrowingFunction())")); + CHECK(strstr(reporter.lastFailedMessage, "1.0001f")); + } + + TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfStdExceptionIncludesCheckContents) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "static_cast(ThrowingStdExceptionFunction())")); + CHECK(strstr(reporter.lastFailedMessage, "1.0001f")); + } + + TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfStandardExceptionIncludesWhat) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)")); + } + } + + class ThrowingObject + { + public: + float operator[](size_t) const + { + throw "Test throw"; + } + }; + + class StdThrowingObject + { + public: + float operator[](size_t) const + { + throw std::runtime_error("Test throw"); + } + }; + + SUITE(CheckArrayCloseExceptionTests) + { + struct CheckArrayCloseFixture + { + CheckArrayCloseFixture() + : reporter() + , testResults(&reporter) + , line(-1) + {} + + void PerformCheckWithNonStdThrow() + { + UnitTest::TestDetails const testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + int const data[4] = { 0, 1, 2, 3 }; + CHECK_ARRAY_CLOSE(data, ThrowingObject(), 4, 0.01f); line = __LINE__; + } + + void PerformCheckWithStdThrow() + { + UnitTest::TestDetails const testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + int const data[4] = { 0, 1, 2, 3 }; + CHECK_ARRAY_CLOSE(data, StdThrowingObject(), 4, 0.01f); line = __LINE__; + } + + RecordingReporter reporter; + UnitTest::TestResults testResults; + int line; + }; + + TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureBecauseOfExceptionContainsCorrectDetails) + { + PerformCheckWithNonStdThrow(); + + CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureBecauseOfStdExceptionContainsCorrectDetails) + { + PerformCheckWithStdThrow(); + + CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckArrayCloseFixture, CheckFailsOnException) + { + PerformCheckWithNonStdThrow(); + + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckArrayCloseFixture, CheckFailsOnStdException) + { + PerformCheckWithStdThrow(); + + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureOnExceptionIncludesCheckContents) + { + PerformCheckWithNonStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "data")); + CHECK(strstr(reporter.lastFailedMessage, "ThrowingObject()")); + } + + TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureOnStdExceptionIncludesCheckContents) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "data")); + CHECK(strstr(reporter.lastFailedMessage, "StdThrowingObject()")); + } + + TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureOnStdExceptionIncludesWhat) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "exception (Test throw)")); + } + } + + SUITE(CheckArrayEqualExceptionTests) + { + struct CheckArrayEqualFixture + { + CheckArrayEqualFixture() + : reporter() + , testResults(&reporter) + , line(-1) + {} + + void PerformCheckWithNonStdThrow() + { + UnitTest::TestDetails const testDetails("arrayEqualTest", "arrayEqualSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + int const data[4] = { 0, 1, 2, 3 }; + CHECK_ARRAY_EQUAL(data, ThrowingObject(), 4); line = __LINE__; + } + + void PerformCheckWithStdThrow() + { + UnitTest::TestDetails const testDetails("arrayEqualTest", "arrayEqualSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + int const data[4] = { 0, 1, 2, 3 }; + CHECK_ARRAY_EQUAL(data, StdThrowingObject(), 4); line = __LINE__; + } + + RecordingReporter reporter; + UnitTest::TestResults testResults; + int line; + }; + + TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureBecauseOfExceptionContainsCorrectDetails) + { + PerformCheckWithNonStdThrow(); + + CHECK_EQUAL("arrayEqualTest", reporter.lastFailedTest); + CHECK_EQUAL("arrayEqualSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureBecauseOfStdExceptionContainsCorrectDetails) + { + PerformCheckWithStdThrow(); + + CHECK_EQUAL("arrayEqualTest", reporter.lastFailedTest); + CHECK_EQUAL("arrayEqualSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckArrayEqualFixture, CheckFailsOnException) + { + PerformCheckWithNonStdThrow(); + + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckArrayEqualFixture, CheckFailsOnStdException) + { + PerformCheckWithStdThrow(); + + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureOnExceptionIncludesCheckContents) + { + PerformCheckWithNonStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "data")); + CHECK(strstr(reporter.lastFailedMessage, "ThrowingObject()")); + } + + TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureOnStdExceptionIncludesCheckContents) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "data")); + CHECK(strstr(reporter.lastFailedMessage, "StdThrowingObject()")); + } + + TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureOnStdExceptionIncludesWhat) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "exception (Test throw)")); + } + } + + SUITE(CheckArray2DExceptionTests) + { + class ThrowingObject2D + { + public: + float* operator[](size_t) const + { + throw "Test throw"; + } + }; + + class StdThrowingObject2D + { + public: + float* operator[](size_t) const + { + throw std::runtime_error("Test throw"); + } + }; + + struct CheckArray2DCloseFixture + { + CheckArray2DCloseFixture() + : reporter() + , testResults(&reporter) + , line(-1) + {} + + void PerformCheckWithNonStdThrow() + { + UnitTest::TestDetails const testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + const float data[2][2] = { {0, 1}, {2, 3} }; + CHECK_ARRAY2D_CLOSE(data, ThrowingObject2D(), 2, 2, 0.01f); line = __LINE__; + } + + void PerformCheckWithStdThrow() + { + UnitTest::TestDetails const testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + const float data[2][2] = { {0, 1}, {2, 3} }; + CHECK_ARRAY2D_CLOSE(data, StdThrowingObject2D(), 2, 2, 0.01f); line = __LINE__; + } + + RecordingReporter reporter; + UnitTest::TestResults testResults; + int line; + }; + + TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureBecauseOfExceptionContainsCorrectDetails) + { + PerformCheckWithNonStdThrow(); + + CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureBecauseOfStdExceptionContainsCorrectDetails) + { + PerformCheckWithStdThrow(); + + CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailsOnException) + { + PerformCheckWithNonStdThrow(); + + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailsOnStdException) + { + PerformCheckWithStdThrow(); + + CHECK(testResults.GetFailureCount() > 0); + } + + TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureOnExceptionIncludesCheckContents) + { + PerformCheckWithNonStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "data")); + CHECK(strstr(reporter.lastFailedMessage, "ThrowingObject2D()")); + } + + TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureOnStdExceptionIncludesCheckContents) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "data")); + CHECK(strstr(reporter.lastFailedMessage, "StdThrowingObject2D()")); + } + + TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureOnStdExceptionIncludesWhat) + { + PerformCheckWithStdThrow(); + + CHECK(strstr(reporter.lastFailedMessage, "exception (Test throw)")); + } + } +} + +#endif diff --git a/tests/TestLongMacros.cpp b/tests/TestLongMacros.cpp new file mode 100644 index 0000000..6720a97 --- /dev/null +++ b/tests/TestLongMacros.cpp @@ -0,0 +1,45 @@ +#define UNITTEST_DISABLE_SHORT_MACROS + +#include "UnitTest++/UnitTestPP.h" + +// This file is not intended to test every little thing, just a few basics to hopefully ensure +// the macros are working and the short macros are not defined. +UNITTEST_SUITE(LongMacros) +{ + UNITTEST_TEST(LongCheckMacroWorks) + { + UNITTEST_CHECK(true); + } + + class Fixture + { + public: + Fixture() : sanity_(true) {} + protected: + bool sanity_; + }; + + UNITTEST_TEST_FIXTURE(Fixture, LongFixtureMacroWorks) + { + UNITTEST_REQUIRE UNITTEST_CHECK(sanity_); + } + + UNITTEST_TEST(ShortMacrosAreNotDefined) + { +#if defined(CHECK) || \ + defined(CHECK_EQUAL) || \ + defined(CHECK_CLOSE) || \ + defined(CHECK_ARRAY_EQUAL) || \ + defined(CHECK_ARRAY_CLOSE) || \ + defined(CHECK_ARRAY2D_CLOSE) || \ + defined(CHECK_THROW) || \ + defined(CHECK_ASSERT) || \ + defined(SUITE) || \ + defined(TEST) || \ + defined(TEST_FIXTURE) || \ + defined(REQUIRE) + + UNITTEST_CHECK(false); +#endif + } +} diff --git a/tests/TestMemoryOutStream.cpp b/tests/TestMemoryOutStream.cpp new file mode 100644 index 0000000..854277e --- /dev/null +++ b/tests/TestMemoryOutStream.cpp @@ -0,0 +1,336 @@ +#include "UnitTest++/UnitTestPP.h" + +#include "UnitTest++/MemoryOutStream.h" +#include +#include +#include +#include + +using namespace UnitTest; +using namespace std; + +namespace { + + const char* maxSignedIntegralStr(size_t nBytes) + { + switch(nBytes) + { + case 8: + return "9223372036854775807"; + case 4: + return "2147483647"; + case 2: + return "32767"; + case 1: + return "127"; + default: + return "Unsupported signed integral size"; + } + } + + const char* minSignedIntegralStr(size_t nBytes) + { + switch(nBytes) + { + case 8: + return "-9223372036854775808"; + case 4: + return "-2147483648"; + case 2: + return "-32768"; + case 1: + return "-128"; + default: + return "Unsupported signed integral size"; + } + } + + const char* maxUnsignedIntegralStr(size_t nBytes) + { + switch(nBytes) + { + case 8: + return "18446744073709551615"; + case 4: + return "4294967295"; + case 2: + return "65535"; + case 1: + return "255"; + default: + return "Unsupported signed integral size"; + } + } + + TEST(DefaultIsEmptyString) + { + MemoryOutStream const stream; + CHECK(stream.GetText() != 0); + CHECK_EQUAL("", stream.GetText()); + } + + TEST(StreamingTextCopiesCharacters) + { + MemoryOutStream stream; + stream << "Lalala"; + CHECK_EQUAL("Lalala", stream.GetText()); + } + + TEST(StreamingMultipleTimesConcatenatesResult) + { + MemoryOutStream stream; + stream << "Bork" << "Foo" << "Bar"; + CHECK_EQUAL("BorkFooBar", stream.GetText()); + } + + TEST(StreamingIntWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (int)123; + CHECK_EQUAL("123", stream.GetText()); + } + + TEST(StreaminMaxIntWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << INT_MAX; + CHECK_EQUAL(maxSignedIntegralStr(sizeof(int)), stream.GetText()); + } + + TEST(StreamingMinIntWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << INT_MIN; + CHECK_EQUAL(minSignedIntegralStr(sizeof(int)), stream.GetText()); + } + + TEST(StreamingUnsignedIntWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (unsigned int)123; + CHECK_EQUAL("123", stream.GetText()); + } + + TEST(StreamingMaxUnsignedIntWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (unsigned int)UINT_MAX; + CHECK_EQUAL(maxUnsignedIntegralStr(sizeof(unsigned int)), stream.GetText()); + } + + TEST(StreamingMinUnsignedIntWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (unsigned int)0; + CHECK_EQUAL("0", stream.GetText()); + } + + TEST(StreamingLongWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (long)(-123); + CHECK_EQUAL("-123", stream.GetText()); + } + + TEST(StreamingMaxLongWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (long)(LONG_MAX); + CHECK_EQUAL(maxSignedIntegralStr(sizeof(long)), stream.GetText()); + } + + TEST(StreamingMinLongWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (long)(LONG_MIN); + CHECK_EQUAL(minSignedIntegralStr(sizeof(long)), stream.GetText()); + } + + TEST(StreamingUnsignedLongWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (unsigned long)123; + CHECK_EQUAL("123", stream.GetText()); + } + + TEST(StreamingMaxUnsignedLongWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (unsigned long)ULONG_MAX; + CHECK_EQUAL(maxUnsignedIntegralStr(sizeof(unsigned long)), stream.GetText()); + } + + TEST(StreamingMinUnsignedLongWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (unsigned long)0ul; + CHECK_EQUAL("0", stream.GetText()); + } + + TEST(StreamingLongLongWritesCorrectCharacters) + { + MemoryOutStream stream; +#ifdef UNITTEST_COMPILER_IS_MSVC6 + stream << (__int64)-12345i64; +#else + stream << (long long)-12345ll; +#endif + CHECK_EQUAL("-12345", stream.GetText()); + } + +#ifdef LLONG_MAX + TEST(StreamingMaxLongLongWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (long long)LLONG_MAX; + CHECK_EQUAL(maxSignedIntegralStr(sizeof(long long)), stream.GetText()); + } +#endif + +#ifdef LLONG_MIN + TEST(StreamingMinLongLongWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (long long)LLONG_MIN; + CHECK_EQUAL(minSignedIntegralStr(sizeof(long long)), stream.GetText()); + } +#endif + + TEST(StreamingUnsignedLongLongWritesCorrectCharacters) + { + MemoryOutStream stream; +#ifdef UNITTEST_COMPILER_IS_MSVC6 + stream << (unsigned __int64)85899ui64; +#else + stream << (unsigned long long)85899ull; +#endif + CHECK_EQUAL("85899", stream.GetText()); + } + +#ifdef ULLONG_MAX + TEST(StreamingMaxUnsignedLongLongWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << (unsigned long long)ULLONG_MAX; + CHECK_EQUAL(maxUnsignedIntegralStr(sizeof(unsigned long long)), stream.GetText()); + } +#endif + + TEST(StreamingMinUnsignedLongLongWritesCorrectCharacters) + { + MemoryOutStream stream; +#ifdef UNITTEST_COMPILER_IS_MSVC6 + stream << (unsigned __int64)0ui64; +#else + stream << (unsigned long long)0ull; +#endif + CHECK_EQUAL("0", stream.GetText()); + } + + TEST(StreamingFloatWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << 3.1415f; + CHECK(strstr(stream.GetText(), "3.1415")); + } + + TEST(StreamingDoubleWritesCorrectCharacters) + { + MemoryOutStream stream; + stream << 3.1415; + CHECK(strstr(stream.GetText(), "3.1415")); + } + + TEST(StreamingPointerWritesCorrectCharacters) + { + MemoryOutStream stream; + int* p = (int*)0x1234; + stream << p; + CHECK(strstr(stream.GetText(), "1234")); + } + + TEST(StreamingSizeTWritesCorrectCharacters) + { + MemoryOutStream stream; + size_t const s = 53124; + stream << s; + CHECK_EQUAL("53124", stream.GetText()); + } + + TEST(ClearEmptiesMemoryOutStreamContents) + { + MemoryOutStream stream; + stream << "Hello world"; + stream.Clear(); + CHECK_EQUAL("", stream.GetText()); + } + +#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM + + TEST(StreamInitialCapacityIsCorrect) + { + MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE); + CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE, stream.GetCapacity()); + } + + TEST(StreamInitialCapacityIsMultipleOfGrowChunkSize) + { + MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE + 1); + CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity()); + } + + + TEST(ExceedingCapacityGrowsBuffer) + { + MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE); + stream << "012345678901234567890123456789"; + char const* const oldBuffer = stream.GetText(); + stream << "0123456789"; + CHECK(oldBuffer != stream.GetText()); + } + + TEST(ExceedingCapacityGrowsBufferByGrowChunk) + { + MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE); + stream << "0123456789012345678901234567890123456789"; + CHECK_EQUAL(MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity()); + } + + TEST(WritingStringLongerThanCapacityFitsInNewBuffer) + { + MemoryOutStream stream(8); + stream << "0123456789ABCDEF"; + CHECK_EQUAL("0123456789ABCDEF", stream.GetText()); + } + + TEST(WritingIntLongerThanCapacityFitsInNewBuffer) + { + MemoryOutStream stream(8); + stream << "aaaa" << 123456; + CHECK_EQUAL("aaaa123456", stream.GetText()); + } + + TEST(WritingFloatLongerThanCapacityFitsInNewBuffer) + { + MemoryOutStream stream(8); + stream << "aaaa" << 123456.0f; + CHECK_EQUAL("aaaa123456.000000", stream.GetText()); + } + + TEST(WritingSizeTLongerThanCapacityFitsInNewBuffer) + { + MemoryOutStream stream(8); + stream << "aaaa" << size_t(32145); + CHECK_EQUAL("aaaa32145", stream.GetText()); + } + + TEST(VerifyLargeDoubleCanBeStreamedWithoutCrashing) + { + MemoryOutStream stream(8); + stream << DBL_MAX; + CHECK(true); + } + +#endif + +} diff --git a/tests/TestRequireMacrosWithExceptionsOff.cpp b/tests/TestRequireMacrosWithExceptionsOff.cpp new file mode 100644 index 0000000..d43fbc1 --- /dev/null +++ b/tests/TestRequireMacrosWithExceptionsOff.cpp @@ -0,0 +1,738 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/CurrentTest.h" +#include "RecordingReporter.h" +#include "ScopedCurrentTest.h" + +#include + +using namespace std; + +#ifdef UNITTEST_NO_EXCEPTIONS + +// NOTE: unit tests here use a work around for std::longjmp +// taking us out of the current running unit test. We use a +// follow on test to check the previous test exhibited correct +// behavior. + +namespace { + + static RecordingReporter reporter; + static std::string testName; + static bool next = false; + static int line = 0; + + // Use destructor to reset our globals + struct DoValidationOn + { + ~DoValidationOn() + { + testName = ""; + next = false; + line = 0; + + reporter.lastFailedLine = 0; + memset(reporter.lastFailedTest, 0, sizeof(reporter.lastFailedTest)); + memset(reporter.lastFailedSuite, 0, sizeof(reporter.lastFailedSuite)); + memset(reporter.lastFailedFile, 0, sizeof(reporter.lastFailedFile)); + } + }; + + TEST(RequireCheckSucceedsOnTrue) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK(true); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequireCheckSucceedsOnTrue_FollowOn) + { + CHECK(next); + } + + TEST(RequiredCheckFailsOnFalse) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK(false); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckFailsOnFalse_FollowOn) + { + CHECK(!next); + } + + TEST(RequireMacroSupportsMultipleChecks) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + REQUIRE + { + CHECK(true); + CHECK_EQUAL(1,1); + } + + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequireMacroSupportsMultipleChecks_FollowOn) + { + CHECK(next); + } + + TEST(RequireMacroSupportsMultipleChecksWithFailingChecks) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + REQUIRE + { + CHECK(true); + CHECK_EQUAL(1,2); + } + + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequireMacroSupportsMultipleChecksWithFailingChecks_FollowOn) + { + CHECK(!next); + } + + TEST(RequireMacroDoesntExecuteCodeAfterAFailingCheck) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + REQUIRE + { + CHECK(false); + next = true; + } + } + } + + TEST_FIXTURE(DoValidationOn, RequireMacroDoesntExecuteCodeAfterAFailingCheck_FollowOn) + { + CHECK(!next); + } + + TEST(FailureReportsCorrectTestName) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + testName = m_details.testName; + REQUIRE CHECK(false); + } + } + + TEST_FIXTURE(DoValidationOn, FailureReportsCorrectTestName_FollowOn) + { + CHECK_EQUAL(testName, reporter.lastFailedTest); + } + + TEST(RequiredCheckFailureIncludesCheckContents) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + testName = m_details.testName; + const bool yaddayadda = false; + + REQUIRE CHECK(yaddayadda); + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckFailureIncludesCheckContents_FollowOn) + { + CHECK(strstr(reporter.lastFailedMessage, "yaddayadda")); + } + + TEST(RequiredCheckEqualSucceedsOnEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK_EQUAL(1,1); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckEqualSucceedsOnEqual_FollowOn) + { + CHECK(next); + } + + TEST(RequiredCheckEqualFailsOnNotEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK_EQUAL(1, 2); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckEqualFailsOnNotEqual_FollowOn) + { +// TODO: check reporter last test name + CHECK(!next); + } + + TEST(RequiredCheckEqualFailureContainsCorrectDetails) + { + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + line = __LINE__; REQUIRE CHECK_EQUAL(1, 123); + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckEqualFailureContainsCorrectDetails_FollowOn) + { + CHECK_EQUAL("testName", reporter.lastFailedTest); + CHECK_EQUAL("suiteName", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + int g_sideEffect = 0; + int FunctionWithSideEffects() + { + ++g_sideEffect; + return 1; + } + + TEST(RequiredCheckEqualDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK_EQUAL(1, FunctionWithSideEffects()); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckEqualDoesNotHaveSideEffectsWhenPassing_FollowOn) + { + CHECK_EQUAL(1, g_sideEffect); + CHECK(next); + } + + TEST(RequiredCheckEqualDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK_EQUAL(2, FunctionWithSideEffects()); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckEqualDoesNotHaveSideEffectsWhenFailing_FollowOn) + { + CHECK_EQUAL(1, g_sideEffect); + CHECK(!next); + } + + TEST(RequiredCheckCloseSucceedsOnEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK_CLOSE(1.0f, 1.001f, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckCloseSucceedsOnEqual_FollowOn) + { + CHECK(next); + } + + TEST(RequiredCheckCloseFailsOnNotEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK_CLOSE (1.0f, 1.1f, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckCloseFailsOnNotEqual_FollowOn) + { + CHECK(!next); + } + + TEST(RequiredCheckCloseFailureContainsCorrectDetails) + { + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails testDetails("test", "suite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + line = __LINE__; REQUIRE CHECK_CLOSE(1.0f, 1.1f, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckCloseFailureContainsCorrectDetails_FollowOn) + { + CHECK_EQUAL("test", reporter.lastFailedTest); + CHECK_EQUAL("suite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + + CHECK(!next); + } + + TEST(RequiredCheckCloseDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK_CLOSE (1, FunctionWithSideEffects(), 0.1f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckCloseDoesNotHaveSideEffectsWhenPassing_FollowOn) + { + CHECK_EQUAL(1, g_sideEffect); + CHECK(next); + } + + TEST(RequiredCheckCloseDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + REQUIRE CHECK_CLOSE(2, FunctionWithSideEffects(), 0.1f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckCloseDoesNotHaveSideEffectsWhenFailingOn) + { + CHECK_EQUAL(1, g_sideEffect); + CHECK(!next); + } + + TEST(RequiredCheckArrayCloseSucceedsOnEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + const float data[4] = { 0, 1, 2, 3 }; + + REQUIRE CHECK_ARRAY_CLOSE (data, data, 4, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayCloseSucceedsOnEqual_FollowOn) + { + CHECK(next); + } + + TEST(RequiredCheckArrayCloseFailsOnNotEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + REQUIRE CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayCloseFailsOnNotEqual_FollowOn) + { + CHECK(!next); + } + + TEST(RequiredCheckArrayCloseFailureIncludesCheckExpectedAndActual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + REQUIRE CHECK_ARRAY_CLOSE(data1, data2, 4, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayCloseFailureIncludesCheckExpectedAndActual_FollowOn) + { + CHECK(!next); + + CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); + CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); + } + + TEST(RequiredCheckArrayCloseFailureContainsCorrectDetails) + { + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + line = __LINE__; REQUIRE CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayCloseFailureContainsCorrectDetails_FollowOn) + { + CHECK(!next); + + CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST(RequiredCheckArrayCloseFailureIncludesTolerance) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + float const data1[4] = { 0, 1, 2, 3 }; + float const data2[4] = { 0, 1, 3, 3 }; + + REQUIRE CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayCloseFailureIncludesTolerance_FollowOn) + { + CHECK(!next); + CHECK(strstr(reporter.lastFailedMessage, "0.01")); + } + + TEST(RequiredCheckArrayEqualSuceedsOnEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + const float data[4] = { 0, 1, 2, 3 }; + + REQUIRE CHECK_ARRAY_EQUAL (data, data, 4); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayEqualSuceedsOnEqual_FollowOn) + { + CHECK(next); + } + + TEST(RequiredCheckArrayEqualFailsOnNotEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + REQUIRE CHECK_ARRAY_EQUAL (data1, data2, 4); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayEqualFailsOnNotEqual) + { + CHECK(!next); + } + + TEST(RequiredCheckArrayEqualFailureIncludesCheckExpectedAndActual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + REQUIRE CHECK_ARRAY_EQUAL (data1, data2, 4); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayEqualFailureIncludesCheckExpectedAndActual_FollowOn) + { + CHECK(!next); + + CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); + CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); + } + + TEST(RequiredCheckArrayEqualFailureContainsCorrectInfo) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + line = __LINE__; REQUIRE CHECK_ARRAY_EQUAL (data1, data2, 4); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayEqualFailureContainsCorrectInfo_FollowOn) + { + CHECK(!next); + + CHECK_EQUAL("RequiredCheckArrayEqualFailureContainsCorrectInfo", reporter.lastFailedTest); + CHECK_EQUAL(__FILE__, reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + float const* FunctionWithSideEffects2() + { + ++g_sideEffect; + static float const data[] = { 0, 1, 2, 3}; + return data; + } + + TEST(RequiredCheckArrayCloseDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[] = { 0, 1, 2, 3 }; + + REQUIRE CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayCloseDoesNotHaveSideEffectsWhenPassing_FollowOn) + { + CHECK_EQUAL(1, g_sideEffect); + CHECK(next); + } + + TEST(RequiredCheckArrayCloseDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[] = { 0, 1, 3, 3 }; + + REQUIRE CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArrayCloseDoesNotHaveSideEffectsWhenFailing_FollowOn) + { + CHECK_EQUAL(1, g_sideEffect); + CHECK(!next); + } + + TEST(RequiredCheckArray2DCloseSucceedsOnEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + const float data[2][2] = { {0, 1}, {2, 3} }; + + REQUIRE CHECK_ARRAY2D_CLOSE(data, data, 2, 2, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArray2DCloseSucceedsOnEqual_FollowOn) + { + CHECK(next); + } + + TEST(RequiredCheckArray2DCloseFailsOnNotEqual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[2][2] = { {0, 1}, {2, 3} }; + int const data2[2][2] = { {0, 1}, {3, 3} }; + + REQUIRE CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArray2DCloseFailsOnNotEqual_FollowOn) + { + CHECK(!next); + } + + TEST(RequiredCheckArray2DCloseFailureIncludesCheckExpectedAndActual) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[2][2] = { {0, 1}, {2, 3} }; + int const data2[2][2] = { {0, 1}, {3, 3} }; + + REQUIRE CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArray2DCloseFailureIncludesCheckExpectedAndActual_FollowOn) + { + CHECK(!next); + + CHECK(strstr(reporter.lastFailedMessage, "xpected [ [ 0 1 ] [ 2 3 ] ]")); + CHECK(strstr(reporter.lastFailedMessage, "was [ [ 0 1 ] [ 3 3 ] ]")); + } + + TEST(RequiredCheckArray2DCloseFailureContainsCorrectDetails) + { + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + int const data1[2][2] = { {0, 1}, {2, 3} }; + int const data2[2][2] = { {0, 1}, {3, 3} }; + + line = __LINE__; REQUIRE CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArray2DCloseFailureContainsCorrectDetails_FollowOn) + { + CHECK(!next); + + CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST(RequiredCheckArray2DCloseFailureIncludesTolerance) + { + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + float const data1[2][2] = { {0, 1}, {2, 3} }; + float const data2[2][2] = { {0, 1}, {3, 3} }; + + REQUIRE CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArray2DCloseFailureIncludesTolerance_FollowOn) + { + CHECK(!next); + CHECK(strstr(reporter.lastFailedMessage, "0.01")); + } + + float const* const* FunctionWithSideEffects3() + { + ++g_sideEffect; + static float const data1[] = {0,1}; + static float const data2[] = {2,3}; + static const float* const data[] = {data1, data2}; + return data; + } + + TEST(RequiredCheckArray2DCloseDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[2][2] = { {0, 1}, {2, 3} }; + + REQUIRE CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArray2DCloseDoesNotHaveSideEffectsWhenPassing_FollowOn) + { + CHECK(next); + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(RequiredCheckArray2DCloseDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[2][2] = { {0, 1}, {3, 3} }; + + REQUIRE CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); + next = true; + } + } + + TEST_FIXTURE(DoValidationOn, RequiredCheckArray2DCloseDoesNotHaveSideEffectsWhenFailing_FollowOn) + { + CHECK(!next); + CHECK_EQUAL(1, g_sideEffect); + } +} + +#endif diff --git a/tests/TestRequireMacrosWithExceptionsOn.cpp b/tests/TestRequireMacrosWithExceptionsOn.cpp new file mode 100644 index 0000000..f904708 --- /dev/null +++ b/tests/TestRequireMacrosWithExceptionsOn.cpp @@ -0,0 +1,849 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/CurrentTest.h" +#include "RecordingReporter.h" +#include "ScopedCurrentTest.h" + +using namespace std; + +#ifndef UNITTEST_NO_EXCEPTIONS + +namespace { + + TEST(RequireCheckSucceedsOnTrue) + { + bool failure = true; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK(true); + } + catch(const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + CHECK(!exception); + } + + TEST(RequiredCheckFailsOnFalse) + { + bool failure = false; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK(false); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + CHECK(exception); + } + + + TEST(RequireMacroSupportsMultipleChecks) + { + bool failure = false; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + try{ + REQUIRE + { + CHECK(true); + CHECK_EQUAL(1,1); + } + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + CHECK(!exception); + } + + + TEST(RequireMacroSupportsMultipleChecksWithFailingChecks) + { + bool failure = false; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + try{ + REQUIRE + { + CHECK(true); + CHECK_EQUAL(1,2); + } + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + CHECK(exception); + } + + TEST(RequireMacroDoesntExecuteCodeAfterAFailingCheck) + { + bool failure = false; + bool exception = false; + bool run = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + try{ + REQUIRE + { + CHECK(false); + run = true; // this shouldn't get executed. + } + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + CHECK(exception); + CHECK(!run); + } + + TEST(FailureReportsCorrectTestName) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK(false); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK_EQUAL(m_details.testName, reporter.lastFailedTest); + } + + TEST(RequiredCheckFailureIncludesCheckContents) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + const bool yaddayadda = false; + + try + { + REQUIRE CHECK(yaddayadda); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK(strstr(reporter.lastFailedMessage, "yaddayadda")); + } + + TEST(RequiredCheckEqualSucceedsOnEqual) + { + bool failure = true; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK_EQUAL(1,1); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + CHECK(!exception); + } + + TEST(RequiredCheckEqualFailsOnNotEqual) + { + bool failure = false; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK_EQUAL(1, 2); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + CHECK(exception); + } + + TEST(RequiredCheckEqualFailureContainsCorrectDetails) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + try + { + line = __LINE__; REQUIRE CHECK_EQUAL(1, 123); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK_EQUAL("testName", reporter.lastFailedTest); + CHECK_EQUAL("suiteName", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + int g_sideEffect = 0; + int FunctionWithSideEffects() + { + ++g_sideEffect; + return 1; + } + + TEST(RequiredCheckEqualDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK_EQUAL(1, FunctionWithSideEffects()); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(RequiredCheckEqualDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK_EQUAL(2, FunctionWithSideEffects()); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + CHECK_EQUAL(1, g_sideEffect); + } + + + TEST(RequiredCheckCloseSucceedsOnEqual) + { + bool failure = true; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK_CLOSE(1.0f, 1.001f, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + CHECK(!exception); + } + + TEST(RequiredCheckCloseFailsOnNotEqual) + { + bool failure = false; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK_CLOSE (1.0f, 1.1f, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + CHECK(exception); + } + + TEST(RequiredCheckCloseFailureContainsCorrectDetails) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails testDetails("test", "suite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + try + { + line = __LINE__; REQUIRE CHECK_CLOSE(1.0f, 1.1f, 0.01f); + CHECK(false); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK_EQUAL("test", reporter.lastFailedTest); + CHECK_EQUAL("suite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST(RequiredCheckCloseDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK_CLOSE (1, FunctionWithSideEffects(), 0.1f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(RequiredCheckCloseDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + try + { + REQUIRE CHECK_CLOSE(2, FunctionWithSideEffects(), 0.1f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(RequiredCheckArrayCloseSucceedsOnEqual) + { + bool failure = true; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + const float data[4] = { 0, 1, 2, 3 }; + + try + { + REQUIRE CHECK_ARRAY_CLOSE (data, data, 4, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + CHECK(!exception); + } + + TEST(RequiredCheckArrayCloseFailsOnNotEqual) + { + bool failure = false; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + try + { + REQUIRE CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + CHECK(exception); + } + + TEST(RequiredCheckArrayCloseFailureIncludesCheckExpectedAndActual) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + try + { + REQUIRE CHECK_ARRAY_CLOSE(data1, data2, 4, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); + CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); + } + + TEST(RequiredCheckArrayCloseFailureContainsCorrectDetails) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + try + { + line = __LINE__; REQUIRE CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST(RequiredCheckArrayCloseFailureIncludesTolerance) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + float const data1[4] = { 0, 1, 2, 3 }; + float const data2[4] = { 0, 1, 3, 3 }; + + try + { + REQUIRE CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK(strstr(reporter.lastFailedMessage, "0.01")); + } + + TEST(RequiredCheckArrayEqualSuceedsOnEqual) + { + bool failure = true; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + const float data[4] = { 0, 1, 2, 3 }; + + try + { + REQUIRE CHECK_ARRAY_EQUAL (data, data, 4); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + CHECK(!exception); + } + + TEST(RequiredCheckArrayEqualFailsOnNotEqual) + { + bool failure = false; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + try + { + REQUIRE CHECK_ARRAY_EQUAL (data1, data2, 4); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + CHECK(exception); + } + + TEST(RequiredCheckArrayEqualFailureIncludesCheckExpectedAndActual) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + try + { + REQUIRE CHECK_ARRAY_EQUAL (data1, data2, 4); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); + CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); + } + + TEST(RequiredCheckArrayEqualFailureContainsCorrectInfo) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[4] = { 0, 1, 2, 3 }; + int const data2[4] = { 0, 1, 3, 3 }; + + try + { + line = __LINE__; REQUIRE CHECK_ARRAY_EQUAL (data1, data2, 4); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK_EQUAL("RequiredCheckArrayEqualFailureContainsCorrectInfo", reporter.lastFailedTest); + CHECK_EQUAL(__FILE__, reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + float const* FunctionWithSideEffects2() + { + ++g_sideEffect; + static float const data[] = {1,2,3,4}; + return data; + } + + TEST(RequiredCheckArrayCloseDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[] = { 1, 2, 3, 4 }; + + REQUIRE CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(RequiredCheckArrayCloseDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[] = { 0, 1, 3, 3 }; + + try + { + REQUIRE CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(RequiredCheckArray2DCloseSucceedsOnEqual) + { + bool failure = true; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + const float data[2][2] = { {0, 1}, {2, 3} }; + + try + { + REQUIRE CHECK_ARRAY2D_CLOSE(data, data, 2, 2, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(!failure); + CHECK(!exception); + } + + TEST(RequiredCheckArray2DCloseFailsOnNotEqual) + { + bool failure = false; + bool exception = false; + { + RecordingReporter reporter; + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[2][2] = { {0, 1}, {2, 3} }; + int const data2[2][2] = { {0, 1}, {3, 3} }; + + try + { + REQUIRE CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + { + exception = true; + } + + failure = (testResults.GetFailureCount() > 0); + } + + CHECK(failure); + CHECK(exception); + } + + TEST(RequiredCheckArray2DCloseFailureIncludesCheckExpectedAndActual) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + int const data1[2][2] = { {0, 1}, {2, 3} }; + int const data2[2][2] = { {0, 1}, {3, 3} }; + + try + { + REQUIRE CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK(strstr(reporter.lastFailedMessage, "xpected [ [ 0 1 ] [ 2 3 ] ]")); + CHECK(strstr(reporter.lastFailedMessage, "was [ [ 0 1 ] [ 3 3 ] ]")); + } + + TEST(RequiredCheckArray2DCloseFailureContainsCorrectDetails) + { + int line = 0; + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); + ScopedCurrentTest scopedResults(testResults, &testDetails); + + int const data1[2][2] = { {0, 1}, {2, 3} }; + int const data2[2][2] = { {0, 1}, {3, 3} }; + + try + { + line = __LINE__; REQUIRE CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); + CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); + CHECK_EQUAL("filename", reporter.lastFailedFile); + CHECK_EQUAL(line, reporter.lastFailedLine); + } + + TEST(RequiredCheckArray2DCloseFailureIncludesTolerance) + { + RecordingReporter reporter; + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + float const data1[2][2] = { {0, 1}, {2, 3} }; + float const data2[2][2] = { {0, 1}, {3, 3} }; + + try + { + REQUIRE CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + + CHECK(strstr(reporter.lastFailedMessage, "0.01")); + } + + float const* const* FunctionWithSideEffects3() + { + ++g_sideEffect; + static float const data1[] = {0,1}; + static float const data2[] = {2,3}; + static const float* const data[] = {data1, data2}; + return data; + } + + TEST(RequiredCheckArray2DCloseDoesNotHaveSideEffectsWhenPassing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[2][2] = { {0, 1}, {2, 3} }; + + try + { + REQUIRE CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + CHECK_EQUAL(1, g_sideEffect); + } + + TEST(RequiredCheckArray2DCloseDoesNotHaveSideEffectsWhenFailing) + { + g_sideEffect = 0; + { + UnitTest::TestResults testResults; + ScopedCurrentTest scopedResults(testResults); + + const float data[2][2] = { {0, 1}, {3, 3} }; + + try + { + REQUIRE CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f); + } + catch (const UnitTest::RequiredCheckException&) + {} + } + CHECK_EQUAL(1, g_sideEffect); + } + +} + +#endif diff --git a/tests/TestTest.cpp b/tests/TestTest.cpp new file mode 100644 index 0000000..0db0650 --- /dev/null +++ b/tests/TestTest.cpp @@ -0,0 +1,133 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/TestReporter.h" +#include "UnitTest++/TimeHelpers.h" +#include "ScopedCurrentTest.h" + +using namespace UnitTest; + +namespace { + + TEST(PassingTestHasNoFailures) + { + class PassingTest : public Test + { + public: + PassingTest() : Test("passing") {} + virtual void RunImpl() const + { + CHECK(true); + } + }; + + TestResults results; + { + ScopedCurrentTest scopedResults(results); + PassingTest().Run(); + } + + CHECK_EQUAL(0, results.GetFailureCount()); + } + + + TEST(FailingTestHasFailures) + { + class FailingTest : public Test + { + public: + FailingTest() : Test("failing") {} + virtual void RunImpl() const + { + CHECK(false); + } + }; + + TestResults results; + { + ScopedCurrentTest scopedResults(results); + FailingTest().Run(); + } + + CHECK_EQUAL(1, results.GetFailureCount()); + } + +#ifndef UNITTEST_NO_EXCEPTIONS + TEST(ThrowingTestsAreReportedAsFailures) + { + class CrashingTest : public Test + { + public: + CrashingTest() : Test("throwing") {} + virtual void RunImpl() const + { + throw "Blah"; + } + }; + + TestResults results; + { + ScopedCurrentTest scopedResult(results); + CrashingTest().Run(); + } + + CHECK_EQUAL(1, results.GetFailureCount()); + } + +#if !defined(UNITTEST_MINGW) && !defined(UNITTEST_WIN32) && !defined(__clang__) +// Skip this test in debug because some debuggers don't like it. +#if defined(NDEBUG) + TEST(CrashingTestsAreReportedAsFailures) + { + class CrashingTest : public Test + { + public: + CrashingTest() : Test("crashing") {} + virtual void RunImpl() const + { + + reinterpret_cast< void (*)() >(0)(); + } + }; + + TestResults results; + { + ScopedCurrentTest scopedResult(results); + CrashingTest().Run(); + } + + CHECK_EQUAL(1, results.GetFailureCount()); + } +#endif +#endif +#endif + + TEST(TestWithUnspecifiedSuiteGetsDefaultSuite) + { + Test test("test"); + CHECK(test.m_details.suiteName != NULL); + CHECK_EQUAL("DefaultSuite", test.m_details.suiteName); + } + + TEST(TestReflectsSpecifiedSuiteName) + { + Test test("test", "testSuite"); + CHECK(test.m_details.suiteName != NULL); + CHECK_EQUAL("testSuite", test.m_details.suiteName); + } + + void Fail() + { + CHECK(false); + } + + TEST(OutOfCoreCHECKMacrosCanFailTests) + { + TestResults results; + { + ScopedCurrentTest scopedResult(results); + Fail(); + } + + CHECK_EQUAL(1, results.GetFailureCount()); + } + +} diff --git a/tests/TestTestList.cpp b/tests/TestTestList.cpp new file mode 100644 index 0000000..4a0bdcb --- /dev/null +++ b/tests/TestTestList.cpp @@ -0,0 +1,50 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/TestList.h" + +using namespace UnitTest; + +namespace { + + + TEST(TestListIsEmptyByDefault) + { + TestList list; + CHECK(list.GetHead() == 0); + } + + TEST(AddingTestSetsHeadToTest) + { + Test test("test"); + TestList list; + list.Add(&test); + + CHECK(list.GetHead() == &test); + CHECK(test.m_nextTest == 0); + } + + TEST(AddingSecondTestAddsItToEndOfList) + { + Test test1("test1"); + Test test2("test2"); + + TestList list; + list.Add(&test1); + list.Add(&test2); + + CHECK(list.GetHead() == &test1); + CHECK(test1.m_nextTest == &test2); + CHECK(test2.m_nextTest == 0); + } + + TEST(ListAdderAddsTestToList) + { + TestList list; + + Test test(""); + ListAdder adder(list, &test); + + CHECK(list.GetHead() == &test); + CHECK(test.m_nextTest == 0); + } + +} diff --git a/tests/TestTestMacros.cpp b/tests/TestTestMacros.cpp new file mode 100644 index 0000000..e66bfb6 --- /dev/null +++ b/tests/TestTestMacros.cpp @@ -0,0 +1,246 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/TestMacros.h" +#include "UnitTest++/TestList.h" +#include "UnitTest++/TestResults.h" +#include "UnitTest++/TestReporter.h" +#include "UnitTest++/ReportAssert.h" +#include "RecordingReporter.h" +#include "ScopedCurrentTest.h" + +using namespace UnitTest; +using namespace std; + +/* test for c++11 support */ +#ifndef _MSC_VER + + /* Test for clang >= 3.3 */ + #ifdef __clang__ + #if (__clang__ == 1) && (__clang_major__ > 3 || (__clang_major__ == 3 && (__clang_minor__ > 2 ))) + #define _NOEXCEPT_OP(x) noexcept(x) + #else + #define _NOEXCEPT_OP(x) + #endif + #endif + + #ifndef __clang__ + /* Test for GCC >= 4.8.0 */ + #ifdef __GNUC__ + #if (__GNUC__ > 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ > 7 )) + #define _NOEXCEPT_OP(x) noexcept(x) + #else + #define _NOEXCEPT_OP(x) + #endif + #endif + #endif + +#elif _MSC_VER + + #if (_MSC_VER > 1800) + #define _NOEXCEPT_OP(x) noexcept(x) + #else + #define _NOEXCEPT_OP(x) + #endif + +#endif + +namespace { + + TestList list1; + UNITTEST_IMPL_TEST(DummyTest, list1) + {} + + TEST (TestsAreAddedToTheListThroughMacro) + { + CHECK(list1.GetHead() != 0); + CHECK(list1.GetHead()->m_nextTest == 0); + } + +#ifndef UNITTEST_NO_EXCEPTIONS + + struct ThrowingThingie + { + ThrowingThingie() : dummy(false) + { + if (!dummy) + throw "Oops"; + } + + bool dummy; + }; + + TestList list2; + UNITTEST_IMPL_TEST_FIXTURE(ThrowingThingie, DummyTestName, list2) + {} + + TEST (ExceptionsInFixtureAreReportedAsHappeningInTheFixture) + { + RecordingReporter reporter; + TestResults result(&reporter); + { + ScopedCurrentTest scopedResults(result); + list2.GetHead()->Run(); + } + + CHECK(strstr(reporter.lastFailedMessage, "xception")); + CHECK(strstr(reporter.lastFailedMessage, "fixture")); + CHECK(strstr(reporter.lastFailedMessage, "ThrowingThingie")); + } + +#endif + + struct DummyFixture + { + int x; + }; + +// We're really testing the macros so we just want them to compile and link + SUITE(TestSuite1) + { + TEST(SimilarlyNamedTestsInDifferentSuitesWork) + {} + + TEST_FIXTURE(DummyFixture, SimilarlyNamedFixtureTestsInDifferentSuitesWork) + {} + } + + SUITE(TestSuite2) + { + TEST(SimilarlyNamedTestsInDifferentSuitesWork) + {} + + TEST_FIXTURE(DummyFixture,SimilarlyNamedFixtureTestsInDifferentSuitesWork) + {} + } + + TestList macroTestList1; + UNITTEST_IMPL_TEST(MacroTestHelper1, macroTestList1) + {} + + TEST(TestAddedWithTEST_EXMacroGetsDefaultSuite) + { + CHECK(macroTestList1.GetHead() != NULL); + CHECK_EQUAL ("MacroTestHelper1", macroTestList1.GetHead()->m_details.testName); + CHECK_EQUAL ("DefaultSuite", macroTestList1.GetHead()->m_details.suiteName); + } + + TestList macroTestList2; + UNITTEST_IMPL_TEST_FIXTURE(DummyFixture, MacroTestHelper2, macroTestList2) + {} + + TEST(TestAddedWithTEST_FIXTURE_EXMacroGetsDefaultSuite) + { + CHECK(macroTestList2.GetHead() != NULL); + CHECK_EQUAL ("MacroTestHelper2", macroTestList2.GetHead()->m_details.testName); + CHECK_EQUAL ("DefaultSuite", macroTestList2.GetHead()->m_details.suiteName); + } + +#ifndef UNITTEST_NO_EXCEPTIONS + + struct FixtureCtorThrows + { + FixtureCtorThrows() { + throw "exception"; + } + }; + + TestList throwingFixtureTestList1; + UNITTEST_IMPL_TEST_FIXTURE(FixtureCtorThrows, FixtureCtorThrowsTestName, throwingFixtureTestList1) + {} + + TEST(FixturesWithThrowingCtorsAreFailures) + { + CHECK(throwingFixtureTestList1.GetHead() != NULL); + RecordingReporter reporter; + TestResults result(&reporter); + { + ScopedCurrentTest scopedResult(result); + throwingFixtureTestList1.GetHead()->Run(); + } + + int const failureCount = result.GetFailedTestCount(); + CHECK_EQUAL(1, failureCount); + CHECK(strstr(reporter.lastFailedMessage, "while constructing fixture")); + } + + struct FixtureDtorThrows + { + ~FixtureDtorThrows() _NOEXCEPT_OP(false) { + throw "exception"; + } + }; + + TestList throwingFixtureTestList2; + UNITTEST_IMPL_TEST_FIXTURE(FixtureDtorThrows, FixtureDtorThrowsTestName, throwingFixtureTestList2) + {} + + TEST(FixturesWithThrowingDtorsAreFailures) + { + CHECK(throwingFixtureTestList2.GetHead() != NULL); + + RecordingReporter reporter; + TestResults result(&reporter); + { + ScopedCurrentTest scopedResult(result); + throwingFixtureTestList2.GetHead()->Run(); + } + + int const failureCount = result.GetFailedTestCount(); + CHECK_EQUAL(1, failureCount); + CHECK(strstr(reporter.lastFailedMessage, "while destroying fixture")); + } + + const int FailingLine = 123; + + struct FixtureCtorAsserts + { + FixtureCtorAsserts() + { + UnitTest::ReportAssert("assert failure", "file", FailingLine); + } + }; + + TestList ctorAssertFixtureTestList; + UNITTEST_IMPL_TEST_FIXTURE(FixtureCtorAsserts, CorrectlyReportsAssertFailureInCtor, ctorAssertFixtureTestList) + {} + + TEST(CorrectlyReportsFixturesWithCtorsThatAssert) + { + RecordingReporter reporter; + TestResults result(&reporter); + { + ScopedCurrentTest scopedResults(result); + ctorAssertFixtureTestList.GetHead()->Run(); + } + + const int failureCount = result.GetFailedTestCount(); + CHECK_EQUAL(1, failureCount); + CHECK_EQUAL(FailingLine, reporter.lastFailedLine); + CHECK(strstr(reporter.lastFailedMessage, "assert failure")); + } + +#endif + +} + +// We're really testing if it's possible to use the same suite in two files +// to compile and link successfuly (TestTestSuite.cpp has suite with the same name) +// Note: we are outside of the anonymous namespace +SUITE(SameTestSuite) +{ + TEST(DummyTest1) + {} +} + +#define CUR_TEST_NAME CurrentTestDetailsContainCurrentTestInfo +#define INNER_STRINGIFY(X) #X +#define STRINGIFY(X) INNER_STRINGIFY(X) + +TEST(CUR_TEST_NAME) +{ + const UnitTest::TestDetails* details = CurrentTest::Details(); + CHECK_EQUAL(STRINGIFY(CUR_TEST_NAME), details->testName); +} + +#undef CUR_TEST_NAME +#undef INNER_STRINGIFY +#undef STRINGIFY diff --git a/tests/TestTestResults.cpp b/tests/TestTestResults.cpp new file mode 100644 index 0000000..1f66744 --- /dev/null +++ b/tests/TestTestResults.cpp @@ -0,0 +1,111 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/TestResults.h" +#include "RecordingReporter.h" + +using namespace UnitTest; + +namespace { + + TestDetails const details("testname", "suitename", "filename", 123); + + + TEST(StartsWithNoTestsRun) + { + TestResults results; + CHECK_EQUAL (0, results.GetTotalTestCount()); + } + + TEST(RecordsNumbersOfTests) + { + TestResults results; + results.OnTestStart(details); + results.OnTestStart(details); + results.OnTestStart(details); + CHECK_EQUAL(3, results.GetTotalTestCount()); + } + + TEST(StartsWithNoTestsFailing) + { + TestResults results; + CHECK_EQUAL (0, results.GetFailureCount()); + } + + TEST(RecordsNumberOfFailures) + { + TestResults results; + results.OnTestFailure(details, ""); + results.OnTestFailure(details, ""); + CHECK_EQUAL(2, results.GetFailureCount()); + } + + TEST(RecordsNumberOfFailedTests) + { + TestResults results; + + results.OnTestStart(details); + results.OnTestFailure(details, ""); + results.OnTestFinish(details, 0); + + results.OnTestStart(details); + results.OnTestFailure(details, ""); + results.OnTestFailure(details, ""); + results.OnTestFailure(details, ""); + results.OnTestFinish(details, 0); + + CHECK_EQUAL (2, results.GetFailedTestCount()); + } + + TEST(NotifiesReporterOfTestStartWithCorrectInfo) + { + RecordingReporter reporter; + TestResults results(&reporter); + results.OnTestStart(details); + + CHECK_EQUAL (1, reporter.testRunCount); + CHECK_EQUAL ("suitename", reporter.lastStartedSuite); + CHECK_EQUAL ("testname", reporter.lastStartedTest); + } + + TEST(NotifiesReporterOfTestFailureWithCorrectInfo) + { + RecordingReporter reporter; + TestResults results(&reporter); + + results.OnTestFailure(details, "failurestring"); + CHECK_EQUAL (1, reporter.testFailedCount); + CHECK_EQUAL ("filename", reporter.lastFailedFile); + CHECK_EQUAL (123, reporter.lastFailedLine); + CHECK_EQUAL ("suitename", reporter.lastFailedSuite); + CHECK_EQUAL ("testname", reporter.lastFailedTest); + CHECK_EQUAL ("failurestring", reporter.lastFailedMessage); + } + + TEST(NotifiesReporterOfCheckFailureWithCorrectInfo) + { + RecordingReporter reporter; + TestResults results(&reporter); + + results.OnTestFailure(details, "failurestring"); + CHECK_EQUAL (1, reporter.testFailedCount); + + CHECK_EQUAL ("filename", reporter.lastFailedFile); + CHECK_EQUAL (123, reporter.lastFailedLine); + CHECK_EQUAL ("testname", reporter.lastFailedTest); + CHECK_EQUAL ("suitename", reporter.lastFailedSuite); + CHECK_EQUAL ("failurestring", reporter.lastFailedMessage); + } + + TEST(NotifiesReporterOfTestEnd) + { + RecordingReporter reporter; + TestResults results(&reporter); + + results.OnTestFinish(details, 0.1234f); + CHECK_EQUAL (1, reporter.testFinishedCount); + CHECK_EQUAL ("testname", reporter.lastFinishedTest); + CHECK_EQUAL ("suitename", reporter.lastFinishedSuite); + CHECK_CLOSE (0.1234f, reporter.lastFinishedTestTime, 0.0001f); + } + + +} diff --git a/tests/TestTestRunner.cpp b/tests/TestTestRunner.cpp new file mode 100644 index 0000000..86c672d --- /dev/null +++ b/tests/TestTestRunner.cpp @@ -0,0 +1,333 @@ +#include "UnitTest++/UnitTestPP.h" +#include "RecordingReporter.h" +#include "UnitTest++/ReportAssert.h" +#include "UnitTest++/TestList.h" +#include "UnitTest++/TimeHelpers.h" +#include "UnitTest++/TimeConstraint.h" +#include "UnitTest++/ReportAssertImpl.h" + +using namespace UnitTest; + +namespace +{ + + struct MockTest : public Test + { + MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1) + : Test(testName) + , success(success_) + , asserted(assert_) + , count(count_) + {} + + virtual void RunImpl() const + { + TestResults& testResults_ = *CurrentTest::Results(); + + for (int i=0; i < count; ++i) + { + if (asserted) + { + ReportAssert("desc", "file", 0); + } + else if (!success) + { + testResults_.OnTestFailure(m_details, "message"); + } + } + } + + bool const success; + bool const asserted; + int const count; + }; + + struct FixtureBase + { + FixtureBase() + : runner(reporter) + {} + + template + int RunTestsIf(TestList const& list, char const* suiteName, + const Predicate& predicate, int maxTestTimeInMs) + { + TestResults* oldResults = CurrentTest::Results(); + const TestDetails* oldDetails = CurrentTest::Details(); + int result = runner.RunTestsIf(list, suiteName, predicate, maxTestTimeInMs); + CurrentTest::Results() = oldResults; + CurrentTest::Details() = oldDetails; + return result; + } + + TestRunner runner; + RecordingReporter reporter; + }; + + struct TestRunnerFixture : public FixtureBase + { + TestList list; + }; + + TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly) + { + MockTest test("goodtest", true, false); + list.Add(&test); + + RunTestsIf(list, NULL, True(), 0); + CHECK_EQUAL(1, reporter.testRunCount); + CHECK_EQUAL("goodtest", reporter.lastStartedTest); + } + + TEST_FIXTURE(TestRunnerFixture, TestFinishIsReportedCorrectly) + { + MockTest test("goodtest", true, false); + list.Add(&test); + + RunTestsIf(list, NULL, True(), 0); + CHECK_EQUAL(1, reporter.testFinishedCount); + CHECK_EQUAL("goodtest", reporter.lastFinishedTest); + } + + class SlowTest : public Test + { + public: + SlowTest() + : Test("slow", "somesuite", "filename", 123) + {} + + virtual void RunImpl() const + { + TimeHelpers::SleepMs(20); + } + }; + + TEST_FIXTURE(TestRunnerFixture, TestFinishIsCalledWithCorrectTime) + { + SlowTest test; + list.Add(&test); + + // Using UnitTest::Timer here is arguably a bit hokey and self-referential, but + // it should guarantee that the test time recorded is less than that plus the + // overhead of RunTestsIf -- the only thing we can reliably assert without + // reworking the test to not use sleeps at all + Timer actual; + actual.Start(); + RunTestsIf(list, NULL, True(), 0); + + CHECK(reporter.lastFinishedTestTime >= 0.005f && reporter.lastFinishedTestTime <= actual.GetTimeInMs()); + } + + TEST_FIXTURE(TestRunnerFixture, FailureCountIsZeroWhenNoTestsAreRun) + { + CHECK_EQUAL(0, RunTestsIf(list, NULL, True(), 0)); + CHECK_EQUAL(0, reporter.testRunCount); + CHECK_EQUAL(0, reporter.testFailedCount); + } + + TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest) + { + MockTest test1("test", false, false); + list.Add(&test1); + MockTest test2("test", true, false); + list.Add(&test2); + MockTest test3("test", false, false); + list.Add(&test3); + + CHECK_EQUAL(2, RunTestsIf(list, NULL, True(), 0)); + CHECK_EQUAL(2, reporter.testFailedCount); + } + + TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing) + { + MockTest test("test", true, true); + list.Add(&test); + + RunTestsIf(list, NULL, True(), 0); + CHECK_EQUAL(1, reporter.testFailedCount); + } + + + TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount) + { + MockTest test1("test", true, false); + MockTest test2("test", true, false); + MockTest test3("test", true, false); + list.Add(&test1); + list.Add(&test2); + list.Add(&test3); + + RunTestsIf(list, NULL, True(), 0); + CHECK_EQUAL(3, reporter.summaryTotalTestCount); + } + + TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailedTests) + { + MockTest test1("test", false, false, 2); + MockTest test2("test", true, false); + MockTest test3("test", false, false, 3); + list.Add(&test1); + list.Add(&test2); + list.Add(&test3); + + RunTestsIf(list, NULL, True(), 0); + CHECK_EQUAL(2, reporter.summaryFailedTestCount); + } + + TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailures) + { + MockTest test1("test", false, false, 2); + MockTest test2("test", true, false); + MockTest test3("test", false, false, 3); + list.Add(&test1); + list.Add(&test2); + list.Add(&test3); + + RunTestsIf(list, NULL, True(), 0); + CHECK_EQUAL(5, reporter.summaryFailureCount); + } + + TEST_FIXTURE(TestRunnerFixture, SlowTestPassesForHighTimeThreshold) + { + SlowTest test; + list.Add(&test); + + RunTestsIf(list, NULL, True(), 0); + CHECK_EQUAL(0, reporter.testFailedCount); + } + + TEST_FIXTURE(TestRunnerFixture, SlowTestFailsForLowTimeThreshold) + { + SlowTest test; + list.Add(&test); + + RunTestsIf(list, NULL, True(), 3); + CHECK_EQUAL(1, reporter.testFailedCount); + } + + TEST_FIXTURE(TestRunnerFixture, SlowTestHasCorrectFailureInformation) + { + SlowTest test; + list.Add(&test); + + RunTestsIf(list, NULL, True(), 3); + + using namespace std; + + CHECK_EQUAL(test.m_details.testName, reporter.lastFailedTest); + CHECK(strstr(test.m_details.filename, reporter.lastFailedFile)); + CHECK_EQUAL(test.m_details.lineNumber, reporter.lastFailedLine); + + CHECK(strstr(reporter.lastFailedMessage, "Global time constraint failed")); + CHECK(strstr(reporter.lastFailedMessage, "3ms")); + } + + TEST_FIXTURE(TestRunnerFixture, SlowTestWithTimeExemptionPasses) + { + class SlowExemptedTest : public Test + { + public: + SlowExemptedTest() : Test("slowexempted", "", 0) {} + virtual void RunImpl() const + { + UNITTEST_TIME_CONSTRAINT_EXEMPT(); + TimeHelpers::SleepMs(20); + } + }; + + SlowExemptedTest test; + list.Add(&test); + + RunTestsIf(list, NULL, True(), 3); + CHECK_EQUAL(0, reporter.testFailedCount); + } + + struct TestSuiteFixture : FixtureBase + { + TestSuiteFixture() + : test1("TestInDefaultSuite") + , test2("TestInOtherSuite", "OtherSuite") + , test3("SecondTestInDefaultSuite") + { + list.Add(&test1); + list.Add(&test2); + } + + Test test1; + Test test2; + Test test3; + TestList list; + }; + + TEST_FIXTURE(TestSuiteFixture, TestRunnerRunsAllSuitesIfNullSuiteIsPassed) + { + RunTestsIf(list, NULL, True(), 0); + CHECK_EQUAL(2, reporter.summaryTotalTestCount); + } + + TEST_FIXTURE(TestSuiteFixture,TestRunnerRunsOnlySpecifiedSuite) + { + RunTestsIf(list, "OtherSuite", True(), 0); + CHECK_EQUAL(1, reporter.summaryTotalTestCount); + CHECK_EQUAL("TestInOtherSuite", reporter.lastFinishedTest); + } + + struct RunTestIfNameIs + { + RunTestIfNameIs(char const* name_) + : name(name_) + {} + + bool operator()(const Test* const test) const + { + using namespace std; + return (0 == strcmp(test->m_details.testName, name)); + } + + char const* name; + }; + + TEST(TestMockPredicateBehavesCorrectly) + { + RunTestIfNameIs predicate("pass"); + + Test pass("pass"); + Test fail("fail"); + + CHECK(predicate(&pass)); + CHECK(!predicate(&fail)); + } + + TEST_FIXTURE(TestRunnerFixture, TestRunnerRunsTestsThatPassPredicate) + { + Test should_run("goodtest"); + list.Add(&should_run); + + Test should_not_run("badtest"); + list.Add(&should_not_run); + + RunTestsIf(list, NULL, RunTestIfNameIs("goodtest"), 0); + CHECK_EQUAL(1, reporter.testRunCount); + CHECK_EQUAL("goodtest", reporter.lastStartedTest); + } + + TEST_FIXTURE(TestRunnerFixture, TestRunnerOnlyRunsTestsInSpecifiedSuiteAndThatPassPredicate) + { + Test runningTest1("goodtest", "suite"); + Test skippedTest2("goodtest"); + Test skippedTest3("badtest", "suite"); + Test skippedTest4("badtest"); + + list.Add(&runningTest1); + list.Add(&skippedTest2); + list.Add(&skippedTest3); + list.Add(&skippedTest4); + + RunTestsIf(list, "suite", RunTestIfNameIs("goodtest"), 0); + + CHECK_EQUAL(1, reporter.testRunCount); + CHECK_EQUAL("goodtest", reporter.lastStartedTest); + CHECK_EQUAL("suite", reporter.lastStartedSuite); + } + +} diff --git a/src/tests/TestTestSuite.cpp b/tests/TestTestSuite.cpp similarity index 76% rename from src/tests/TestTestSuite.cpp rename to tests/TestTestSuite.cpp index 07e51cd..e0bbacf 100644 --- a/src/tests/TestTestSuite.cpp +++ b/tests/TestTestSuite.cpp @@ -1,12 +1,11 @@ -#include "../../unittestpp.h" - -// We're really testing if it's possible to use the same suite in two files -// to compile and link successfuly (TestTestSuite.cpp has suite with the same name) -// Note: we are outside of the anonymous namespace -SUITE(SameTestSuite) -{ - TEST(DummyTest2) - { - } -} - +#include "UnitTest++/UnitTestPP.h" + +// We're really testing if it's possible to use the same suite in two files +// to compile and link successfuly (TestTestSuite.cpp has suite with the same name) +// Note: we are outside of the anonymous namespace +SUITE(SameTestSuite) +{ + TEST(DummyTest2) + {} +} + diff --git a/tests/TestTimeConstraint.cpp b/tests/TestTimeConstraint.cpp new file mode 100644 index 0000000..976b8ce --- /dev/null +++ b/tests/TestTimeConstraint.cpp @@ -0,0 +1,69 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/TestResults.h" +#include "UnitTest++/TimeHelpers.h" +#include "RecordingReporter.h" +#include "ScopedCurrentTest.h" + +using namespace UnitTest; + +namespace +{ + + TEST(TimeConstraintSucceedsWithFastTest) + { + TestResults result; + { + ScopedCurrentTest scopedResult(result); + TimeConstraint t(200, TestDetails("", "", "", 0), 0); + TimeHelpers::SleepMs(5); + } + CHECK_EQUAL(0, result.GetFailureCount()); + } + + TEST(TimeConstraintFailsWithSlowTest) + { + TestResults result; + { + ScopedCurrentTest scopedResult(result); + TimeConstraint t(10, TestDetails("", "", "", 0),0); + TimeHelpers::SleepMs(20); + } + CHECK_EQUAL(1, result.GetFailureCount()); + } + + TEST(TimeConstraintFailureIncludesCorrectData) + { + RecordingReporter reporter; + TestResults result(&reporter); + { + ScopedCurrentTest scopedResult(result); + + TestDetails const details("testname", "suitename", "filename", 10); + TimeConstraint t(10, details,10); + TimeHelpers::SleepMs(20); + } + + using namespace std; + + CHECK(strstr(reporter.lastFailedFile, "filename")); + CHECK_EQUAL(10, reporter.lastFailedLine); + CHECK(strstr(reporter.lastFailedTest, "testname")); + } + + TEST(TimeConstraintFailureIncludesTimeoutInformation) + { + RecordingReporter reporter; + TestResults result(&reporter); + { + ScopedCurrentTest scopedResult(result); + TimeConstraint t(10, TestDetails("", "", "", 0),0); + TimeHelpers::SleepMs(20); + } + + using namespace std; + + CHECK(strstr(reporter.lastFailedMessage, "ime constraint")); + CHECK(strstr(reporter.lastFailedMessage, "under 10ms")); + } + +} diff --git a/tests/TestTimeConstraintMacro.cpp b/tests/TestTimeConstraintMacro.cpp new file mode 100644 index 0000000..a8d0c79 --- /dev/null +++ b/tests/TestTimeConstraintMacro.cpp @@ -0,0 +1,88 @@ +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/TimeHelpers.h" + +#include "RecordingReporter.h" +#include "ScopedCurrentTest.h" + +namespace { + + TEST(TimeConstraintMacroQualifiesNamespace) + { + // If this compiles without a "using namespace UnitTest;", all is well. + UNITTEST_TIME_CONSTRAINT(1); + } + + TEST(TimeConstraintMacroUsesCorrectInfo) + { + int testLine = 0; + RecordingReporter reporter; + + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + UNITTEST_TIME_CONSTRAINT(10); testLine = __LINE__; + UnitTest::TimeHelpers::SleepMs(20); + } + + using namespace std; + + CHECK_EQUAL(1, reporter.testFailedCount); + CHECK(strstr(reporter.lastFailedFile, __FILE__)); + CHECK_EQUAL(testLine, reporter.lastFailedLine); + CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroUsesCorrectInfo")); + } + + TEST(TimeConstraintMacroComparesAgainstPreciseActual) + { + int testLine = 0; + RecordingReporter reporter; + + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + UNITTEST_TIME_CONSTRAINT(1); testLine = __LINE__; + + // start a new timer and run until we're as little over the 1 msec + // threshold as we can achieve; this should guarantee that the "test" + // runs in some very small amount of time > 1 msec + UnitTest::Timer myTimer; + myTimer.Start(); + + while (myTimer.GetTimeInMs() < 1.001) + UnitTest::TimeHelpers::SleepMs(0); + } + + using namespace std; + + CHECK_EQUAL(1, reporter.testFailedCount); + CHECK(strstr(reporter.lastFailedFile, __FILE__)); + CHECK_EQUAL(testLine, reporter.lastFailedLine); + CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroComparesAgainstPreciseActual")); + } + + struct EmptyFixture {}; + + TEST_FIXTURE(EmptyFixture, TimeConstraintMacroWorksInFixtures) + { + int testLine = 0; + RecordingReporter reporter; + + { + UnitTest::TestResults testResults(&reporter); + ScopedCurrentTest scopedResults(testResults); + + UNITTEST_TIME_CONSTRAINT(10); testLine = __LINE__; + UnitTest::TimeHelpers::SleepMs(20); + } + + using namespace std; + + CHECK_EQUAL(1, reporter.testFailedCount); + CHECK(strstr(reporter.lastFailedFile, __FILE__)); + CHECK_EQUAL(testLine, reporter.lastFailedLine); + CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroWorksInFixtures")); + } + +} diff --git a/tests/TestUnitTestPP.cpp b/tests/TestUnitTestPP.cpp new file mode 100644 index 0000000..831b360 --- /dev/null +++ b/tests/TestUnitTestPP.cpp @@ -0,0 +1,147 @@ +#include "UnitTest++/UnitTestPP.h" +#include "ScopedCurrentTest.h" + +// These are sample tests that show the different features of the framework + +namespace { + + TEST(ValidCheckSucceeds) + { + bool const b = true; + CHECK(b); + } + + TEST(CheckWorksWithPointers) + { + void* p = (void *)0x100; + CHECK(p); + CHECK(p != 0); + } + + TEST(ValidCheckEqualSucceeds) + { + int const x = 3; + int const y = 3; + CHECK_EQUAL(x, y); + } + + TEST(CheckEqualWorksWithPointers) + { + void* p = (void *)0; + CHECK_EQUAL((void*)0, p); + } + + TEST(ValidCheckCloseSucceeds) + { + CHECK_CLOSE(2.0f, 2.001f, 0.01f); + CHECK_CLOSE(2.001f, 2.0f, 0.01f); + } + + TEST(ArrayCloseSucceeds) + { + float const a1[] = {1, 2, 3}; + float const a2[] = {1, 2.01f, 3}; + CHECK_ARRAY_CLOSE(a1, a2, 3, 0.1f); + } + +#ifndef UNITTEST_NO_EXCEPTIONS + + TEST(CheckThrowMacroSucceedsOnCorrectException) + { + struct TestException {}; + CHECK_THROW(throw TestException(), TestException); + } + + TEST(CheckAssertSucceeds) + { + CHECK_ASSERT(UnitTest::ReportAssert("desc", "file", 0)); + } + + TEST(CheckThrowMacroFailsOnMissingException) + { + class NoThrowTest : public UnitTest::Test + { + public: + NoThrowTest() : Test("nothrow") {} + void DontThrow() const + {} + + virtual void RunImpl() const + { + CHECK_THROW(DontThrow(), int); + } + }; + + UnitTest::TestResults results; + { + ScopedCurrentTest scopedResults(results); + + NoThrowTest test; + test.Run(); + } + + CHECK_EQUAL(1, results.GetFailureCount()); + } + + TEST(CheckThrowMacroFailsOnWrongException) + { + class WrongThrowTest : public UnitTest::Test + { + public: + WrongThrowTest() : Test("wrongthrow") {} + virtual void RunImpl() const + { + CHECK_THROW(throw "oops", int); + } + }; + + UnitTest::TestResults results; + { + ScopedCurrentTest scopedResults(results); + + WrongThrowTest test; + test.Run(); + } + + CHECK_EQUAL(1, results.GetFailureCount()); + } + +#endif + + struct SimpleFixture + { + SimpleFixture() + { + ++instanceCount; + } + ~SimpleFixture() + { + --instanceCount; + } + + static int instanceCount; + }; + + int SimpleFixture::instanceCount = 0; + + TEST_FIXTURE(SimpleFixture, DefaultFixtureCtorIsCalled) + { + CHECK(SimpleFixture::instanceCount > 0); + } + + TEST_FIXTURE(SimpleFixture, OnlyOneFixtureAliveAtATime) + { + CHECK_EQUAL(1, SimpleFixture::instanceCount); + } + + void CheckBool(const bool b) + { + CHECK(b); + } + + TEST(CanCallCHECKOutsideOfTestFunction) + { + CheckBool(true); + } + +} diff --git a/tests/TestXmlTestReporter.cpp b/tests/TestXmlTestReporter.cpp new file mode 100644 index 0000000..a3edde2 --- /dev/null +++ b/tests/TestXmlTestReporter.cpp @@ -0,0 +1,187 @@ +#include "UnitTest++/Config.h" +#ifndef UNITTEST_NO_DEFERRED_REPORTER + +#include "UnitTest++/UnitTestPP.h" +#include "UnitTest++/XmlTestReporter.h" + +#include + +using namespace UnitTest; +using std::ostringstream; + +namespace +{ + +#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM + +// Overload to let MemoryOutStream accept std::string + MemoryOutStream& operator<<(MemoryOutStream& s, const std::string& value) + { + s << value.c_str(); + return s; + } + +#endif + + struct XmlTestReporterFixture + { + XmlTestReporterFixture() + : reporter(output) + {} + + ostringstream output; + XmlTestReporter reporter; + }; + + TEST_FIXTURE(XmlTestReporterFixture, MultipleCharactersAreEscaped) + { + TestDetails const details("TestName", "suite", "filename.h", 4321); + + reporter.ReportTestStart(details); + reporter.ReportFailure(details, "\"\"\'\'&&<<>>"); + reporter.ReportTestFinish(details, 0.1f); + reporter.ReportSummary(1, 2, 3, 0.1f); + + char const* expected = + "" + "" + "" + "" + "" + ""; + + CHECK_EQUAL(expected, output.str().c_str()); + } + + TEST_FIXTURE(XmlTestReporterFixture, OutputIsCachedUntilReportSummaryIsCalled) + { + TestDetails const details("", "", "", 0); + + reporter.ReportTestStart(details); + reporter.ReportFailure(details, "message"); + reporter.ReportTestFinish(details, 1.0F); + CHECK(output.str().empty()); + + reporter.ReportSummary(1, 1, 1, 1.0f); + CHECK(!output.str().empty()); + } + + TEST_FIXTURE(XmlTestReporterFixture, EmptyReportSummaryFormat) + { + reporter.ReportSummary(0, 0, 0, 0.1f); + + const char *expected = + "" + "" + ""; + + CHECK_EQUAL(expected, output.str().c_str()); + } + + TEST_FIXTURE(XmlTestReporterFixture, SingleSuccessfulTestReportSummaryFormat) + { + TestDetails const details("TestName", "DefaultSuite", "", 0); + + reporter.ReportTestStart(details); + reporter.ReportSummary(1, 0, 0, 0.1f); + + const char *expected = + "" + "" + "" + ""; + + CHECK_EQUAL(expected, output.str().c_str()); + } + + TEST_FIXTURE(XmlTestReporterFixture, SingleFailedTestReportSummaryFormat) + { + TestDetails const details("A Test", "suite", "A File", 4321); + + reporter.ReportTestStart(details); + reporter.ReportFailure(details, "A Failure"); + reporter.ReportSummary(1, 1, 1, 0.1f); + + const char *expected = + "" + "" + "" + "" + "" + ""; + + CHECK_EQUAL(expected, output.str().c_str()); + } + + TEST_FIXTURE(XmlTestReporterFixture, FailureMessageIsXMLEscaped) + { + TestDetails const details("TestName", "suite", "filename.h", 4321); + + reporter.ReportTestStart(details); + reporter.ReportFailure(details, "\"\'&<>"); + reporter.ReportTestFinish(details, 0.1f); + reporter.ReportSummary(1, 1, 1, 0.1f); + + char const* expected = + "" + "" + "" + "" + "" + ""; + + CHECK_EQUAL(expected, output.str().c_str()); + } + + TEST_FIXTURE(XmlTestReporterFixture, OneFailureAndOneSuccess) + { + TestDetails const failedDetails("FailedTest", "suite", "fail.h", 1); + reporter.ReportTestStart(failedDetails); + reporter.ReportFailure(failedDetails, "expected 1 but was 2"); + reporter.ReportTestFinish(failedDetails, 0.1f); + + TestDetails const succeededDetails("SucceededTest", "suite", "", 0); + reporter.ReportTestStart(succeededDetails); + reporter.ReportTestFinish(succeededDetails, 1.0f); + reporter.ReportSummary(2, 1, 1, 1.1f); + + char const* expected = + "" + "" + "" + "" + "" + "" + ""; + + CHECK_EQUAL(expected, output.str().c_str()); + } + + TEST_FIXTURE(XmlTestReporterFixture, MultipleFailures) + { + TestDetails const failedDetails1("FailedTest", "suite", "fail.h", 1); + TestDetails const failedDetails2("FailedTest", "suite", "fail.h", 31); + + reporter.ReportTestStart(failedDetails1); + reporter.ReportFailure(failedDetails1, "expected 1 but was 2"); + reporter.ReportFailure(failedDetails2, "expected one but was two"); + reporter.ReportTestFinish(failedDetails1, 0.1f); + + reporter.ReportSummary(1, 1, 2, 1.1f); + + char const* expected = + "" + "" + "" + "" + "" + "" + ""; + + CHECK_EQUAL(expected, output.str().c_str()); + } + +} + +#endif diff --git a/unittestpp.h b/unittestpp.h deleted file mode 100644 index b66b2c4..0000000 --- a/unittestpp.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef UNITTESTPP_H -#define UNITTESTPP_H - -#include "config.h" -#include "src/TestMacros.h" -#include "src/CheckMacros.h" -#include "src/TestRunner.h" -#include "src/TimeConstraint.h" -#include "src/ReportAssert.h" - -#endif diff --git a/unittestpp_vs2005.sln b/unittestpp_vs2005.sln deleted file mode 100644 index 3bb7617..0000000 --- a/unittestpp_vs2005.sln +++ /dev/null @@ -1,49 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittestpp_vs2005", "src\unittestpp_vs2005.vcproj", "{64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-unittestpp_vs2005", "src\tests\test-unittestpp_vs2005.vcproj", "{9CCC3439-309E-4E85-B3B8-CE704D385D48}" - ProjectSection(ProjectDependencies) = postProject - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6} = {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - win32_dll_vc80_debug|Win32 = win32_dll_vc80_debug|Win32 - win32_dll_vc80_release|Win32 = win32_dll_vc80_release|Win32 - win32_static_vc80_md_debug|Win32 = win32_static_vc80_md_debug|Win32 - win32_static_vc80_md_release|Win32 = win32_static_vc80_md_release|Win32 - win32_static_vc80_mt_debug|Win32 = win32_static_vc80_mt_debug|Win32 - win32_static_vc80_mt_release|Win32 = win32_static_vc80_mt_release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc80_debug|Win32.ActiveCfg = win32_dll_vc80_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc80_debug|Win32.Build.0 = win32_dll_vc80_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc80_release|Win32.ActiveCfg = win32_dll_vc80_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc80_release|Win32.Build.0 = win32_dll_vc80_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_md_debug|Win32.ActiveCfg = win32_static_vc80_md_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_md_debug|Win32.Build.0 = win32_static_vc80_md_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_md_release|Win32.ActiveCfg = win32_static_vc80_md_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_md_release|Win32.Build.0 = win32_static_vc80_md_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_mt_debug|Win32.ActiveCfg = win32_static_vc80_mt_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_mt_debug|Win32.Build.0 = win32_static_vc80_mt_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_mt_release|Win32.ActiveCfg = win32_static_vc80_mt_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_mt_release|Win32.Build.0 = win32_static_vc80_mt_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc80_debug|Win32.ActiveCfg = win32_dll_vc80_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc80_debug|Win32.Build.0 = win32_dll_vc80_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc80_release|Win32.ActiveCfg = win32_dll_vc80_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc80_release|Win32.Build.0 = win32_dll_vc80_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_md_debug|Win32.ActiveCfg = win32_static_vc80_md_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_md_debug|Win32.Build.0 = win32_static_vc80_md_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_md_release|Win32.ActiveCfg = win32_static_vc80_md_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_md_release|Win32.Build.0 = win32_static_vc80_md_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_mt_debug|Win32.ActiveCfg = win32_static_vc80_mt_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_mt_debug|Win32.Build.0 = win32_static_vc80_mt_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_mt_release|Win32.ActiveCfg = win32_static_vc80_mt_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_mt_release|Win32.Build.0 = win32_static_vc80_mt_release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/unittestpp_vs2008.sln b/unittestpp_vs2008.sln deleted file mode 100644 index f7004a4..0000000 --- a/unittestpp_vs2008.sln +++ /dev/null @@ -1,49 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittestpp_vs2008", "src\unittestpp_vs2008.vcproj", "{64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-unittestpp_vs2008", "src\tests\test-unittestpp_vs2008.vcproj", "{9CCC3439-309E-4E85-B3B8-CE704D385D48}" - ProjectSection(ProjectDependencies) = postProject - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6} = {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - win32_dll_vc90_debug|Win32 = win32_dll_vc90_debug|Win32 - win32_dll_vc90_release|Win32 = win32_dll_vc90_release|Win32 - win32_static_vc90_md_debug|Win32 = win32_static_vc90_md_debug|Win32 - win32_static_vc90_md_release|Win32 = win32_static_vc90_md_release|Win32 - win32_static_vc90_mt_debug|Win32 = win32_static_vc90_mt_debug|Win32 - win32_static_vc90_mt_release|Win32 = win32_static_vc90_mt_release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc90_debug|Win32.ActiveCfg = win32_dll_vc90_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc90_debug|Win32.Build.0 = win32_dll_vc90_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc90_release|Win32.ActiveCfg = win32_dll_vc90_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc90_release|Win32.Build.0 = win32_dll_vc90_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_md_debug|Win32.ActiveCfg = win32_static_vc90_md_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_md_debug|Win32.Build.0 = win32_static_vc90_md_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_md_release|Win32.ActiveCfg = win32_static_vc90_md_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_md_release|Win32.Build.0 = win32_static_vc90_md_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_mt_debug|Win32.ActiveCfg = win32_static_vc90_mt_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_mt_debug|Win32.Build.0 = win32_static_vc90_mt_debug|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_mt_release|Win32.ActiveCfg = win32_static_vc90_mt_release|Win32 - {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_mt_release|Win32.Build.0 = win32_static_vc90_mt_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc90_debug|Win32.ActiveCfg = win32_dll_vc90_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc90_debug|Win32.Build.0 = win32_dll_vc90_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc90_release|Win32.ActiveCfg = win32_dll_vc90_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc90_release|Win32.Build.0 = win32_dll_vc90_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_md_debug|Win32.ActiveCfg = win32_static_vc90_md_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_md_debug|Win32.Build.0 = win32_static_vc90_md_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_md_release|Win32.ActiveCfg = win32_static_vc90_md_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_md_release|Win32.Build.0 = win32_static_vc90_md_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_mt_debug|Win32.ActiveCfg = win32_static_vc90_mt_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_mt_debug|Win32.Build.0 = win32_static_vc90_mt_debug|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_mt_release|Win32.ActiveCfg = win32_static_vc90_mt_release|Win32 - {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_mt_release|Win32.Build.0 = win32_static_vc90_mt_release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal