From e8b339d25bb319a9b8e2e2b529f3c42304631b62 Mon Sep 17 00:00:00 2001 From: mutouyun Date: Sun, 6 Sep 2020 21:33:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8=20gtest=20=E6=9B=BF=E6=8D=A2?= =?UTF-8?q?=20qtest=EF=BC=8C=E6=B5=8B=E8=AF=95=E4=B8=8D=E5=86=8D=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=20qt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- .travis.yml | 19 +- {test => 3rdparty}/capo/random.hpp | 0 {test => 3rdparty}/capo/spin_lock.hpp | 0 {test => 3rdparty}/capo/stopwatch.hpp | 0 3rdparty/gperftools/libtcmalloc_minimal.so.4 | 1 + .../gperftools/libtcmalloc_minimal.so.4.5.3 | 1 + {test => 3rdparty}/gperftools/tcmalloc.h | 0 3rdparty/gtest/CMakeLists.txt | 328 + 3rdparty/gtest/CONTRIBUTORS | 37 + 3rdparty/gtest/LICENSE | 28 + 3rdparty/gtest/README.md | 244 + 3rdparty/gtest/cmake/Config.cmake.in | 9 + 3rdparty/gtest/cmake/gtest.pc.in | 10 + 3rdparty/gtest/cmake/gtest_main.pc.in | 11 + 3rdparty/gtest/cmake/internal_utils.cmake | 358 + 3rdparty/gtest/cmake/libgtest.la.in | 21 + 3rdparty/gtest/docs/advanced.md | 2567 ++++++ 3rdparty/gtest/docs/faq.md | 753 ++ 3rdparty/gtest/docs/pkgconfig.md | 141 + 3rdparty/gtest/docs/primer.md | 567 ++ 3rdparty/gtest/docs/pump_manual.md | 190 + 3rdparty/gtest/docs/samples.md | 22 + .../gtest/include/gtest/gtest-death-test.h | 343 + 3rdparty/gtest/include/gtest/gtest-matchers.h | 750 ++ 3rdparty/gtest/include/gtest/gtest-message.h | 218 + .../gtest/include/gtest/gtest-param-test.h | 503 ++ 3rdparty/gtest/include/gtest/gtest-printers.h | 928 ++ 3rdparty/gtest/include/gtest/gtest-spi.h | 238 + .../gtest/include/gtest/gtest-test-part.h | 184 + .../gtest/include/gtest/gtest-typed-test.h | 330 + 3rdparty/gtest/include/gtest/gtest.h | 2478 ++++++ .../gtest/include/gtest/gtest_pred_impl.h | 359 + 3rdparty/gtest/include/gtest/gtest_prod.h | 61 + .../include/gtest/internal/custom/README.md | 56 + .../gtest/internal/custom/gtest-port.h | 37 + .../gtest/internal/custom/gtest-printers.h | 42 + .../include/gtest/internal/custom/gtest.h | 37 + .../internal/gtest-death-test-internal.h | 304 + .../include/gtest/internal/gtest-filepath.h | 211 + .../include/gtest/internal/gtest-internal.h | 1380 +++ .../include/gtest/internal/gtest-param-util.h | 883 ++ .../include/gtest/internal/gtest-port-arch.h | 107 + .../gtest/include/gtest/internal/gtest-port.h | 2231 +++++ .../include/gtest/internal/gtest-string.h | 171 + .../include/gtest/internal/gtest-type-util.h | 3335 ++++++++ .../gtest/internal/gtest-type-util.h.pump | 302 + 3rdparty/gtest/samples/prime_tables.h | 126 + 3rdparty/gtest/samples/sample1.cc | 66 + 3rdparty/gtest/samples/sample1.h | 41 + 3rdparty/gtest/samples/sample10_unittest.cc | 139 + 3rdparty/gtest/samples/sample1_unittest.cc | 151 + 3rdparty/gtest/samples/sample2.cc | 54 + 3rdparty/gtest/samples/sample2.h | 81 + 3rdparty/gtest/samples/sample2_unittest.cc | 107 + 3rdparty/gtest/samples/sample3-inl.h | 172 + 3rdparty/gtest/samples/sample3_unittest.cc | 149 + 3rdparty/gtest/samples/sample4.cc | 54 + 3rdparty/gtest/samples/sample4.h | 53 + 3rdparty/gtest/samples/sample4_unittest.cc | 53 + 3rdparty/gtest/samples/sample5_unittest.cc | 196 + 3rdparty/gtest/samples/sample6_unittest.cc | 224 + 3rdparty/gtest/samples/sample7_unittest.cc | 117 + 3rdparty/gtest/samples/sample8_unittest.cc | 154 + 3rdparty/gtest/samples/sample9_unittest.cc | 156 + 3rdparty/gtest/scripts/common.py | 83 + 3rdparty/gtest/scripts/fuse_gtest_files.py | 253 + 3rdparty/gtest/scripts/gen_gtest_pred_impl.py | 730 ++ 3rdparty/gtest/scripts/gtest-config.in | 274 + 3rdparty/gtest/scripts/pump.py | 855 ++ 3rdparty/gtest/scripts/release_docs.py | 158 + 3rdparty/gtest/scripts/upload.py | 1387 +++ 3rdparty/gtest/scripts/upload_gtest.py | 78 + 3rdparty/gtest/src/gtest-all.cc | 48 + 3rdparty/gtest/src/gtest-death-test.cc | 1653 ++++ 3rdparty/gtest/src/gtest-filepath.cc | 379 + 3rdparty/gtest/src/gtest-internal-inl.h | 1211 +++ 3rdparty/gtest/src/gtest-matchers.cc | 97 + 3rdparty/gtest/src/gtest-port.cc | 1399 +++ 3rdparty/gtest/src/gtest-printers.cc | 442 + 3rdparty/gtest/src/gtest-test-part.cc | 104 + 3rdparty/gtest/src/gtest-typed-test.cc | 118 + 3rdparty/gtest/src/gtest.cc | 6177 ++++++++++++++ 3rdparty/gtest/src/gtest_main.cc | 47 + 3rdparty/gtest/test/BUILD.bazel | 521 ++ .../googletest-break-on-failure-unittest.py | 208 + .../googletest-break-on-failure-unittest_.cc | 86 + .../test/googletest-catch-exceptions-test.py | 236 + .../test/googletest-catch-exceptions-test_.cc | 293 + 3rdparty/gtest/test/googletest-color-test.py | 127 + 3rdparty/gtest/test/googletest-color-test_.cc | 62 + .../gtest/test/googletest-death-test-test.cc | 1516 ++++ .../test/googletest-death-test_ex_test.cc | 92 + .../gtest/test/googletest-env-var-test.py | 117 + .../gtest/test/googletest-env-var-test_.cc | 122 + .../gtest/test/googletest-filepath-test.cc | 649 ++ .../gtest/test/googletest-filter-unittest.py | 639 ++ .../gtest/test/googletest-filter-unittest_.cc | 137 + .../test/googletest-json-outfiles-test.py | 191 + .../test/googletest-json-output-unittest.py | 778 ++ .../test/googletest-list-tests-unittest.py | 205 + .../test/googletest-list-tests-unittest_.cc | 156 + .../gtest/test/googletest-listener-test.cc | 518 ++ .../gtest/test/googletest-message-test.cc | 158 + .../gtest/test/googletest-options-test.cc | 216 + .../googletest-output-test-golden-lin.txt | 1140 +++ 3rdparty/gtest/test/googletest-output-test.py | 346 + .../gtest/test/googletest-output-test_.cc | 1157 +++ ...oogletest-param-test-invalid-name1-test.py | 63 + ...ogletest-param-test-invalid-name1-test_.cc | 50 + ...oogletest-param-test-invalid-name2-test.py | 62 + ...ogletest-param-test-invalid-name2-test_.cc | 55 + .../gtest/test/googletest-param-test-test.cc | 1055 +++ .../gtest/test/googletest-param-test-test.h | 51 + .../gtest/test/googletest-param-test2-test.cc | 61 + 3rdparty/gtest/test/googletest-port-test.cc | 1272 +++ .../gtest/test/googletest-printers-test.cc | 1620 ++++ .../gtest/test/googletest-shuffle-test.py | 323 + .../gtest/test/googletest-shuffle-test_.cc | 101 + .../gtest/test/googletest-test-part-test.cc | 230 + 3rdparty/gtest/test/googletest-test2_test.cc | 61 + .../test/googletest-throw-on-failure-test.py | 168 + .../test/googletest-throw-on-failure-test_.cc | 71 + .../test/googletest-uninitialized-test.py | 67 + .../test/googletest-uninitialized-test_.cc | 42 + 3rdparty/gtest/test/gtest-typed-test2_test.cc | 44 + 3rdparty/gtest/test/gtest-typed-test_test.cc | 462 + 3rdparty/gtest/test/gtest-typed-test_test.h | 65 + .../gtest/test/gtest-unittest-api_test.cc | 340 + 3rdparty/gtest/test/gtest_all_test.cc | 46 + .../test/gtest_assert_by_exception_test.cc | 116 + 3rdparty/gtest/test/gtest_environment_test.cc | 188 + 3rdparty/gtest/test/gtest_help_test.py | 170 + 3rdparty/gtest/test/gtest_help_test_.cc | 45 + 3rdparty/gtest/test/gtest_json_test_utils.py | 60 + .../gtest/test/gtest_list_output_unittest.py | 141 + .../gtest/test/gtest_list_output_unittest_.cc | 51 + 3rdparty/gtest/test/gtest_main_unittest.cc | 44 + 3rdparty/gtest/test/gtest_no_test_unittest.cc | 54 + .../gtest/test/gtest_pred_impl_unittest.cc | 2427 ++++++ .../gtest/test/gtest_premature_exit_test.cc | 126 + 3rdparty/gtest/test/gtest_prod_test.cc | 56 + 3rdparty/gtest/test/gtest_repeat_test.cc | 233 + ...test_skip_environment_check_output_test.py | 54 + .../gtest_skip_in_environment_setup_test.cc | 49 + 3rdparty/gtest/test/gtest_skip_test.cc | 55 + 3rdparty/gtest/test/gtest_sole_header_test.cc | 56 + 3rdparty/gtest/test/gtest_stress_test.cc | 248 + .../gtest_test_macro_stack_footprint_test.cc | 89 + 3rdparty/gtest/test/gtest_test_utils.py | 314 + 3rdparty/gtest/test/gtest_testbridge_test.py | 63 + 3rdparty/gtest/test/gtest_testbridge_test_.cc | 43 + .../test/gtest_throw_on_failure_ex_test.cc | 90 + 3rdparty/gtest/test/gtest_unittest.cc | 7488 +++++++++++++++++ .../gtest/test/gtest_xml_outfile1_test_.cc | 43 + .../gtest/test/gtest_xml_outfile2_test_.cc | 43 + .../gtest/test/gtest_xml_outfiles_test.py | 135 + .../gtest/test/gtest_xml_output_unittest.py | 389 + .../gtest/test/gtest_xml_output_unittest_.cc | 188 + 3rdparty/gtest/test/gtest_xml_test_utils.py | 196 + 3rdparty/gtest/test/production.cc | 35 + 3rdparty/gtest/test/production.h | 54 + CMakeLists.txt | 19 + build/CMakeLists.txt | 11 - build/chat/CMakeLists.txt | 14 - build/chat/chat.pro | 19 - build/cpp-ipc.pro | 4 - build/ipc/CMakeLists.txt | 16 - build/ipc/ipc.pro | 73 - build/test/CMakeLists.txt | 26 - build/test/test.pro | 40 - demo/chat/CMakeLists.txt | 11 + src/CMakeLists.txt | 18 + test/CMakeLists.txt | 29 + test/gperftools/libtcmalloc_minimal.so | Bin 1414680 -> 0 bytes test/gperftools/libtcmalloc_minimal.so.4 | 1 - test/gperftools/libtcmalloc_minimal.so.4.5.3 | 1 - test/main.cpp | 43 - test/test.h | 18 +- test/test_circ.cpp | 59 +- test/test_ipc.cpp | 107 +- test/test_mem.cpp | 38 +- test/test_shm.cpp | 103 +- test/test_waiter.cpp | 23 +- 184 files changed, 67882 insertions(+), 496 deletions(-) rename {test => 3rdparty}/capo/random.hpp (100%) rename {test => 3rdparty}/capo/spin_lock.hpp (100%) rename {test => 3rdparty}/capo/stopwatch.hpp (100%) create mode 100644 3rdparty/gperftools/libtcmalloc_minimal.so.4 create mode 100644 3rdparty/gperftools/libtcmalloc_minimal.so.4.5.3 rename {test => 3rdparty}/gperftools/tcmalloc.h (100%) mode change 100755 => 100644 create mode 100644 3rdparty/gtest/CMakeLists.txt create mode 100644 3rdparty/gtest/CONTRIBUTORS create mode 100644 3rdparty/gtest/LICENSE create mode 100644 3rdparty/gtest/README.md create mode 100644 3rdparty/gtest/cmake/Config.cmake.in create mode 100644 3rdparty/gtest/cmake/gtest.pc.in create mode 100644 3rdparty/gtest/cmake/gtest_main.pc.in create mode 100644 3rdparty/gtest/cmake/internal_utils.cmake create mode 100644 3rdparty/gtest/cmake/libgtest.la.in create mode 100644 3rdparty/gtest/docs/advanced.md create mode 100644 3rdparty/gtest/docs/faq.md create mode 100644 3rdparty/gtest/docs/pkgconfig.md create mode 100644 3rdparty/gtest/docs/primer.md create mode 100644 3rdparty/gtest/docs/pump_manual.md create mode 100644 3rdparty/gtest/docs/samples.md create mode 100644 3rdparty/gtest/include/gtest/gtest-death-test.h create mode 100644 3rdparty/gtest/include/gtest/gtest-matchers.h create mode 100644 3rdparty/gtest/include/gtest/gtest-message.h create mode 100644 3rdparty/gtest/include/gtest/gtest-param-test.h create mode 100644 3rdparty/gtest/include/gtest/gtest-printers.h create mode 100644 3rdparty/gtest/include/gtest/gtest-spi.h create mode 100644 3rdparty/gtest/include/gtest/gtest-test-part.h create mode 100644 3rdparty/gtest/include/gtest/gtest-typed-test.h create mode 100644 3rdparty/gtest/include/gtest/gtest.h create mode 100644 3rdparty/gtest/include/gtest/gtest_pred_impl.h create mode 100644 3rdparty/gtest/include/gtest/gtest_prod.h create mode 100644 3rdparty/gtest/include/gtest/internal/custom/README.md create mode 100644 3rdparty/gtest/include/gtest/internal/custom/gtest-port.h create mode 100644 3rdparty/gtest/include/gtest/internal/custom/gtest-printers.h create mode 100644 3rdparty/gtest/include/gtest/internal/custom/gtest.h create mode 100644 3rdparty/gtest/include/gtest/internal/gtest-death-test-internal.h create mode 100644 3rdparty/gtest/include/gtest/internal/gtest-filepath.h create mode 100644 3rdparty/gtest/include/gtest/internal/gtest-internal.h create mode 100644 3rdparty/gtest/include/gtest/internal/gtest-param-util.h create mode 100644 3rdparty/gtest/include/gtest/internal/gtest-port-arch.h create mode 100644 3rdparty/gtest/include/gtest/internal/gtest-port.h create mode 100644 3rdparty/gtest/include/gtest/internal/gtest-string.h create mode 100644 3rdparty/gtest/include/gtest/internal/gtest-type-util.h create mode 100644 3rdparty/gtest/include/gtest/internal/gtest-type-util.h.pump create mode 100644 3rdparty/gtest/samples/prime_tables.h create mode 100644 3rdparty/gtest/samples/sample1.cc create mode 100644 3rdparty/gtest/samples/sample1.h create mode 100644 3rdparty/gtest/samples/sample10_unittest.cc create mode 100644 3rdparty/gtest/samples/sample1_unittest.cc create mode 100644 3rdparty/gtest/samples/sample2.cc create mode 100644 3rdparty/gtest/samples/sample2.h create mode 100644 3rdparty/gtest/samples/sample2_unittest.cc create mode 100644 3rdparty/gtest/samples/sample3-inl.h create mode 100644 3rdparty/gtest/samples/sample3_unittest.cc create mode 100644 3rdparty/gtest/samples/sample4.cc create mode 100644 3rdparty/gtest/samples/sample4.h create mode 100644 3rdparty/gtest/samples/sample4_unittest.cc create mode 100644 3rdparty/gtest/samples/sample5_unittest.cc create mode 100644 3rdparty/gtest/samples/sample6_unittest.cc create mode 100644 3rdparty/gtest/samples/sample7_unittest.cc create mode 100644 3rdparty/gtest/samples/sample8_unittest.cc create mode 100644 3rdparty/gtest/samples/sample9_unittest.cc create mode 100644 3rdparty/gtest/scripts/common.py create mode 100644 3rdparty/gtest/scripts/fuse_gtest_files.py create mode 100644 3rdparty/gtest/scripts/gen_gtest_pred_impl.py create mode 100644 3rdparty/gtest/scripts/gtest-config.in create mode 100644 3rdparty/gtest/scripts/pump.py create mode 100644 3rdparty/gtest/scripts/release_docs.py create mode 100644 3rdparty/gtest/scripts/upload.py create mode 100644 3rdparty/gtest/scripts/upload_gtest.py create mode 100644 3rdparty/gtest/src/gtest-all.cc create mode 100644 3rdparty/gtest/src/gtest-death-test.cc create mode 100644 3rdparty/gtest/src/gtest-filepath.cc create mode 100644 3rdparty/gtest/src/gtest-internal-inl.h create mode 100644 3rdparty/gtest/src/gtest-matchers.cc create mode 100644 3rdparty/gtest/src/gtest-port.cc create mode 100644 3rdparty/gtest/src/gtest-printers.cc create mode 100644 3rdparty/gtest/src/gtest-test-part.cc create mode 100644 3rdparty/gtest/src/gtest-typed-test.cc create mode 100644 3rdparty/gtest/src/gtest.cc create mode 100644 3rdparty/gtest/src/gtest_main.cc create mode 100644 3rdparty/gtest/test/BUILD.bazel create mode 100644 3rdparty/gtest/test/googletest-break-on-failure-unittest.py create mode 100644 3rdparty/gtest/test/googletest-break-on-failure-unittest_.cc create mode 100644 3rdparty/gtest/test/googletest-catch-exceptions-test.py create mode 100644 3rdparty/gtest/test/googletest-catch-exceptions-test_.cc create mode 100644 3rdparty/gtest/test/googletest-color-test.py create mode 100644 3rdparty/gtest/test/googletest-color-test_.cc create mode 100644 3rdparty/gtest/test/googletest-death-test-test.cc create mode 100644 3rdparty/gtest/test/googletest-death-test_ex_test.cc create mode 100644 3rdparty/gtest/test/googletest-env-var-test.py create mode 100644 3rdparty/gtest/test/googletest-env-var-test_.cc create mode 100644 3rdparty/gtest/test/googletest-filepath-test.cc create mode 100644 3rdparty/gtest/test/googletest-filter-unittest.py create mode 100644 3rdparty/gtest/test/googletest-filter-unittest_.cc create mode 100644 3rdparty/gtest/test/googletest-json-outfiles-test.py create mode 100644 3rdparty/gtest/test/googletest-json-output-unittest.py create mode 100644 3rdparty/gtest/test/googletest-list-tests-unittest.py create mode 100644 3rdparty/gtest/test/googletest-list-tests-unittest_.cc create mode 100644 3rdparty/gtest/test/googletest-listener-test.cc create mode 100644 3rdparty/gtest/test/googletest-message-test.cc create mode 100644 3rdparty/gtest/test/googletest-options-test.cc create mode 100644 3rdparty/gtest/test/googletest-output-test-golden-lin.txt create mode 100644 3rdparty/gtest/test/googletest-output-test.py create mode 100644 3rdparty/gtest/test/googletest-output-test_.cc create mode 100644 3rdparty/gtest/test/googletest-param-test-invalid-name1-test.py create mode 100644 3rdparty/gtest/test/googletest-param-test-invalid-name1-test_.cc create mode 100644 3rdparty/gtest/test/googletest-param-test-invalid-name2-test.py create mode 100644 3rdparty/gtest/test/googletest-param-test-invalid-name2-test_.cc create mode 100644 3rdparty/gtest/test/googletest-param-test-test.cc create mode 100644 3rdparty/gtest/test/googletest-param-test-test.h create mode 100644 3rdparty/gtest/test/googletest-param-test2-test.cc create mode 100644 3rdparty/gtest/test/googletest-port-test.cc create mode 100644 3rdparty/gtest/test/googletest-printers-test.cc create mode 100644 3rdparty/gtest/test/googletest-shuffle-test.py create mode 100644 3rdparty/gtest/test/googletest-shuffle-test_.cc create mode 100644 3rdparty/gtest/test/googletest-test-part-test.cc create mode 100644 3rdparty/gtest/test/googletest-test2_test.cc create mode 100644 3rdparty/gtest/test/googletest-throw-on-failure-test.py create mode 100644 3rdparty/gtest/test/googletest-throw-on-failure-test_.cc create mode 100644 3rdparty/gtest/test/googletest-uninitialized-test.py create mode 100644 3rdparty/gtest/test/googletest-uninitialized-test_.cc create mode 100644 3rdparty/gtest/test/gtest-typed-test2_test.cc create mode 100644 3rdparty/gtest/test/gtest-typed-test_test.cc create mode 100644 3rdparty/gtest/test/gtest-typed-test_test.h create mode 100644 3rdparty/gtest/test/gtest-unittest-api_test.cc create mode 100644 3rdparty/gtest/test/gtest_all_test.cc create mode 100644 3rdparty/gtest/test/gtest_assert_by_exception_test.cc create mode 100644 3rdparty/gtest/test/gtest_environment_test.cc create mode 100644 3rdparty/gtest/test/gtest_help_test.py create mode 100644 3rdparty/gtest/test/gtest_help_test_.cc create mode 100644 3rdparty/gtest/test/gtest_json_test_utils.py create mode 100644 3rdparty/gtest/test/gtest_list_output_unittest.py create mode 100644 3rdparty/gtest/test/gtest_list_output_unittest_.cc create mode 100644 3rdparty/gtest/test/gtest_main_unittest.cc create mode 100644 3rdparty/gtest/test/gtest_no_test_unittest.cc create mode 100644 3rdparty/gtest/test/gtest_pred_impl_unittest.cc create mode 100644 3rdparty/gtest/test/gtest_premature_exit_test.cc create mode 100644 3rdparty/gtest/test/gtest_prod_test.cc create mode 100644 3rdparty/gtest/test/gtest_repeat_test.cc create mode 100644 3rdparty/gtest/test/gtest_skip_environment_check_output_test.py create mode 100644 3rdparty/gtest/test/gtest_skip_in_environment_setup_test.cc create mode 100644 3rdparty/gtest/test/gtest_skip_test.cc create mode 100644 3rdparty/gtest/test/gtest_sole_header_test.cc create mode 100644 3rdparty/gtest/test/gtest_stress_test.cc create mode 100644 3rdparty/gtest/test/gtest_test_macro_stack_footprint_test.cc create mode 100644 3rdparty/gtest/test/gtest_test_utils.py create mode 100644 3rdparty/gtest/test/gtest_testbridge_test.py create mode 100644 3rdparty/gtest/test/gtest_testbridge_test_.cc create mode 100644 3rdparty/gtest/test/gtest_throw_on_failure_ex_test.cc create mode 100644 3rdparty/gtest/test/gtest_unittest.cc create mode 100644 3rdparty/gtest/test/gtest_xml_outfile1_test_.cc create mode 100644 3rdparty/gtest/test/gtest_xml_outfile2_test_.cc create mode 100644 3rdparty/gtest/test/gtest_xml_outfiles_test.py create mode 100644 3rdparty/gtest/test/gtest_xml_output_unittest.py create mode 100644 3rdparty/gtest/test/gtest_xml_output_unittest_.cc create mode 100644 3rdparty/gtest/test/gtest_xml_test_utils.py create mode 100644 3rdparty/gtest/test/production.cc create mode 100644 3rdparty/gtest/test/production.h create mode 100644 CMakeLists.txt delete mode 100755 build/CMakeLists.txt delete mode 100644 build/chat/CMakeLists.txt delete mode 100644 build/chat/chat.pro delete mode 100644 build/cpp-ipc.pro delete mode 100755 build/ipc/CMakeLists.txt delete mode 100644 build/ipc/ipc.pro delete mode 100755 build/test/CMakeLists.txt delete mode 100755 build/test/test.pro create mode 100644 demo/chat/CMakeLists.txt create mode 100644 src/CMakeLists.txt create mode 100644 test/CMakeLists.txt delete mode 100755 test/gperftools/libtcmalloc_minimal.so delete mode 120000 test/gperftools/libtcmalloc_minimal.so.4 delete mode 120000 test/gperftools/libtcmalloc_minimal.so.4.5.3 delete mode 100644 test/main.cpp diff --git a/.gitignore b/.gitignore index a3ee2cf..5ea6006 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,4 @@ target_wrapper.* CMakeLists.txt.user* # My output files -output +build diff --git a/.travis.yml b/.travis.yml index ca1c828..2092890 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,31 +8,22 @@ addons: - ubuntu-toolchain-r-test packages: - g++-8 - - qtbase5-dev matrix: include: - compiler: gcc env: - - MATRIX_EVAL="USING_CMAKE=0 CC=gcc-8 && CXX=g++-8" + - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" - compiler: clang - - compiler: clang - env: - - MATRIX_EVAL="USING_CMAKE=1" before_install: - eval "${MATRIX_EVAL}" - - qmake -v script: - - cd ./build - - if [ $USING_CMAKE -eq 1 ]; then - cmake -DCMAKE_BUILD_TYPE=Release CMakeLists.txt; - else - qmake -o Makefile cpp-ipc.pro QMAKE_CC=$CC QMAKE_CXX=$CXX QMAKE_LINK=$CXX QMAKE_CXXFLAGS+=-std=gnu++1z; - fi - - make -j`getconf _NPROCESSORS_ONLN` - - export LD_LIBRARY_PATH=../output:$LD_LIBRARY_PATH && ../output/test-ipc + - mkdir -p ./build && cd ./build + - cmake -DCMAKE_BUILD_TYPE=Release .. + - make -j`nproc` + - export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH && ./bin/test-ipc notifications: slack: diff --git a/test/capo/random.hpp b/3rdparty/capo/random.hpp similarity index 100% rename from test/capo/random.hpp rename to 3rdparty/capo/random.hpp diff --git a/test/capo/spin_lock.hpp b/3rdparty/capo/spin_lock.hpp similarity index 100% rename from test/capo/spin_lock.hpp rename to 3rdparty/capo/spin_lock.hpp diff --git a/test/capo/stopwatch.hpp b/3rdparty/capo/stopwatch.hpp similarity index 100% rename from test/capo/stopwatch.hpp rename to 3rdparty/capo/stopwatch.hpp diff --git a/3rdparty/gperftools/libtcmalloc_minimal.so.4 b/3rdparty/gperftools/libtcmalloc_minimal.so.4 new file mode 100644 index 0000000..74cc460 --- /dev/null +++ b/3rdparty/gperftools/libtcmalloc_minimal.so.4 @@ -0,0 +1 @@ +libtcmalloc_minimal.so \ No newline at end of file diff --git a/3rdparty/gperftools/libtcmalloc_minimal.so.4.5.3 b/3rdparty/gperftools/libtcmalloc_minimal.so.4.5.3 new file mode 100644 index 0000000..74cc460 --- /dev/null +++ b/3rdparty/gperftools/libtcmalloc_minimal.so.4.5.3 @@ -0,0 +1 @@ +libtcmalloc_minimal.so \ No newline at end of file diff --git a/test/gperftools/tcmalloc.h b/3rdparty/gperftools/tcmalloc.h old mode 100755 new mode 100644 similarity index 100% rename from test/gperftools/tcmalloc.h rename to 3rdparty/gperftools/tcmalloc.h diff --git a/3rdparty/gtest/CMakeLists.txt b/3rdparty/gtest/CMakeLists.txt new file mode 100644 index 0000000..db29294 --- /dev/null +++ b/3rdparty/gtest/CMakeLists.txt @@ -0,0 +1,328 @@ +######################################################################## +# Note: CMake support is community-based. The maintainers do not use CMake +# internally. +# +# CMake build script for Google Test. +# +# To run the tests for Google Test itself on Linux, use 'make test' or +# ctest. You can select which tests to run using 'ctest -R regex'. +# For more options, run 'ctest --help'. + +# When other libraries are using a shared version of runtime libraries, +# Google Test also has to use one. +option( + gtest_force_shared_crt + "Use shared (DLL) run-time lib even when Google Test is built as static lib." + OFF) + +option(gtest_build_tests "Build all of gtest's own tests." OFF) + +option(gtest_build_samples "Build gtest's sample programs." OFF) + +option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF) + +option( + gtest_hide_internal_symbols + "Build gtest with internal symbols hidden in shared libraries." + OFF) + +# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). +include(cmake/hermetic_build.cmake OPTIONAL) + +if (COMMAND pre_project_set_up_hermetic_build) + pre_project_set_up_hermetic_build() +endif() + +######################################################################## +# +# Project-wide settings + +# Name of the project. +# +# CMake files in this project can refer to the root source directory +# as ${gtest_SOURCE_DIR} and to the root binary directory as +# ${gtest_BINARY_DIR}. +# Language "C" is required for find_package(Threads). + +# Project version: + +if (CMAKE_VERSION VERSION_LESS 3.0) + project(gtest CXX C) + set(PROJECT_VERSION ${GOOGLETEST_VERSION}) +else() + cmake_policy(SET CMP0048 NEW) + project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C) +endif() +cmake_minimum_required(VERSION 2.6.4) + +if (POLICY CMP0063) # Visibility + cmake_policy(SET CMP0063 NEW) +endif (POLICY CMP0063) + +if (COMMAND set_up_hermetic_build) + set_up_hermetic_build() +endif() + +# These commands only run if this is the main project +if(CMAKE_PROJECT_NAME STREQUAL "gtest" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution") + + # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to + # make it prominent in the GUI. + option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) + +else() + + mark_as_advanced( + gtest_force_shared_crt + gtest_build_tests + gtest_build_samples + gtest_disable_pthreads + gtest_hide_internal_symbols) + +endif() + + +if (gtest_hide_internal_symbols) + set(CMAKE_CXX_VISIBILITY_PRESET hidden) + set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) +endif() + +# Define helper functions and macros used by Google Test. +include(cmake/internal_utils.cmake) + +config_compiler_and_linker() # Defined in internal_utils.cmake. + +# Create the CMake package file descriptors. +if (INSTALL_GTEST) + include(CMakePackageConfigHelpers) + set(cmake_package_name GTest) + set(targets_export_name ${cmake_package_name}Targets CACHE INTERNAL "") + set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated" CACHE INTERNAL "") + set(cmake_files_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${cmake_package_name}") + set(version_file "${generated_dir}/${cmake_package_name}ConfigVersion.cmake") + write_basic_package_version_file(${version_file} VERSION ${GOOGLETEST_VERSION} COMPATIBILITY AnyNewerVersion) + install(EXPORT ${targets_export_name} + NAMESPACE ${cmake_package_name}:: + DESTINATION ${cmake_files_install_dir}) + set(config_file "${generated_dir}/${cmake_package_name}Config.cmake") + configure_package_config_file("${gtest_SOURCE_DIR}/cmake/Config.cmake.in" + "${config_file}" INSTALL_DESTINATION ${cmake_files_install_dir}) + install(FILES ${version_file} ${config_file} + DESTINATION ${cmake_files_install_dir}) +endif() + +# Where Google Test's .h files can be found. +set(gtest_build_include_dirs + "${gtest_SOURCE_DIR}/include" + "${gtest_SOURCE_DIR}") +include_directories(${gtest_build_include_dirs}) + +######################################################################## +# +# Defines the gtest & gtest_main libraries. User tests should link +# with one of them. + +# Google Test libraries. We build them using more strict warnings than what +# are used for other targets, to ensure that gtest can be compiled by a user +# aggressive about warnings. +cxx_library(gtest "${cxx_strict}" src/gtest-all.cc) +cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc) +# If the CMake version supports it, attach header directory information +# to the targets for when we are part of a parent build (ie being pulled +# in via add_subdirectory() rather than being a standalone build). +if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") + target_include_directories(gtest SYSTEM INTERFACE + "$" + "$/${CMAKE_INSTALL_INCLUDEDIR}>") + target_include_directories(gtest_main SYSTEM INTERFACE + "$" + "$/${CMAKE_INSTALL_INCLUDEDIR}>") +endif() +target_link_libraries(gtest_main PUBLIC gtest) + +######################################################################## +# +# Install rules +install_project(gtest gtest_main) + +######################################################################## +# +# Samples on how to link user tests with gtest or gtest_main. +# +# They are not built by default. To build them, set the +# gtest_build_samples option to ON. You can do it by running ccmake +# or specifying the -Dgtest_build_samples=ON flag when running cmake. + +if (gtest_build_samples) + cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc) + cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc) + cxx_executable(sample3_unittest samples gtest_main) + cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc) + cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc) + cxx_executable(sample6_unittest samples gtest_main) + cxx_executable(sample7_unittest samples gtest_main) + cxx_executable(sample8_unittest samples gtest_main) + cxx_executable(sample9_unittest samples gtest) + cxx_executable(sample10_unittest samples gtest) +endif() + +######################################################################## +# +# Google Test's own tests. +# +# You can skip this section if you aren't interested in testing +# Google Test itself. +# +# The tests are not built by default. To build them, set the +# gtest_build_tests option to ON. You can do it by running ccmake +# or specifying the -Dgtest_build_tests=ON flag when running cmake. + +if (gtest_build_tests) + # This must be set in the root directory for the tests to be run by + # 'make test' or ctest. + enable_testing() + + if (WIN32) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$/RunTest.ps1" + CONTENT +"$project_bin = \"${CMAKE_BINARY_DIR}/bin/$\" +$env:Path = \"$project_bin;$env:Path\" +& $args") + elseif (MINGW OR CYGWIN) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1" + CONTENT +"$project_bin = (cygpath --windows ${CMAKE_BINARY_DIR}/bin) +$env:Path = \"$project_bin;$env:Path\" +& $args") + endif() + + ############################################################ + # C++ tests built with standard compiler flags. + + cxx_test(googletest-death-test-test gtest_main) + cxx_test(gtest_environment_test gtest) + cxx_test(googletest-filepath-test gtest_main) + cxx_test(googletest-listener-test gtest_main) + cxx_test(gtest_main_unittest gtest_main) + cxx_test(googletest-message-test gtest_main) + cxx_test(gtest_no_test_unittest gtest) + cxx_test(googletest-options-test gtest_main) + cxx_test(googletest-param-test-test gtest + test/googletest-param-test2-test.cc) + cxx_test(googletest-port-test gtest_main) + cxx_test(gtest_pred_impl_unittest gtest_main) + cxx_test(gtest_premature_exit_test gtest + test/gtest_premature_exit_test.cc) + cxx_test(googletest-printers-test gtest_main) + cxx_test(gtest_prod_test gtest_main + test/production.cc) + cxx_test(gtest_repeat_test gtest) + cxx_test(gtest_sole_header_test gtest_main) + cxx_test(gtest_stress_test gtest) + cxx_test(googletest-test-part-test gtest_main) + cxx_test(gtest_throw_on_failure_ex_test gtest) + cxx_test(gtest-typed-test_test gtest_main + test/gtest-typed-test2_test.cc) + cxx_test(gtest_unittest gtest_main) + cxx_test(gtest-unittest-api_test gtest) + cxx_test(gtest_skip_in_environment_setup_test gtest_main) + cxx_test(gtest_skip_test gtest_main) + + ############################################################ + # C++ tests built with non-standard compiler flags. + + # MSVC 7.1 does not support STL with exceptions disabled. + if (NOT MSVC OR MSVC_VERSION GREATER 1310) + cxx_library(gtest_no_exception "${cxx_no_exception}" + src/gtest-all.cc) + cxx_library(gtest_main_no_exception "${cxx_no_exception}" + src/gtest-all.cc src/gtest_main.cc) + endif() + cxx_library(gtest_main_no_rtti "${cxx_no_rtti}" + src/gtest-all.cc src/gtest_main.cc) + + cxx_test_with_flags(gtest-death-test_ex_nocatch_test + "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0" + gtest test/googletest-death-test_ex_test.cc) + cxx_test_with_flags(gtest-death-test_ex_catch_test + "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1" + gtest test/googletest-death-test_ex_test.cc) + + cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}" + gtest_main_no_rtti test/gtest_unittest.cc) + + cxx_shared_library(gtest_dll "${cxx_default}" + src/gtest-all.cc src/gtest_main.cc) + + cxx_executable_with_flags(gtest_dll_test_ "${cxx_default}" + gtest_dll test/gtest_all_test.cc) + set_target_properties(gtest_dll_test_ + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + + ############################################################ + # Python tests. + + cxx_executable(googletest-break-on-failure-unittest_ test gtest) + py_test(googletest-break-on-failure-unittest) + + py_test(gtest_skip_environment_check_output_test) + + # Visual Studio .NET 2003 does not support STL with exceptions disabled. + if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003 + cxx_executable_with_flags( + googletest-catch-exceptions-no-ex-test_ + "${cxx_no_exception}" + gtest_main_no_exception + test/googletest-catch-exceptions-test_.cc) + endif() + + cxx_executable_with_flags( + googletest-catch-exceptions-ex-test_ + "${cxx_exception}" + gtest_main + test/googletest-catch-exceptions-test_.cc) + py_test(googletest-catch-exceptions-test) + + cxx_executable(googletest-color-test_ test gtest) + py_test(googletest-color-test) + + cxx_executable(googletest-env-var-test_ test gtest) + py_test(googletest-env-var-test) + + cxx_executable(googletest-filter-unittest_ test gtest) + py_test(googletest-filter-unittest) + + cxx_executable(gtest_help_test_ test gtest_main) + py_test(gtest_help_test) + + cxx_executable(googletest-list-tests-unittest_ test gtest) + py_test(googletest-list-tests-unittest) + + cxx_executable(googletest-output-test_ test gtest) + py_test(googletest-output-test --no_stacktrace_support) + + cxx_executable(googletest-shuffle-test_ test gtest) + py_test(googletest-shuffle-test) + + # MSVC 7.1 does not support STL with exceptions disabled. + if (NOT MSVC OR MSVC_VERSION GREATER 1310) + cxx_executable(googletest-throw-on-failure-test_ test gtest_no_exception) + set_target_properties(googletest-throw-on-failure-test_ + PROPERTIES + COMPILE_FLAGS "${cxx_no_exception}") + py_test(googletest-throw-on-failure-test) + endif() + + cxx_executable(googletest-uninitialized-test_ test gtest) + py_test(googletest-uninitialized-test) + + cxx_executable(gtest_xml_outfile1_test_ test gtest_main) + cxx_executable(gtest_xml_outfile2_test_ test gtest_main) + py_test(gtest_xml_outfiles_test) + py_test(googletest-json-outfiles-test) + + cxx_executable(gtest_xml_output_unittest_ test gtest) + py_test(gtest_xml_output_unittest --no_stacktrace_support) + py_test(googletest-json-output-unittest --no_stacktrace_support) +endif() diff --git a/3rdparty/gtest/CONTRIBUTORS b/3rdparty/gtest/CONTRIBUTORS new file mode 100644 index 0000000..feae2fc --- /dev/null +++ b/3rdparty/gtest/CONTRIBUTORS @@ -0,0 +1,37 @@ +# This file contains a list of people who've made non-trivial +# contribution to the Google C++ Testing Framework project. People +# who commit code to the project are encouraged to add their names +# here. Please keep the list sorted by first names. + +Ajay Joshi +Balázs Dán +Bharat Mediratta +Chandler Carruth +Chris Prince +Chris Taylor +Dan Egnor +Eric Roman +Hady Zalek +Jeffrey Yasskin +Jói Sigurðsson +Keir Mierle +Keith Ray +Kenton Varda +Manuel Klimek +Markus Heule +Mika Raento +Miklós Fazekas +Pasi Valminen +Patrick Hanna +Patrick Riley +Peter Kaminski +Preston Jackson +Rainer Klaffenboeck +Russ Cox +Russ Rufer +Sean Mcafee +Sigurður Ásgeirsson +Tracy Bialik +Vadim Berman +Vlad Losev +Zhanyong Wan diff --git a/3rdparty/gtest/LICENSE b/3rdparty/gtest/LICENSE new file mode 100644 index 0000000..1941a11 --- /dev/null +++ b/3rdparty/gtest/LICENSE @@ -0,0 +1,28 @@ +Copyright 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/3rdparty/gtest/README.md b/3rdparty/gtest/README.md new file mode 100644 index 0000000..766ddc1 --- /dev/null +++ b/3rdparty/gtest/README.md @@ -0,0 +1,244 @@ +### Generic Build Instructions + +#### Setup + +To build Google Test and your tests that use it, you need to tell your build +system where to find its headers and source files. The exact way to do it +depends on which build system you use, and is usually straightforward. + +### Build with CMake + +Google Test comes with a CMake build script ( +[CMakeLists.txt](https://github.com/google/googletest/blob/master/CMakeLists.txt)) +that can be used on a wide range of platforms ("C" stands for cross-platform.). +If you don't have CMake installed already, you can download it for free from +. + +CMake works by generating native makefiles or build projects that can be used in +the compiler environment of your choice. You can either build Google Test as a +standalone project or it can be incorporated into an existing CMake build for +another project. + +#### Standalone CMake Project + +When building Google Test as a standalone project, the typical workflow starts +with: + + mkdir mybuild # Create a directory to hold the build output. + cd mybuild + cmake ${GTEST_DIR} # Generate native build scripts. + +If you want to build Google Test's samples, you should replace the last command +with + + cmake -Dgtest_build_samples=ON ${GTEST_DIR} + +If you are on a \*nix system, you should now see a Makefile in the current +directory. Just type 'make' to build gtest. + +If you use Windows and have Visual Studio installed, a `gtest.sln` file and +several `.vcproj` files will be created. You can then build them using Visual +Studio. + +On Mac OS X with Xcode installed, a `.xcodeproj` file will be generated. + +#### Incorporating Into An Existing CMake Project + +If you want to use gtest in a project which already uses CMake, then a more +robust and flexible approach is to build gtest as part of that project directly. +This is done by making the GoogleTest source code available to the main build +and adding it using CMake's `add_subdirectory()` command. This has the +significant advantage that the same compiler and linker settings are used +between gtest and the rest of your project, so issues associated with using +incompatible libraries (eg debug/release), etc. are avoided. This is +particularly useful on Windows. Making GoogleTest's source code available to the +main build can be done a few different ways: + +* Download the GoogleTest source code manually and place it at a known + location. This is the least flexible approach and can make it more difficult + to use with continuous integration systems, etc. +* Embed the GoogleTest source code as a direct copy in the main project's + source tree. This is often the simplest approach, but is also the hardest to + keep up to date. Some organizations may not permit this method. +* Add GoogleTest as a git submodule or equivalent. This may not always be + possible or appropriate. Git submodules, for example, have their own set of + advantages and drawbacks. +* Use CMake to download GoogleTest as part of the build's configure step. This + is just a little more complex, but doesn't have the limitations of the other + methods. + +The last of the above methods is implemented with a small piece of CMake code in +a separate file (e.g. `CMakeLists.txt.in`) which is copied to the build area and +then invoked as a sub-build _during the CMake stage_. That directory is then +pulled into the main build with `add_subdirectory()`. For example: + +New file `CMakeLists.txt.in`: + +```cmake +cmake_minimum_required(VERSION 2.8.2) + +project(googletest-download NONE) + +include(ExternalProject) +ExternalProject_Add(googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG master + SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" +) +``` + +Existing build's `CMakeLists.txt`: + +```cmake +# Download and unpack googletest at configure time +configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt) +execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) +if(result) + message(FATAL_ERROR "CMake step for googletest failed: ${result}") +endif() +execute_process(COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) +if(result) + message(FATAL_ERROR "Build step for googletest failed: ${result}") +endif() + +# Prevent overriding the parent project's compiler/linker +# settings on Windows +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +# Add googletest directly to our build. This defines +# the gtest and gtest_main targets. +add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src + ${CMAKE_CURRENT_BINARY_DIR}/googletest-build + EXCLUDE_FROM_ALL) + +# The gtest/gtest_main targets carry header search path +# dependencies automatically when using CMake 2.8.11 or +# later. Otherwise we have to add them here ourselves. +if (CMAKE_VERSION VERSION_LESS 2.8.11) + include_directories("${gtest_SOURCE_DIR}/include") +endif() + +# Now simply link against gtest or gtest_main as needed. Eg +add_executable(example example.cpp) +target_link_libraries(example gtest_main) +add_test(NAME example_test COMMAND example) +``` + +Note that this approach requires CMake 2.8.2 or later due to its use of the +`ExternalProject_Add()` command. The above technique is discussed in more detail +in [this separate article](http://crascit.com/2015/07/25/cmake-gtest/) which +also contains a link to a fully generalized implementation of the technique. + +##### Visual Studio Dynamic vs Static Runtimes + +By default, new Visual Studio projects link the C runtimes dynamically but +Google Test links them statically. This will generate an error that looks +something like the following: gtest.lib(gtest-all.obj) : error LNK2038: mismatch +detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value +'MDd_DynamicDebug' in main.obj + +Google Test already has a CMake option for this: `gtest_force_shared_crt` + +Enabling this option will make gtest link the runtimes dynamically too, and +match the project in which it is included. + +#### C++ Standard Version + +An environment that supports C++11 is required in order to successfully build +Google Test. One way to ensure this is to specify the standard in the top-level +project, for example by using the `set(CMAKE_CXX_STANDARD 11)` command. If this +is not feasible, for example in a C project using Google Test for validation, +then it can be specified by adding it to the options for cmake via the +`DCMAKE_CXX_FLAGS` option. + +### Tweaking Google Test + +Google Test can be used in diverse environments. The default configuration may +not work (or may not work well) out of the box in some environments. However, +you can easily tweak Google Test by defining control macros on the compiler +command line. Generally, these macros are named like `GTEST_XYZ` and you define +them to either 1 or 0 to enable or disable a certain feature. + +We list the most frequently used macros below. For a complete list, see file +[include/gtest/internal/gtest-port.h](https://github.com/google/googletest/blob/master/googletest/include/gtest/internal/gtest-port.h). + +### Multi-threaded Tests + +Google Test is thread-safe where the pthread library is available. After +`#include "gtest/gtest.h"`, you can check the +`GTEST_IS_THREADSAFE` macro to see whether this is the case (yes if the macro is +`#defined` to 1, no if it's undefined.). + +If Google Test doesn't correctly detect whether pthread is available in your +environment, you can force it with + + -DGTEST_HAS_PTHREAD=1 + +or + + -DGTEST_HAS_PTHREAD=0 + +When Google Test uses pthread, you may need to add flags to your compiler and/or +linker to select the pthread library, or you'll get link errors. If you use the +CMake script or the deprecated Autotools script, this is taken care of for you. +If you use your own build script, you'll need to read your compiler and linker's +manual to figure out what flags to add. + +### As a Shared Library (DLL) + +Google Test is compact, so most users can build and link it as a static library +for the simplicity. You can choose to use Google Test as a shared library (known +as a DLL on Windows) if you prefer. + +To compile *gtest* as a shared library, add + + -DGTEST_CREATE_SHARED_LIBRARY=1 + +to the compiler flags. You'll also need to tell the linker to produce a shared +library instead - consult your linker's manual for how to do it. + +To compile your *tests* that use the gtest shared library, add + + -DGTEST_LINKED_AS_SHARED_LIBRARY=1 + +to the compiler flags. + +Note: while the above steps aren't technically necessary today when using some +compilers (e.g. GCC), they may become necessary in the future, if we decide to +improve the speed of loading the library (see + for details). Therefore you are recommended +to always add the above flags when using Google Test as a shared library. +Otherwise a future release of Google Test may break your build script. + +### Avoiding Macro Name Clashes + +In C++, macros don't obey namespaces. Therefore two libraries that both define a +macro of the same name will clash if you `#include` both definitions. In case a +Google Test macro clashes with another library, you can force Google Test to +rename its macro to avoid the conflict. + +Specifically, if both Google Test and some other code define macro FOO, you can +add + + -DGTEST_DONT_DEFINE_FOO=1 + +to the compiler flags to tell Google Test to change the macro's name from `FOO` +to `GTEST_FOO`. Currently `FOO` can be `FAIL`, `SUCCEED`, or `TEST`. For +example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write + + GTEST_TEST(SomeTest, DoesThis) { ... } + +instead of + + TEST(SomeTest, DoesThis) { ... } + +in order to define a test. diff --git a/3rdparty/gtest/cmake/Config.cmake.in b/3rdparty/gtest/cmake/Config.cmake.in new file mode 100644 index 0000000..12be449 --- /dev/null +++ b/3rdparty/gtest/cmake/Config.cmake.in @@ -0,0 +1,9 @@ +@PACKAGE_INIT@ +include(CMakeFindDependencyMacro) +if (@GTEST_HAS_PTHREAD@) + set(THREADS_PREFER_PTHREAD_FLAG @THREADS_PREFER_PTHREAD_FLAG@) + find_dependency(Threads) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") +check_required_components("@project_name@") diff --git a/3rdparty/gtest/cmake/gtest.pc.in b/3rdparty/gtest/cmake/gtest.pc.in new file mode 100644 index 0000000..9aae29e --- /dev/null +++ b/3rdparty/gtest/cmake/gtest.pc.in @@ -0,0 +1,10 @@ +prefix=${pcfiledir}/../.. +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: gtest +Description: GoogleTest (without main() function) +Version: @PROJECT_VERSION@ +URL: https://github.com/google/googletest +Libs: -L${libdir} -lgtest @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ diff --git a/3rdparty/gtest/cmake/gtest_main.pc.in b/3rdparty/gtest/cmake/gtest_main.pc.in new file mode 100644 index 0000000..915f297 --- /dev/null +++ b/3rdparty/gtest/cmake/gtest_main.pc.in @@ -0,0 +1,11 @@ +prefix=${pcfiledir}/../.. +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: gtest_main +Description: GoogleTest (with main() function) +Version: @PROJECT_VERSION@ +URL: https://github.com/google/googletest +Requires: gtest +Libs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ diff --git a/3rdparty/gtest/cmake/internal_utils.cmake b/3rdparty/gtest/cmake/internal_utils.cmake new file mode 100644 index 0000000..2f70f0b --- /dev/null +++ b/3rdparty/gtest/cmake/internal_utils.cmake @@ -0,0 +1,358 @@ +# Defines functions and macros useful for building Google Test and +# Google Mock. +# +# Note: +# +# - This file will be run twice when building Google Mock (once via +# Google Test's CMakeLists.txt, and once via Google Mock's). +# Therefore it shouldn't have any side effects other than defining +# the functions and macros. +# +# - The functions/macros defined in this file may depend on Google +# Test and Google Mock's option() definitions, and thus must be +# called *after* the options have been defined. + +if (POLICY CMP0054) + cmake_policy(SET CMP0054 NEW) +endif (POLICY CMP0054) + +# Tweaks CMake's default compiler/linker settings to suit Google Test's needs. +# +# This must be a macro(), as inside a function string() can only +# update variables in the function scope. +macro(fix_default_compiler_settings_) + if (MSVC) + # For MSVC, CMake sets certain flags to defaults we want to override. + # This replacement code is taken from sample in the CMake Wiki at + # https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace. + foreach (flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt) + # When Google Test is built as a shared library, it should also use + # shared runtime libraries. Otherwise, it may end up with multiple + # copies of runtime library data in different modules, resulting in + # hard-to-find crashes. When it is built as a static library, it is + # preferable to use CRT as static libraries, as we don't have to rely + # on CRT DLLs being available. CMake always defaults to using shared + # CRT libraries, so we override that default here. + string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}") + endif() + + # We prefer more strict warning checking for building Google Test. + # Replaces /W3 with /W4 in defaults. + string(REPLACE "/W3" "/W4" ${flag_var} "${${flag_var}}") + + # Prevent D9025 warning for targets that have exception handling + # turned off (/EHs-c- flag). Where required, exceptions are explicitly + # re-enabled using the cxx_exception_flags variable. + string(REPLACE "/EHsc" "" ${flag_var} "${${flag_var}}") + endforeach() + endif() +endmacro() + +# Defines the compiler/linker flags used to build Google Test and +# Google Mock. You can tweak these definitions to suit your need. A +# variable's value is empty before it's explicitly assigned to. +macro(config_compiler_and_linker) + # Note: pthreads on MinGW is not supported, even if available + # instead, we use windows threading primitives + unset(GTEST_HAS_PTHREAD) + if (NOT gtest_disable_pthreads AND NOT MINGW) + # Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT. + find_package(Threads) + if (CMAKE_USE_PTHREADS_INIT) + set(GTEST_HAS_PTHREAD ON) + endif() + endif() + + fix_default_compiler_settings_() + if (MSVC) + # Newlines inside flags variables break CMake's NMake generator. + # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds. + set(cxx_base_flags "-GS -W4 -WX -wd4251 -wd4275 -nologo -J -Zi") + set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32") + set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN") + set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1") + set(cxx_no_exception_flags "-EHs-c- -D_HAS_EXCEPTIONS=0") + set(cxx_no_rtti_flags "-GR-") + # Suppress "unreachable code" warning + # http://stackoverflow.com/questions/3232669 explains the issue. + set(cxx_base_flags "${cxx_base_flags} -wd4702") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(cxx_base_flags "-Wall -Wshadow -Werror -Wconversion") + set(cxx_exception_flags "-fexceptions") + set(cxx_no_exception_flags "-fno-exceptions") + set(cxx_strict_flags "-W -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wredundant-decls") + set(cxx_no_rtti_flags "-fno-rtti") + elseif (CMAKE_COMPILER_IS_GNUCXX) + set(cxx_base_flags "-Wall -Wshadow -Werror") + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0) + set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else") + endif() + set(cxx_exception_flags "-fexceptions") + set(cxx_no_exception_flags "-fno-exceptions") + # Until version 4.3.2, GCC doesn't define a macro to indicate + # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI + # explicitly. + set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0") + set(cxx_strict_flags + "-Wextra -Wno-unused-parameter -Wno-missing-field-initializers") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") + set(cxx_exception_flags "-features=except") + # Sun Pro doesn't provide macros to indicate whether exceptions and + # RTTI are enabled, so we define GTEST_HAS_* explicitly. + set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0") + set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR + CMAKE_CXX_COMPILER_ID STREQUAL "XL") + # CMake 2.8 changes Visual Age's compiler ID to "XL". + set(cxx_exception_flags "-qeh") + set(cxx_no_exception_flags "-qnoeh") + # Until version 9.0, Visual Age doesn't define a macro to indicate + # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI + # explicitly. + set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP") + set(cxx_base_flags "-AA -mt") + set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1") + set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0") + # RTTI can not be disabled in HP aCC compiler. + set(cxx_no_rtti_flags "") + endif() + + # The pthreads library is available and allowed? + if (DEFINED GTEST_HAS_PTHREAD) + set(GTEST_HAS_PTHREAD_MACRO "-DGTEST_HAS_PTHREAD=1") + else() + set(GTEST_HAS_PTHREAD_MACRO "-DGTEST_HAS_PTHREAD=0") + endif() + set(cxx_base_flags "${cxx_base_flags} ${GTEST_HAS_PTHREAD_MACRO}") + + # For building gtest's own tests and samples. + set(cxx_exception "${cxx_base_flags} ${cxx_exception_flags}") + set(cxx_no_exception + "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}") + set(cxx_default "${cxx_exception}") + set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}") + + # For building the gtest libraries. + set(cxx_strict "${cxx_default} ${cxx_strict_flags}") +endmacro() + +# Defines the gtest & gtest_main libraries. User tests should link +# with one of them. +function(cxx_library_with_type name type cxx_flags) + # type can be either STATIC or SHARED to denote a static or shared library. + # ARGN refers to additional arguments after 'cxx_flags'. + add_library(${name} ${type} ${ARGN}) + set_target_properties(${name} + PROPERTIES + COMPILE_FLAGS "${cxx_flags}") + # Generate debug library name with a postfix. + set_target_properties(${name} + PROPERTIES + DEBUG_POSTFIX "d") + # Set the output directory for build artifacts + set_target_properties(${name} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") + # make PDBs match library name + get_target_property(pdb_debug_postfix ${name} DEBUG_POSTFIX) + set_target_properties(${name} + PROPERTIES + PDB_NAME "${name}" + PDB_NAME_DEBUG "${name}${pdb_debug_postfix}" + COMPILE_PDB_NAME "${name}" + COMPILE_PDB_NAME_DEBUG "${name}${pdb_debug_postfix}") + + if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED") + set_target_properties(${name} + PROPERTIES + COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1") + if (NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") + target_compile_definitions(${name} INTERFACE + $) + endif() + endif() + if (DEFINED GTEST_HAS_PTHREAD) + if ("${CMAKE_VERSION}" VERSION_LESS "3.1.0") + set(threads_spec ${CMAKE_THREAD_LIBS_INIT}) + else() + set(threads_spec Threads::Threads) + endif() + target_link_libraries(${name} PUBLIC ${threads_spec}) + endif() +endfunction() + +######################################################################## +# +# Helper functions for creating build targets. + +function(cxx_shared_library name cxx_flags) + cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN}) +endfunction() + +function(cxx_library name cxx_flags) + cxx_library_with_type(${name} "" "${cxx_flags}" ${ARGN}) +endfunction() + +# cxx_executable_with_flags(name cxx_flags libs srcs...) +# +# creates a named C++ executable that depends on the given libraries and +# is built from the given source files with the given compiler flags. +function(cxx_executable_with_flags name cxx_flags libs) + add_executable(${name} ${ARGN}) + if (MSVC) + # BigObj required for tests. + set(cxx_flags "${cxx_flags} -bigobj") + endif() + if (cxx_flags) + set_target_properties(${name} + PROPERTIES + COMPILE_FLAGS "${cxx_flags}") + endif() + if (BUILD_SHARED_LIBS) + set_target_properties(${name} + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + endif() + # To support mixing linking in static and dynamic libraries, link each + # library in with an extra call to target_link_libraries. + foreach (lib "${libs}") + target_link_libraries(${name} ${lib}) + endforeach() +endfunction() + +# cxx_executable(name dir lib srcs...) +# +# creates a named target that depends on the given libs and is built +# from the given source files. dir/name.cc is implicitly included in +# the source file list. +function(cxx_executable name dir libs) + cxx_executable_with_flags( + ${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN}) +endfunction() + +# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE. +find_package(PythonInterp) + +# cxx_test_with_flags(name cxx_flags libs srcs...) +# +# creates a named C++ test that depends on the given libs and is built +# from the given source files with the given compiler flags. +function(cxx_test_with_flags name cxx_flags libs) + cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN}) + if (WIN32 OR MINGW) + add_test(NAME ${name} + COMMAND "powershell" "-Command" "${CMAKE_CURRENT_BINARY_DIR}/$/RunTest.ps1" "$") + else() + add_test(NAME ${name} + COMMAND "$") + endif() +endfunction() + +# cxx_test(name libs srcs...) +# +# creates a named test target that depends on the given libs and is +# built from the given source files. Unlike cxx_test_with_flags, +# test/name.cc is already implicitly included in the source file list. +function(cxx_test name libs) + cxx_test_with_flags("${name}" "${cxx_default}" "${libs}" + "test/${name}.cc" ${ARGN}) +endfunction() + +# py_test(name) +# +# creates a Python test with the given name whose main module is in +# test/name.py. It does nothing if Python is not installed. +function(py_test name) + if (PYTHONINTERP_FOUND) + if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 3.1) + if (CMAKE_CONFIGURATION_TYPES) + # Multi-configuration build generators as for Visual Studio save + # output in a subdirectory of CMAKE_CURRENT_BINARY_DIR (Debug, + # Release etc.), so we have to provide it here. + if (WIN32 OR MINGW) + add_test(NAME ${name} + COMMAND powershell -Command ${CMAKE_CURRENT_BINARY_DIR}/$/RunTest.ps1 + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py + --build_dir=${CMAKE_CURRENT_BINARY_DIR}/$ ${ARGN}) + else() + add_test(NAME ${name} + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py + --build_dir=${CMAKE_CURRENT_BINARY_DIR}/$ ${ARGN}) + endif() + else (CMAKE_CONFIGURATION_TYPES) + # Single-configuration build generators like Makefile generators + # don't have subdirs below CMAKE_CURRENT_BINARY_DIR. + if (WIN32 OR MINGW) + add_test(NAME ${name} + COMMAND powershell -Command ${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1 + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py + --build_dir=${CMAKE_CURRENT_BINARY_DIR} ${ARGN}) + else() + add_test(NAME ${name} + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py + --build_dir=${CMAKE_CURRENT_BINARY_DIR} ${ARGN}) + endif() + endif (CMAKE_CONFIGURATION_TYPES) + else() + # ${CMAKE_CURRENT_BINARY_DIR} is known at configuration time, so we can + # directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known + # only at ctest runtime (by calling ctest -c ), so + # we have to escape $ to delay variable substitution here. + if (WIN32 OR MINGW) + add_test(NAME ${name} + COMMAND powershell -Command ${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1 + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py + --build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN}) + else() + add_test(NAME ${name} + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py + --build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN}) + endif() + endif() + endif(PYTHONINTERP_FOUND) +endfunction() + +# install_project(targets...) +# +# Installs the specified targets and configures the associated pkgconfig files. +function(install_project) + if(INSTALL_GTEST) + install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + # Install the project targets. + install(TARGETS ${ARGN} + EXPORT ${targets_export_name} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") + if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + # Install PDBs + foreach(t ${ARGN}) + get_target_property(t_pdb_name ${t} COMPILE_PDB_NAME) + get_target_property(t_pdb_name_debug ${t} COMPILE_PDB_NAME_DEBUG) + get_target_property(t_pdb_output_directory ${t} PDB_OUTPUT_DIRECTORY) + install(FILES + "${t_pdb_output_directory}/\${CMAKE_INSTALL_CONFIG_NAME}/$<$:${t_pdb_name_debug}>$<$>:${t_pdb_name}>.pdb" + DESTINATION ${CMAKE_INSTALL_LIBDIR} + OPTIONAL) + endforeach() + endif() + # Configure and install pkgconfig files. + foreach(t ${ARGN}) + set(configured_pc "${generated_dir}/${t}.pc") + configure_file("${PROJECT_SOURCE_DIR}/cmake/${t}.pc.in" + "${configured_pc}" @ONLY) + install(FILES "${configured_pc}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + endforeach() + endif() +endfunction() diff --git a/3rdparty/gtest/cmake/libgtest.la.in b/3rdparty/gtest/cmake/libgtest.la.in new file mode 100644 index 0000000..840c838 --- /dev/null +++ b/3rdparty/gtest/cmake/libgtest.la.in @@ -0,0 +1,21 @@ +# libgtest.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.6 + +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Names of this library. +library_names='libgtest.so' + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='@CMAKE_INSTALL_FULL_LIBDIR@' diff --git a/3rdparty/gtest/docs/advanced.md b/3rdparty/gtest/docs/advanced.md new file mode 100644 index 0000000..3e5f779 --- /dev/null +++ b/3rdparty/gtest/docs/advanced.md @@ -0,0 +1,2567 @@ +# Advanced googletest Topics + + + +## Introduction + +Now that you have read the [googletest Primer](primer.md) and learned how to +write tests using googletest, it's time to learn some new tricks. This document +will show you more assertions as well as how to construct complex failure +messages, propagate fatal failures, reuse and speed up your test fixtures, and +use various flags with your tests. + +## More Assertions + +This section covers some less frequently used, but still significant, +assertions. + +### Explicit Success and Failure + +These three assertions do not actually test a value or expression. Instead, they +generate a success or failure directly. Like the macros that actually perform a +test, you may stream a custom failure message into them. + +```c++ +SUCCEED(); +``` + +Generates a success. This does **NOT** make the overall test succeed. A test is +considered successful only if none of its assertions fail during its execution. + +NOTE: `SUCCEED()` is purely documentary and currently doesn't generate any +user-visible output. However, we may add `SUCCEED()` messages to googletest's +output in the future. + +```c++ +FAIL(); +ADD_FAILURE(); +ADD_FAILURE_AT("file_path", line_number); +``` + +`FAIL()` generates a fatal failure, while `ADD_FAILURE()` and `ADD_FAILURE_AT()` +generate a nonfatal failure. These are useful when control flow, rather than a +Boolean expression, determines the test's success or failure. For example, you +might want to write something like: + +```c++ +switch(expression) { + case 1: + ... some checks ... + case 2: + ... some other checks ... + default: + FAIL() << "We shouldn't get here."; +} +``` + +NOTE: you can only use `FAIL()` in functions that return `void`. See the +[Assertion Placement section](#assertion-placement) for more information. + +### Exception Assertions + +These are for verifying that a piece of code throws (or does not throw) an +exception of the given type: + +Fatal assertion | Nonfatal assertion | Verifies +------------------------------------------ | ------------------------------------------ | -------- +`ASSERT_THROW(statement, exception_type);` | `EXPECT_THROW(statement, exception_type);` | `statement` throws an exception of the given type +`ASSERT_ANY_THROW(statement);` | `EXPECT_ANY_THROW(statement);` | `statement` throws an exception of any type +`ASSERT_NO_THROW(statement);` | `EXPECT_NO_THROW(statement);` | `statement` doesn't throw any exception + +Examples: + +```c++ +ASSERT_THROW(Foo(5), bar_exception); + +EXPECT_NO_THROW({ + int n = 5; + Bar(&n); +}); +``` + +**Availability**: requires exceptions to be enabled in the build environment + +### Predicate Assertions for Better Error Messages + +Even though googletest has a rich set of assertions, they can never be complete, +as it's impossible (nor a good idea) to anticipate all scenarios a user might +run into. Therefore, sometimes a user has to use `EXPECT_TRUE()` to check a +complex expression, for lack of a better macro. This has the problem of not +showing you the values of the parts of the expression, making it hard to +understand what went wrong. As a workaround, some users choose to construct the +failure message by themselves, streaming it into `EXPECT_TRUE()`. However, this +is awkward especially when the expression has side-effects or is expensive to +evaluate. + +googletest gives you three different options to solve this problem: + +#### Using an Existing Boolean Function + +If you already have a function or functor that returns `bool` (or a type that +can be implicitly converted to `bool`), you can use it in a *predicate +assertion* to get the function arguments printed for free: + + + +| Fatal assertion | Nonfatal assertion | Verifies | +| --------------------------------- | --------------------------------- | --------------------------- | +| `ASSERT_PRED1(pred1, val1)` | `EXPECT_PRED1(pred1, val1)` | `pred1(val1)` is true | +| `ASSERT_PRED2(pred2, val1, val2)` | `EXPECT_PRED2(pred2, val1, val2)` | `pred1(val1, val2)` is true | +| `...` | `...` | `...` | + + +In the above, `predn` is an `n`-ary predicate function or functor, where `val1`, +`val2`, ..., and `valn` are its arguments. The assertion succeeds if the +predicate returns `true` when applied to the given arguments, and fails +otherwise. When the assertion fails, it prints the value of each argument. In +either case, the arguments are evaluated exactly once. + +Here's an example. Given + +```c++ +// Returns true if m and n have no common divisors except 1. +bool MutuallyPrime(int m, int n) { ... } + +const int a = 3; +const int b = 4; +const int c = 10; +``` + +the assertion + +```c++ + EXPECT_PRED2(MutuallyPrime, a, b); +``` + +will succeed, while the assertion + +```c++ + EXPECT_PRED2(MutuallyPrime, b, c); +``` + +will fail with the message + +```none +MutuallyPrime(b, c) is false, where +b is 4 +c is 10 +``` + +> NOTE: +> +> 1. If you see a compiler error "no matching function to call" when using +> `ASSERT_PRED*` or `EXPECT_PRED*`, please see +> [this](faq.md#the-compiler-complains-no-matching-function-to-call-when-i-use-assert-pred-how-do-i-fix-it) +> for how to resolve it. + +#### Using a Function That Returns an AssertionResult + +While `EXPECT_PRED*()` and friends are handy for a quick job, the syntax is not +satisfactory: you have to use different macros for different arities, and it +feels more like Lisp than C++. The `::testing::AssertionResult` class solves +this problem. + +An `AssertionResult` object represents the result of an assertion (whether it's +a success or a failure, and an associated message). You can create an +`AssertionResult` using one of these factory functions: + +```c++ +namespace testing { + +// Returns an AssertionResult object to indicate that an assertion has +// succeeded. +AssertionResult AssertionSuccess(); + +// Returns an AssertionResult object to indicate that an assertion has +// failed. +AssertionResult AssertionFailure(); + +} +``` + +You can then use the `<<` operator to stream messages to the `AssertionResult` +object. + +To provide more readable messages in Boolean assertions (e.g. `EXPECT_TRUE()`), +write a predicate function that returns `AssertionResult` instead of `bool`. For +example, if you define `IsEven()` as: + +```c++ +::testing::AssertionResult IsEven(int n) { + if ((n % 2) == 0) + return ::testing::AssertionSuccess(); + else + return ::testing::AssertionFailure() << n << " is odd"; +} +``` + +instead of: + +```c++ +bool IsEven(int n) { + return (n % 2) == 0; +} +``` + +the failed assertion `EXPECT_TRUE(IsEven(Fib(4)))` will print: + +```none +Value of: IsEven(Fib(4)) + Actual: false (3 is odd) +Expected: true +``` + +instead of a more opaque + +```none +Value of: IsEven(Fib(4)) + Actual: false +Expected: true +``` + +If you want informative messages in `EXPECT_FALSE` and `ASSERT_FALSE` as well +(one third of Boolean assertions in the Google code base are negative ones), and +are fine with making the predicate slower in the success case, you can supply a +success message: + +```c++ +::testing::AssertionResult IsEven(int n) { + if ((n % 2) == 0) + return ::testing::AssertionSuccess() << n << " is even"; + else + return ::testing::AssertionFailure() << n << " is odd"; +} +``` + +Then the statement `EXPECT_FALSE(IsEven(Fib(6)))` will print + +```none + Value of: IsEven(Fib(6)) + Actual: true (8 is even) + Expected: false +``` + +#### Using a Predicate-Formatter + +If you find the default message generated by `(ASSERT|EXPECT)_PRED*` and +`(ASSERT|EXPECT)_(TRUE|FALSE)` unsatisfactory, or some arguments to your +predicate do not support streaming to `ostream`, you can instead use the +following *predicate-formatter assertions* to *fully* customize how the message +is formatted: + +Fatal assertion | Nonfatal assertion | Verifies +------------------------------------------------ | ------------------------------------------------ | -------- +`ASSERT_PRED_FORMAT1(pred_format1, val1);` | `EXPECT_PRED_FORMAT1(pred_format1, val1);` | `pred_format1(val1)` is successful +`ASSERT_PRED_FORMAT2(pred_format2, val1, val2);` | `EXPECT_PRED_FORMAT2(pred_format2, val1, val2);` | `pred_format2(val1, val2)` is successful +`...` | `...` | ... + +The difference between this and the previous group of macros is that instead of +a predicate, `(ASSERT|EXPECT)_PRED_FORMAT*` take a *predicate-formatter* +(`pred_formatn`), which is a function or functor with the signature: + +```c++ +::testing::AssertionResult PredicateFormattern(const char* expr1, + const char* expr2, + ... + const char* exprn, + T1 val1, + T2 val2, + ... + Tn valn); +``` + +where `val1`, `val2`, ..., and `valn` are the values of the predicate arguments, +and `expr1`, `expr2`, ..., and `exprn` are the corresponding expressions as they +appear in the source code. The types `T1`, `T2`, ..., and `Tn` can be either +value types or reference types. For example, if an argument has type `Foo`, you +can declare it as either `Foo` or `const Foo&`, whichever is appropriate. + +As an example, let's improve the failure message in `MutuallyPrime()`, which was +used with `EXPECT_PRED2()`: + +```c++ +// Returns the smallest prime common divisor of m and n, +// or 1 when m and n are mutually prime. +int SmallestPrimeCommonDivisor(int m, int n) { ... } + +// A predicate-formatter for asserting that two integers are mutually prime. +::testing::AssertionResult AssertMutuallyPrime(const char* m_expr, + const char* n_expr, + int m, + int n) { + if (MutuallyPrime(m, n)) return ::testing::AssertionSuccess(); + + return ::testing::AssertionFailure() << m_expr << " and " << n_expr + << " (" << m << " and " << n << ") are not mutually prime, " + << "as they have a common divisor " << SmallestPrimeCommonDivisor(m, n); +} +``` + +With this predicate-formatter, we can use + +```c++ + EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c); +``` + +to generate the message + +```none +b and c (4 and 10) are not mutually prime, as they have a common divisor 2. +``` + +As you may have realized, many of the built-in assertions we introduced earlier +are special cases of `(EXPECT|ASSERT)_PRED_FORMAT*`. In fact, most of them are +indeed defined using `(EXPECT|ASSERT)_PRED_FORMAT*`. + +### Floating-Point Comparison + +Comparing floating-point numbers is tricky. Due to round-off errors, it is very +unlikely that two floating-points will match exactly. Therefore, `ASSERT_EQ` 's +naive comparison usually doesn't work. And since floating-points can have a wide +value range, no single fixed error bound works. It's better to compare by a +fixed relative error bound, except for values close to 0 due to the loss of +precision there. + +In general, for floating-point comparison to make sense, the user needs to +carefully choose the error bound. If they don't want or care to, comparing in +terms of Units in the Last Place (ULPs) is a good default, and googletest +provides assertions to do this. Full details about ULPs are quite long; if you +want to learn more, see +[here](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). + +#### Floating-Point Macros + + + +| Fatal assertion | Nonfatal assertion | Verifies | +| ------------------------------- | ------------------------------- | ---------------------------------------- | +| `ASSERT_FLOAT_EQ(val1, val2);` | `EXPECT_FLOAT_EQ(val1, val2);` | the two `float` values are almost equal | +| `ASSERT_DOUBLE_EQ(val1, val2);` | `EXPECT_DOUBLE_EQ(val1, val2);` | the two `double` values are almost equal | + + + +By "almost equal" we mean the values are within 4 ULP's from each other. + +The following assertions allow you to choose the acceptable error bound: + + + +| Fatal assertion | Nonfatal assertion | Verifies | +| ------------------------------------- | ------------------------------------- | -------------------------------------------------------------------------------- | +| `ASSERT_NEAR(val1, val2, abs_error);` | `EXPECT_NEAR(val1, val2, abs_error);` | the difference between `val1` and `val2` doesn't exceed the given absolute error | + + + +#### Floating-Point Predicate-Format Functions + +Some floating-point operations are useful, but not that often used. In order to +avoid an explosion of new macros, we provide them as predicate-format functions +that can be used in predicate assertion macros (e.g. `EXPECT_PRED_FORMAT2`, +etc). + +```c++ +EXPECT_PRED_FORMAT2(::testing::FloatLE, val1, val2); +EXPECT_PRED_FORMAT2(::testing::DoubleLE, val1, val2); +``` + +Verifies that `val1` is less than, or almost equal to, `val2`. You can replace +`EXPECT_PRED_FORMAT2` in the above table with `ASSERT_PRED_FORMAT2`. + +### Asserting Using gMock Matchers + +[gMock](../../googlemock) comes with a library of matchers for validating +arguments passed to mock objects. A gMock *matcher* is basically a predicate +that knows how to describe itself. It can be used in these assertion macros: + + + +| Fatal assertion | Nonfatal assertion | Verifies | +| ------------------------------ | ------------------------------ | --------------------- | +| `ASSERT_THAT(value, matcher);` | `EXPECT_THAT(value, matcher);` | value matches matcher | + + + +For example, `StartsWith(prefix)` is a matcher that matches a string starting +with `prefix`, and you can write: + +```c++ +using ::testing::StartsWith; +... + // Verifies that Foo() returns a string starting with "Hello". + EXPECT_THAT(Foo(), StartsWith("Hello")); +``` + +Read this +[recipe](../../googlemock/docs/cook_book.md#using-matchers-in-googletest-assertions) +in the gMock Cookbook for more details. + +gMock has a rich set of matchers. You can do many things googletest cannot do +alone with them. For a list of matchers gMock provides, read +[this](../../googlemock/docs/cook_book.md##using-matchers). It's easy to write +your [own matchers](../../googlemock/docs/cook_book.md#NewMatchers) too. + +gMock is bundled with googletest, so you don't need to add any build dependency +in order to take advantage of this. Just include `"testing/base/public/gmock.h"` +and you're ready to go. + +### More String Assertions + +(Please read the [previous](#asserting-using-gmock-matchers) section first if +you haven't.) + +You can use the gMock +[string matchers](../../googlemock/docs/cheat_sheet.md#string-matchers) with +`EXPECT_THAT()` or `ASSERT_THAT()` to do more string comparison tricks +(sub-string, prefix, suffix, regular expression, and etc). For example, + +```c++ +using ::testing::HasSubstr; +using ::testing::MatchesRegex; +... + ASSERT_THAT(foo_string, HasSubstr("needle")); + EXPECT_THAT(bar_string, MatchesRegex("\\w*\\d+")); +``` + +If the string contains a well-formed HTML or XML document, you can check whether +its DOM tree matches an +[XPath expression](http://www.w3.org/TR/xpath/#contents): + +```c++ +// Currently still in //template/prototemplate/testing:xpath_matcher +#include "template/prototemplate/testing/xpath_matcher.h" +using prototemplate::testing::MatchesXPath; +EXPECT_THAT(html_string, MatchesXPath("//a[text()='click here']")); +``` + +### Windows HRESULT assertions + +These assertions test for `HRESULT` success or failure. + +Fatal assertion | Nonfatal assertion | Verifies +-------------------------------------- | -------------------------------------- | -------- +`ASSERT_HRESULT_SUCCEEDED(expression)` | `EXPECT_HRESULT_SUCCEEDED(expression)` | `expression` is a success `HRESULT` +`ASSERT_HRESULT_FAILED(expression)` | `EXPECT_HRESULT_FAILED(expression)` | `expression` is a failure `HRESULT` + +The generated output contains the human-readable error message associated with +the `HRESULT` code returned by `expression`. + +You might use them like this: + +```c++ +CComPtr shell; +ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L"Shell.Application")); +CComVariant empty; +ASSERT_HRESULT_SUCCEEDED(shell->ShellExecute(CComBSTR(url), empty, empty, empty, empty)); +``` + +### Type Assertions + +You can call the function + +```c++ +::testing::StaticAssertTypeEq(); +``` + +to assert that types `T1` and `T2` are the same. The function does nothing if +the assertion is satisfied. If the types are different, the function call will +fail to compile, the compiler error message will say that +`type1 and type2 are not the same type` and most likely (depending on the compiler) +show you the actual values of `T1` and `T2`. This is mainly useful inside +template code. + +**Caveat**: When used inside a member function of a class template or a function +template, `StaticAssertTypeEq()` is effective only if the function is +instantiated. For example, given: + +```c++ +template class Foo { + public: + void Bar() { ::testing::StaticAssertTypeEq(); } +}; +``` + +the code: + +```c++ +void Test1() { Foo foo; } +``` + +will not generate a compiler error, as `Foo::Bar()` is never actually +instantiated. Instead, you need: + +```c++ +void Test2() { Foo foo; foo.Bar(); } +``` + +to cause a compiler error. + +### Assertion Placement + +You can use assertions in any C++ function. In particular, it doesn't have to be +a method of the test fixture class. The one constraint is that assertions that +generate a fatal failure (`FAIL*` and `ASSERT_*`) can only be used in +void-returning functions. This is a consequence of Google's not using +exceptions. By placing it in a non-void function you'll get a confusing compile +error like `"error: void value not ignored as it ought to be"` or `"cannot +initialize return object of type 'bool' with an rvalue of type 'void'"` or +`"error: no viable conversion from 'void' to 'string'"`. + +If you need to use fatal assertions in a function that returns non-void, one +option is to make the function return the value in an out parameter instead. For +example, you can rewrite `T2 Foo(T1 x)` to `void Foo(T1 x, T2* result)`. You +need to make sure that `*result` contains some sensible value even when the +function returns prematurely. As the function now returns `void`, you can use +any assertion inside of it. + +If changing the function's type is not an option, you should just use assertions +that generate non-fatal failures, such as `ADD_FAILURE*` and `EXPECT_*`. + +NOTE: Constructors and destructors are not considered void-returning functions, +according to the C++ language specification, and so you may not use fatal +assertions in them; you'll get a compilation error if you try. Instead, either +call `abort` and crash the entire test executable, or put the fatal assertion in +a `SetUp`/`TearDown` function; see +[constructor/destructor vs. `SetUp`/`TearDown`](faq.md#CtorVsSetUp) + +WARNING: A fatal assertion in a helper function (private void-returning method) +called from a constructor or destructor does not does not terminate the current +test, as your intuition might suggest: it merely returns from the constructor or +destructor early, possibly leaving your object in a partially-constructed or +partially-destructed state! You almost certainly want to `abort` or use +`SetUp`/`TearDown` instead. + +## Teaching googletest How to Print Your Values + +When a test assertion such as `EXPECT_EQ` fails, googletest prints the argument +values to help you debug. It does this using a user-extensible value printer. + +This printer knows how to print built-in C++ types, native arrays, STL +containers, and any type that supports the `<<` operator. For other types, it +prints the raw bytes in the value and hopes that you the user can figure it out. + +As mentioned earlier, the printer is *extensible*. That means you can teach it +to do a better job at printing your particular type than to dump the bytes. To +do that, define `<<` for your type: + +```c++ +#include + +namespace foo { + +class Bar { // We want googletest to be able to print instances of this. +... + // Create a free inline friend function. + friend std::ostream& operator<<(std::ostream& os, const Bar& bar) { + return os << bar.DebugString(); // whatever needed to print bar to os + } +}; + +// If you can't declare the function in the class it's important that the +// << operator is defined in the SAME namespace that defines Bar. C++'s look-up +// rules rely on that. +std::ostream& operator<<(std::ostream& os, const Bar& bar) { + return os << bar.DebugString(); // whatever needed to print bar to os +} + +} // namespace foo +``` + +Sometimes, this might not be an option: your team may consider it bad style to +have a `<<` operator for `Bar`, or `Bar` may already have a `<<` operator that +doesn't do what you want (and you cannot change it). If so, you can instead +define a `PrintTo()` function like this: + +```c++ +#include + +namespace foo { + +class Bar { + ... + friend void PrintTo(const Bar& bar, std::ostream* os) { + *os << bar.DebugString(); // whatever needed to print bar to os + } +}; + +// If you can't declare the function in the class it's important that PrintTo() +// is defined in the SAME namespace that defines Bar. C++'s look-up rules rely +// on that. +void PrintTo(const Bar& bar, std::ostream* os) { + *os << bar.DebugString(); // whatever needed to print bar to os +} + +} // namespace foo +``` + +If you have defined both `<<` and `PrintTo()`, the latter will be used when +googletest is concerned. This allows you to customize how the value appears in +googletest's output without affecting code that relies on the behavior of its +`<<` operator. + +If you want to print a value `x` using googletest's value printer yourself, just +call `::testing::PrintToString(x)`, which returns an `std::string`: + +```c++ +vector > bar_ints = GetBarIntVector(); + +EXPECT_TRUE(IsCorrectBarIntVector(bar_ints)) + << "bar_ints = " << ::testing::PrintToString(bar_ints); +``` + +## Death Tests + +In many applications, there are assertions that can cause application failure if +a condition is not met. These sanity checks, which ensure that the program is in +a known good state, are there to fail at the earliest possible time after some +program state is corrupted. If the assertion checks the wrong condition, then +the program may proceed in an erroneous state, which could lead to memory +corruption, security holes, or worse. Hence it is vitally important to test that +such assertion statements work as expected. + +Since these precondition checks cause the processes to die, we call such tests +_death tests_. More generally, any test that checks that a program terminates +(except by throwing an exception) in an expected fashion is also a death test. + +Note that if a piece of code throws an exception, we don't consider it "death" +for the purpose of death tests, as the caller of the code could catch the +exception and avoid the crash. If you want to verify exceptions thrown by your +code, see [Exception Assertions](#ExceptionAssertions). + +If you want to test `EXPECT_*()/ASSERT_*()` failures in your test code, see +Catching Failures + +### How to Write a Death Test + +googletest has the following macros to support death tests: + +Fatal assertion | Nonfatal assertion | Verifies +------------------------------------------------ | ------------------------------------------------ | -------- +`ASSERT_DEATH(statement, matcher);` | `EXPECT_DEATH(statement, matcher);` | `statement` crashes with the given error +`ASSERT_DEATH_IF_SUPPORTED(statement, matcher);` | `EXPECT_DEATH_IF_SUPPORTED(statement, matcher);` | if death tests are supported, verifies that `statement` crashes with the given error; otherwise verifies nothing +`ASSERT_EXIT(statement, predicate, matcher);` | `EXPECT_EXIT(statement, predicate, matcher);` | `statement` exits with the given error, and its exit code matches `predicate` + +where `statement` is a statement that is expected to cause the process to die, +`predicate` is a function or function object that evaluates an integer exit +status, and `matcher` is either a GMock matcher matching a `const std::string&` +or a (Perl) regular expression - either of which is matched against the stderr +output of `statement`. For legacy reasons, a bare string (i.e. with no matcher) +is interpreted as `ContainsRegex(str)`, **not** `Eq(str)`. Note that `statement` +can be *any valid statement* (including *compound statement*) and doesn't have +to be an expression. + +As usual, the `ASSERT` variants abort the current test function, while the +`EXPECT` variants do not. + +> NOTE: We use the word "crash" here to mean that the process terminates with a +> *non-zero* exit status code. There are two possibilities: either the process +> has called `exit()` or `_exit()` with a non-zero value, or it may be killed by +> a signal. +> +> This means that if `*statement*` terminates the process with a 0 exit code, it +> is *not* considered a crash by `EXPECT_DEATH`. Use `EXPECT_EXIT` instead if +> this is the case, or if you want to restrict the exit code more precisely. + +A predicate here must accept an `int` and return a `bool`. The death test +succeeds only if the predicate returns `true`. googletest defines a few +predicates that handle the most common cases: + +```c++ +::testing::ExitedWithCode(exit_code) +``` + +This expression is `true` if the program exited normally with the given exit +code. + +```c++ +::testing::KilledBySignal(signal_number) // Not available on Windows. +``` + +This expression is `true` if the program was killed by the given signal. + +The `*_DEATH` macros are convenient wrappers for `*_EXIT` that use a predicate +that verifies the process' exit code is non-zero. + +Note that a death test only cares about three things: + +1. does `statement` abort or exit the process? +2. (in the case of `ASSERT_EXIT` and `EXPECT_EXIT`) does the exit status + satisfy `predicate`? Or (in the case of `ASSERT_DEATH` and `EXPECT_DEATH`) + is the exit status non-zero? And +3. does the stderr output match `regex`? + +In particular, if `statement` generates an `ASSERT_*` or `EXPECT_*` failure, it +will **not** cause the death test to fail, as googletest assertions don't abort +the process. + +To write a death test, simply use one of the above macros inside your test +function. For example, + +```c++ +TEST(MyDeathTest, Foo) { + // This death test uses a compound statement. + ASSERT_DEATH({ + int n = 5; + Foo(&n); + }, "Error on line .* of Foo()"); +} + +TEST(MyDeathTest, NormalExit) { + EXPECT_EXIT(NormalExit(), ::testing::ExitedWithCode(0), "Success"); +} + +TEST(MyDeathTest, KillMyself) { + EXPECT_EXIT(KillMyself(), ::testing::KilledBySignal(SIGKILL), + "Sending myself unblockable signal"); +} +``` + +verifies that: + +* calling `Foo(5)` causes the process to die with the given error message, +* calling `NormalExit()` causes the process to print `"Success"` to stderr and + exit with exit code 0, and +* calling `KillMyself()` kills the process with signal `SIGKILL`. + +The test function body may contain other assertions and statements as well, if +necessary. + +### Death Test Naming + +IMPORTANT: We strongly recommend you to follow the convention of naming your +**test suite** (not test) `*DeathTest` when it contains a death test, as +demonstrated in the above example. The +[Death Tests And Threads](#death-tests-and-threads) section below explains why. + +If a test fixture class is shared by normal tests and death tests, you can use +`using` or `typedef` to introduce an alias for the fixture class and avoid +duplicating its code: + +```c++ +class FooTest : public ::testing::Test { ... }; + +using FooDeathTest = FooTest; + +TEST_F(FooTest, DoesThis) { + // normal test +} + +TEST_F(FooDeathTest, DoesThat) { + // death test +} +``` + +### Regular Expression Syntax + +On POSIX systems (e.g. Linux, Cygwin, and Mac), googletest uses the +[POSIX extended regular expression](http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04) +syntax. To learn about this syntax, you may want to read this +[Wikipedia entry](http://en.wikipedia.org/wiki/Regular_expression#POSIX_Extended_Regular_Expressions). + +On Windows, googletest uses its own simple regular expression implementation. It +lacks many features. For example, we don't support union (`"x|y"`), grouping +(`"(xy)"`), brackets (`"[xy]"`), and repetition count (`"x{5,7}"`), among +others. Below is what we do support (`A` denotes a literal character, period +(`.`), or a single `\\ ` escape sequence; `x` and `y` denote regular +expressions.): + +Expression | Meaning +---------- | -------------------------------------------------------------- +`c` | matches any literal character `c` +`\\d` | matches any decimal digit +`\\D` | matches any character that's not a decimal digit +`\\f` | matches `\f` +`\\n` | matches `\n` +`\\r` | matches `\r` +`\\s` | matches any ASCII whitespace, including `\n` +`\\S` | matches any character that's not a whitespace +`\\t` | matches `\t` +`\\v` | matches `\v` +`\\w` | matches any letter, `_`, or decimal digit +`\\W` | matches any character that `\\w` doesn't match +`\\c` | matches any literal character `c`, which must be a punctuation +`.` | matches any single character except `\n` +`A?` | matches 0 or 1 occurrences of `A` +`A*` | matches 0 or many occurrences of `A` +`A+` | matches 1 or many occurrences of `A` +`^` | matches the beginning of a string (not that of each line) +`$` | matches the end of a string (not that of each line) +`xy` | matches `x` followed by `y` + +To help you determine which capability is available on your system, googletest +defines macros to govern which regular expression it is using. The macros are: +`GTEST_USES_SIMPLE_RE=1` or `GTEST_USES_POSIX_RE=1`. If you want your death +tests to work in all cases, you can either `#if` on these macros or use the more +limited syntax only. + +### How It Works + +Under the hood, `ASSERT_EXIT()` spawns a new process and executes the death test +statement in that process. The details of how precisely that happens depend on +the platform and the variable ::testing::GTEST_FLAG(death_test_style) (which is +initialized from the command-line flag `--gtest_death_test_style`). + +* On POSIX systems, `fork()` (or `clone()` on Linux) is used to spawn the + child, after which: + * If the variable's value is `"fast"`, the death test statement is + immediately executed. + * If the variable's value is `"threadsafe"`, the child process re-executes + the unit test binary just as it was originally invoked, but with some + extra flags to cause just the single death test under consideration to + be run. +* On Windows, the child is spawned using the `CreateProcess()` API, and + re-executes the binary to cause just the single death test under + consideration to be run - much like the `threadsafe` mode on POSIX. + +Other values for the variable are illegal and will cause the death test to fail. +Currently, the flag's default value is **"fast"** + +1. the child's exit status satisfies the predicate, and +2. the child's stderr matches the regular expression. + +If the death test statement runs to completion without dying, the child process +will nonetheless terminate, and the assertion fails. + +### Death Tests And Threads + +The reason for the two death test styles has to do with thread safety. Due to +well-known problems with forking in the presence of threads, death tests should +be run in a single-threaded context. Sometimes, however, it isn't feasible to +arrange that kind of environment. For example, statically-initialized modules +may start threads before main is ever reached. Once threads have been created, +it may be difficult or impossible to clean them up. + +googletest has three features intended to raise awareness of threading issues. + +1. A warning is emitted if multiple threads are running when a death test is + encountered. +2. Test suites with a name ending in "DeathTest" are run before all other + tests. +3. It uses `clone()` instead of `fork()` to spawn the child process on Linux + (`clone()` is not available on Cygwin and Mac), as `fork()` is more likely + to cause the child to hang when the parent process has multiple threads. + +It's perfectly fine to create threads inside a death test statement; they are +executed in a separate process and cannot affect the parent. + +### Death Test Styles + +The "threadsafe" death test style was introduced in order to help mitigate the +risks of testing in a possibly multithreaded environment. It trades increased +test execution time (potentially dramatically so) for improved thread safety. + +The automated testing framework does not set the style flag. You can choose a +particular style of death tests by setting the flag programmatically: + +```c++ +testing::FLAGS_gtest_death_test_style="threadsafe" +``` + +You can do this in `main()` to set the style for all death tests in the binary, +or in individual tests. Recall that flags are saved before running each test and +restored afterwards, so you need not do that yourself. For example: + +```c++ +int main(int argc, char** argv) { + InitGoogle(argv[0], &argc, &argv, true); + ::testing::FLAGS_gtest_death_test_style = "fast"; + return RUN_ALL_TESTS(); +} + +TEST(MyDeathTest, TestOne) { + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + // This test is run in the "threadsafe" style: + ASSERT_DEATH(ThisShouldDie(), ""); +} + +TEST(MyDeathTest, TestTwo) { + // This test is run in the "fast" style: + ASSERT_DEATH(ThisShouldDie(), ""); +} +``` + +### Caveats + +The `statement` argument of `ASSERT_EXIT()` can be any valid C++ statement. If +it leaves the current function via a `return` statement or by throwing an +exception, the death test is considered to have failed. Some googletest macros +may return from the current function (e.g. `ASSERT_TRUE()`), so be sure to avoid +them in `statement`. + +Since `statement` runs in the child process, any in-memory side effect (e.g. +modifying a variable, releasing memory, etc) it causes will *not* be observable +in the parent process. In particular, if you release memory in a death test, +your program will fail the heap check as the parent process will never see the +memory reclaimed. To solve this problem, you can + +1. try not to free memory in a death test; +2. free the memory again in the parent process; or +3. do not use the heap checker in your program. + +Due to an implementation detail, you cannot place multiple death test assertions +on the same line; otherwise, compilation will fail with an unobvious error +message. + +Despite the improved thread safety afforded by the "threadsafe" style of death +test, thread problems such as deadlock are still possible in the presence of +handlers registered with `pthread_atfork(3)`. + + +## Using Assertions in Sub-routines + +### Adding Traces to Assertions + +If a test sub-routine is called from several places, when an assertion inside it +fails, it can be hard to tell which invocation of the sub-routine the failure is +from. You can alleviate this problem using extra logging or custom failure +messages, but that usually clutters up your tests. A better solution is to use +the `SCOPED_TRACE` macro or the `ScopedTrace` utility: + +```c++ +SCOPED_TRACE(message); +ScopedTrace trace("file_path", line_number, message); +``` + +where `message` can be anything streamable to `std::ostream`. `SCOPED_TRACE` +macro will cause the current file name, line number, and the given message to be +added in every failure message. `ScopedTrace` accepts explicit file name and +line number in arguments, which is useful for writing test helpers. The effect +will be undone when the control leaves the current lexical scope. + +For example, + +```c++ +10: void Sub1(int n) { +11: EXPECT_EQ(Bar(n), 1); +12: EXPECT_EQ(Bar(n + 1), 2); +13: } +14: +15: TEST(FooTest, Bar) { +16: { +17: SCOPED_TRACE("A"); // This trace point will be included in +18: // every failure in this scope. +19: Sub1(1); +20: } +21: // Now it won't. +22: Sub1(9); +23: } +``` + +could result in messages like these: + +```none +path/to/foo_test.cc:11: Failure +Value of: Bar(n) +Expected: 1 + Actual: 2 + Trace: +path/to/foo_test.cc:17: A + +path/to/foo_test.cc:12: Failure +Value of: Bar(n + 1) +Expected: 2 + Actual: 3 +``` + +Without the trace, it would've been difficult to know which invocation of +`Sub1()` the two failures come from respectively. (You could add an extra +message to each assertion in `Sub1()` to indicate the value of `n`, but that's +tedious.) + +Some tips on using `SCOPED_TRACE`: + +1. With a suitable message, it's often enough to use `SCOPED_TRACE` at the + beginning of a sub-routine, instead of at each call site. +2. When calling sub-routines inside a loop, make the loop iterator part of the + message in `SCOPED_TRACE` such that you can know which iteration the failure + is from. +3. Sometimes the line number of the trace point is enough for identifying the + particular invocation of a sub-routine. In this case, you don't have to + choose a unique message for `SCOPED_TRACE`. You can simply use `""`. +4. You can use `SCOPED_TRACE` in an inner scope when there is one in the outer + scope. In this case, all active trace points will be included in the failure + messages, in reverse order they are encountered. +5. The trace dump is clickable in Emacs - hit `return` on a line number and + you'll be taken to that line in the source file! + +### Propagating Fatal Failures + +A common pitfall when using `ASSERT_*` and `FAIL*` is not understanding that +when they fail they only abort the _current function_, not the entire test. For +example, the following test will segfault: + +```c++ +void Subroutine() { + // Generates a fatal failure and aborts the current function. + ASSERT_EQ(1, 2); + + // The following won't be executed. + ... +} + +TEST(FooTest, Bar) { + Subroutine(); // The intended behavior is for the fatal failure + // in Subroutine() to abort the entire test. + + // The actual behavior: the function goes on after Subroutine() returns. + int* p = NULL; + *p = 3; // Segfault! +} +``` + +To alleviate this, googletest provides three different solutions. You could use +either exceptions, the `(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the +`HasFatalFailure()` function. They are described in the following two +subsections. + +#### Asserting on Subroutines with an exception + +The following code can turn ASSERT-failure into an exception: + +```c++ +class ThrowListener : public testing::EmptyTestEventListener { + void OnTestPartResult(const testing::TestPartResult& result) override { + if (result.type() == testing::TestPartResult::kFatalFailure) { + throw testing::AssertionException(result); + } + } +}; +int main(int argc, char** argv) { + ... + testing::UnitTest::GetInstance()->listeners().Append(new ThrowListener); + return RUN_ALL_TESTS(); +} +``` + +This listener should be added after other listeners if you have any, otherwise +they won't see failed `OnTestPartResult`. + +#### Asserting on Subroutines + +As shown above, if your test calls a subroutine that has an `ASSERT_*` failure +in it, the test will continue after the subroutine returns. This may not be what +you want. + +Often people want fatal failures to propagate like exceptions. For that +googletest offers the following macros: + +Fatal assertion | Nonfatal assertion | Verifies +------------------------------------- | ------------------------------------- | -------- +`ASSERT_NO_FATAL_FAILURE(statement);` | `EXPECT_NO_FATAL_FAILURE(statement);` | `statement` doesn't generate any new fatal failures in the current thread. + +Only failures in the thread that executes the assertion are checked to determine +the result of this type of assertions. If `statement` creates new threads, +failures in these threads are ignored. + +Examples: + +```c++ +ASSERT_NO_FATAL_FAILURE(Foo()); + +int i; +EXPECT_NO_FATAL_FAILURE({ + i = Bar(); +}); +``` + +Assertions from multiple threads are currently not supported on Windows. + +#### Checking for Failures in the Current Test + +`HasFatalFailure()` in the `::testing::Test` class returns `true` if an +assertion in the current test has suffered a fatal failure. This allows +functions to catch fatal failures in a sub-routine and return early. + +```c++ +class Test { + public: + ... + static bool HasFatalFailure(); +}; +``` + +The typical usage, which basically simulates the behavior of a thrown exception, +is: + +```c++ +TEST(FooTest, Bar) { + Subroutine(); + // Aborts if Subroutine() had a fatal failure. + if (HasFatalFailure()) return; + + // The following won't be executed. + ... +} +``` + +If `HasFatalFailure()` is used outside of `TEST()` , `TEST_F()` , or a test +fixture, you must add the `::testing::Test::` prefix, as in: + +```c++ +if (::testing::Test::HasFatalFailure()) return; +``` + +Similarly, `HasNonfatalFailure()` returns `true` if the current test has at +least one non-fatal failure, and `HasFailure()` returns `true` if the current +test has at least one failure of either kind. + +## Logging Additional Information + +In your test code, you can call `RecordProperty("key", value)` to log additional +information, where `value` can be either a string or an `int`. The *last* value +recorded for a key will be emitted to the +[XML output](#generating-an-xml-report) if you specify one. For example, the +test + +```c++ +TEST_F(WidgetUsageTest, MinAndMaxWidgets) { + RecordProperty("MaximumWidgets", ComputeMaxUsage()); + RecordProperty("MinimumWidgets", ComputeMinUsage()); +} +``` + +will output XML like this: + +```xml + ... + + ... +``` + +> NOTE: +> +> * `RecordProperty()` is a static member of the `Test` class. Therefore it +> needs to be prefixed with `::testing::Test::` if used outside of the +> `TEST` body and the test fixture class. +> * `*key*` must be a valid XML attribute name, and cannot conflict with the +> ones already used by googletest (`name`, `status`, `time`, `classname`, +> `type_param`, and `value_param`). +> * Calling `RecordProperty()` outside of the lifespan of a test is allowed. +> If it's called outside of a test but between a test suite's +> `SetUpTestSuite()` and `TearDownTestSuite()` methods, it will be +> attributed to the XML element for the test suite. If it's called outside +> of all test suites (e.g. in a test environment), it will be attributed to +> the top-level XML element. + +## Sharing Resources Between Tests in the Same Test Suite + +googletest creates a new test fixture object for each test in order to make +tests independent and easier to debug. However, sometimes tests use resources +that are expensive to set up, making the one-copy-per-test model prohibitively +expensive. + +If the tests don't change the resource, there's no harm in their sharing a +single resource copy. So, in addition to per-test set-up/tear-down, googletest +also supports per-test-suite set-up/tear-down. To use it: + +1. In your test fixture class (say `FooTest` ), declare as `static` some member + variables to hold the shared resources. +2. Outside your test fixture class (typically just below it), define those + member variables, optionally giving them initial values. +3. In the same test fixture class, define a `static void SetUpTestSuite()` + function (remember not to spell it as **`SetupTestSuite`** with a small + `u`!) to set up the shared resources and a `static void TearDownTestSuite()` + function to tear them down. + +That's it! googletest automatically calls `SetUpTestSuite()` before running the +*first test* in the `FooTest` test suite (i.e. before creating the first +`FooTest` object), and calls `TearDownTestSuite()` after running the *last test* +in it (i.e. after deleting the last `FooTest` object). In between, the tests can +use the shared resources. + +Remember that the test order is undefined, so your code can't depend on a test +preceding or following another. Also, the tests must either not modify the state +of any shared resource, or, if they do modify the state, they must restore the +state to its original value before passing control to the next test. + +Here's an example of per-test-suite set-up and tear-down: + +```c++ +class FooTest : public ::testing::Test { + protected: + // Per-test-suite set-up. + // Called before the first test in this test suite. + // Can be omitted if not needed. + static void SetUpTestSuite() { + shared_resource_ = new ...; + } + + // Per-test-suite tear-down. + // Called after the last test in this test suite. + // Can be omitted if not needed. + static void TearDownTestSuite() { + delete shared_resource_; + shared_resource_ = NULL; + } + + // You can define per-test set-up logic as usual. + virtual void SetUp() { ... } + + // You can define per-test tear-down logic as usual. + virtual void TearDown() { ... } + + // Some expensive resource shared by all tests. + static T* shared_resource_; +}; + +T* FooTest::shared_resource_ = NULL; + +TEST_F(FooTest, Test1) { + ... you can refer to shared_resource_ here ... +} + +TEST_F(FooTest, Test2) { + ... you can refer to shared_resource_ here ... +} +``` + +NOTE: Though the above code declares `SetUpTestSuite()` protected, it may +sometimes be necessary to declare it public, such as when using it with +`TEST_P`. + +## Global Set-Up and Tear-Down + +Just as you can do set-up and tear-down at the test level and the test suite +level, you can also do it at the test program level. Here's how. + +First, you subclass the `::testing::Environment` class to define a test +environment, which knows how to set-up and tear-down: + +```c++ +class Environment : public ::testing::Environment { + public: + virtual ~Environment() {} + + // Override this to define how to set up the environment. + void SetUp() override {} + + // Override this to define how to tear down the environment. + void TearDown() override {} +}; +``` + +Then, you register an instance of your environment class with googletest by +calling the `::testing::AddGlobalTestEnvironment()` function: + +```c++ +Environment* AddGlobalTestEnvironment(Environment* env); +``` + +Now, when `RUN_ALL_TESTS()` is called, it first calls the `SetUp()` method of +each environment object, then runs the tests if none of the environments +reported fatal failures and `GTEST_SKIP()` was not called. `RUN_ALL_TESTS()` +always calls `TearDown()` with each environment object, regardless of whether or +not the tests were run. + +It's OK to register multiple environment objects. In this suite, their `SetUp()` +will be called in the order they are registered, and their `TearDown()` will be +called in the reverse order. + +Note that googletest takes ownership of the registered environment objects. +Therefore **do not delete them** by yourself. + +You should call `AddGlobalTestEnvironment()` before `RUN_ALL_TESTS()` is called, +probably in `main()`. If you use `gtest_main`, you need to call this before +`main()` starts for it to take effect. One way to do this is to define a global +variable like this: + +```c++ +::testing::Environment* const foo_env = + ::testing::AddGlobalTestEnvironment(new FooEnvironment); +``` + +However, we strongly recommend you to write your own `main()` and call +`AddGlobalTestEnvironment()` there, as relying on initialization of global +variables makes the code harder to read and may cause problems when you register +multiple environments from different translation units and the environments have +dependencies among them (remember that the compiler doesn't guarantee the order +in which global variables from different translation units are initialized). + +## Value-Parameterized Tests + +*Value-parameterized tests* allow you to test your code with different +parameters without writing multiple copies of the same test. This is useful in a +number of situations, for example: + +* You have a piece of code whose behavior is affected by one or more + command-line flags. You want to make sure your code performs correctly for + various values of those flags. +* You want to test different implementations of an OO interface. +* You want to test your code over various inputs (a.k.a. data-driven testing). + This feature is easy to abuse, so please exercise your good sense when doing + it! + +### How to Write Value-Parameterized Tests + +To write value-parameterized tests, first you should define a fixture class. It +must be derived from both `testing::Test` and `testing::WithParamInterface` +(the latter is a pure interface), where `T` is the type of your parameter +values. For convenience, you can just derive the fixture class from +`testing::TestWithParam`, which itself is derived from both `testing::Test` +and `testing::WithParamInterface`. `T` can be any copyable type. If it's a +raw pointer, you are responsible for managing the lifespan of the pointed +values. + +NOTE: If your test fixture defines `SetUpTestSuite()` or `TearDownTestSuite()` +they must be declared **public** rather than **protected** in order to use +`TEST_P`. + +```c++ +class FooTest : + public testing::TestWithParam { + // You can implement all the usual fixture class members here. + // To access the test parameter, call GetParam() from class + // TestWithParam. +}; + +// Or, when you want to add parameters to a pre-existing fixture class: +class BaseTest : public testing::Test { + ... +}; +class BarTest : public BaseTest, + public testing::WithParamInterface { + ... +}; +``` + +Then, use the `TEST_P` macro to define as many test patterns using this fixture +as you want. The `_P` suffix is for "parameterized" or "pattern", whichever you +prefer to think. + +```c++ +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} +``` + +Finally, you can use `INSTANTIATE_TEST_SUITE_P` to instantiate the test suite +with any set of parameters you want. googletest defines a number of functions +for generating test parameters. They return what we call (surprise!) *parameter +generators*. Here is a summary of them, which are all in the `testing` +namespace: + + + +| Parameter Generator | Behavior | +| ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `Range(begin, end [, step])` | Yields values `{begin, begin+step, begin+step+step, ...}`. The values do not include `end`. `step` defaults to 1. | +| `Values(v1, v2, ..., vN)` | Yields values `{v1, v2, ..., vN}`. | +| `ValuesIn(container)` and `ValuesIn(begin,end)` | Yields values from a C-style array, an STL-style container, or an iterator range `[begin, end)` | +| `Bool()` | Yields sequence `{false, true}`. | +| `Combine(g1, g2, ..., gN)` | Yields all combinations (Cartesian product) as std\:\:tuples of the values generated by the `N` generators. | + + + +For more details, see the comments at the definitions of these functions. + +The following statement will instantiate tests from the `FooTest` test suite +each with parameter values `"meeny"`, `"miny"`, and `"moe"`. + +```c++ +INSTANTIATE_TEST_SUITE_P(InstantiationName, + FooTest, + testing::Values("meeny", "miny", "moe")); +``` + +NOTE: The code above must be placed at global or namespace scope, not at +function scope. + +NOTE: Don't forget this step! If you do your test will silently pass, but none +of its suites will ever run! + +To distinguish different instances of the pattern (yes, you can instantiate it +more than once), the first argument to `INSTANTIATE_TEST_SUITE_P` is a prefix +that will be added to the actual test suite name. Remember to pick unique +prefixes for different instantiations. The tests from the instantiation above +will have these names: + +* `InstantiationName/FooTest.DoesBlah/0` for `"meeny"` +* `InstantiationName/FooTest.DoesBlah/1` for `"miny"` +* `InstantiationName/FooTest.DoesBlah/2` for `"moe"` +* `InstantiationName/FooTest.HasBlahBlah/0` for `"meeny"` +* `InstantiationName/FooTest.HasBlahBlah/1` for `"miny"` +* `InstantiationName/FooTest.HasBlahBlah/2` for `"moe"` + +You can use these names in [`--gtest_filter`](#running-a-subset-of-the-tests). + +This statement will instantiate all tests from `FooTest` again, each with +parameter values `"cat"` and `"dog"`: + +```c++ +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, + testing::ValuesIn(pets)); +``` + +The tests from the instantiation above will have these names: + +* `AnotherInstantiationName/FooTest.DoesBlah/0` for `"cat"` +* `AnotherInstantiationName/FooTest.DoesBlah/1` for `"dog"` +* `AnotherInstantiationName/FooTest.HasBlahBlah/0` for `"cat"` +* `AnotherInstantiationName/FooTest.HasBlahBlah/1` for `"dog"` + +Please note that `INSTANTIATE_TEST_SUITE_P` will instantiate *all* tests in the +given test suite, whether their definitions come before or *after* the +`INSTANTIATE_TEST_SUITE_P` statement. + +You can see [sample7_unittest.cc] and [sample8_unittest.cc] for more examples. + +[sample7_unittest.cc]: ../samples/sample7_unittest.cc "Parameterized Test example" +[sample8_unittest.cc]: ../samples/sample8_unittest.cc "Parameterized Test example with multiple parameters" + +### Creating Value-Parameterized Abstract Tests + +In the above, we define and instantiate `FooTest` in the *same* source file. +Sometimes you may want to define value-parameterized tests in a library and let +other people instantiate them later. This pattern is known as *abstract tests*. +As an example of its application, when you are designing an interface you can +write a standard suite of abstract tests (perhaps using a factory function as +the test parameter) that all implementations of the interface are expected to +pass. When someone implements the interface, they can instantiate your suite to +get all the interface-conformance tests for free. + +To define abstract tests, you should organize your code like this: + +1. Put the definition of the parameterized test fixture class (e.g. `FooTest`) + in a header file, say `foo_param_test.h`. Think of this as *declaring* your + abstract tests. +2. Put the `TEST_P` definitions in `foo_param_test.cc`, which includes + `foo_param_test.h`. Think of this as *implementing* your abstract tests. + +Once they are defined, you can instantiate them by including `foo_param_test.h`, +invoking `INSTANTIATE_TEST_SUITE_P()`, and depending on the library target that +contains `foo_param_test.cc`. You can instantiate the same abstract test suite +multiple times, possibly in different source files. + +### Specifying Names for Value-Parameterized Test Parameters + +The optional last argument to `INSTANTIATE_TEST_SUITE_P()` allows the user to +specify a function or functor that generates custom test name suffixes based on +the test parameters. The function should accept one argument of type +`testing::TestParamInfo`, and return `std::string`. + +`testing::PrintToStringParamName` is a builtin test suffix generator that +returns the value of `testing::PrintToString(GetParam())`. It does not work for +`std::string` or C strings. + +NOTE: test names must be non-empty, unique, and may only contain ASCII +alphanumeric characters. In particular, they +[should not contain underscores](faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore) + +```c++ +class MyTestSuite : public testing::TestWithParam {}; + +TEST_P(MyTestSuite, MyTest) +{ + std::cout << "Example Test Param: " << GetParam() << std::endl; +} + +INSTANTIATE_TEST_SUITE_P(MyGroup, MyTestSuite, testing::Range(0, 10), + testing::PrintToStringParamName()); +``` + +Providing a custom functor allows for more control over test parameter name +generation, especially for types where the automatic conversion does not +generate helpful parameter names (e.g. strings as demonstrated above). The +following example illustrates this for multiple parameters, an enumeration type +and a string, and also demonstrates how to combine generators. It uses a lambda +for conciseness: + +```c++ +enum class MyType { MY_FOO = 0, MY_BAR = 1 }; + +class MyTestSuite : public testing::TestWithParam> { +}; + +INSTANTIATE_TEST_SUITE_P( + MyGroup, MyTestSuite, + testing::Combine( + testing::Values(MyType::VALUE_0, MyType::VALUE_1), + testing::ValuesIn("", "")), + [](const testing::TestParamInfo& info) { + string name = absl::StrCat( + std::get<0>(info.param) == MY_FOO ? "Foo" : "Bar", "_", + std::get<1>(info.param)); + absl::c_replace_if(name, [](char c) { return !std::isalnum(c); }, '_'); + return name; + }); +``` + +## Typed Tests + +Suppose you have multiple implementations of the same interface and want to make +sure that all of them satisfy some common requirements. Or, you may have defined +several types that are supposed to conform to the same "concept" and you want to +verify it. In both cases, you want the same test logic repeated for different +types. + +While you can write one `TEST` or `TEST_F` for each type you want to test (and +you may even factor the test logic into a function template that you invoke from +the `TEST`), it's tedious and doesn't scale: if you want `m` tests over `n` +types, you'll end up writing `m*n` `TEST`s. + +*Typed tests* allow you to repeat the same test logic over a list of types. You +only need to write the test logic once, although you must know the type list +when writing typed tests. Here's how you do it: + +First, define a fixture class template. It should be parameterized by a type. +Remember to derive it from `::testing::Test`: + +```c++ +template +class FooTest : public ::testing::Test { + public: + ... + typedef std::list List; + static T shared_; + T value_; +}; +``` + +Next, associate a list of types with the test suite, which will be repeated for +each type in the list: + +```c++ +using MyTypes = ::testing::Types; +TYPED_TEST_SUITE(FooTest, MyTypes); +``` + +The type alias (`using` or `typedef`) is necessary for the `TYPED_TEST_SUITE` +macro to parse correctly. Otherwise the compiler will think that each comma in +the type list introduces a new macro argument. + +Then, use `TYPED_TEST()` instead of `TEST_F()` to define a typed test for this +test suite. You can repeat this as many times as you want: + +```c++ +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to the special name TypeParam to get the type + // parameter. Since we are inside a derived class template, C++ requires + // us to visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the 'TestFixture::' + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the 'typename TestFixture::' + // prefix. The 'typename' is required to satisfy the compiler. + typename TestFixture::List values; + + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } +``` + +You can see [sample6_unittest.cc] for a complete example. + +[sample6_unittest.cc]: ../samples/sample6_unittest.cc "Typed Test example" + +## Type-Parameterized Tests + +*Type-parameterized tests* are like typed tests, except that they don't require +you to know the list of types ahead of time. Instead, you can define the test +logic first and instantiate it with different type lists later. You can even +instantiate it more than once in the same program. + +If you are designing an interface or concept, you can define a suite of +type-parameterized tests to verify properties that any valid implementation of +the interface/concept should have. Then, the author of each implementation can +just instantiate the test suite with their type to verify that it conforms to +the requirements, without having to write similar tests repeatedly. Here's an +example: + +First, define a fixture class template, as we did with typed tests: + +```c++ +template +class FooTest : public ::testing::Test { + ... +}; +``` + +Next, declare that you will define a type-parameterized test suite: + +```c++ +TYPED_TEST_SUITE_P(FooTest); +``` + +Then, use `TYPED_TEST_P()` to define a type-parameterized test. You can repeat +this as many times as you want: + +```c++ +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } +``` + +Now the tricky part: you need to register all test patterns using the +`REGISTER_TYPED_TEST_SUITE_P` macro before you can instantiate them. The first +argument of the macro is the test suite name; the rest are the names of the +tests in this test suite: + +```c++ +REGISTER_TYPED_TEST_SUITE_P(FooTest, + DoesBlah, HasPropertyA); +``` + +Finally, you are free to instantiate the pattern with the types you want. If you +put the above code in a header file, you can `#include` it in multiple C++ +source files and instantiate it multiple times. + +```c++ +typedef ::testing::Types MyTypes; +INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); +``` + +To distinguish different instances of the pattern, the first argument to the +`INSTANTIATE_TYPED_TEST_SUITE_P` macro is a prefix that will be added to the +actual test suite name. Remember to pick unique prefixes for different +instances. + +In the special case where the type list contains only one type, you can write +that type directly without `::testing::Types<...>`, like this: + +```c++ +INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int); +``` + +You can see [sample6_unittest.cc] for a complete example. + +## Testing Private Code + +If you change your software's internal implementation, your tests should not +break as long as the change is not observable by users. Therefore, **per the +black-box testing principle, most of the time you should test your code through +its public interfaces.** + +**If you still find yourself needing to test internal implementation code, +consider if there's a better design.** The desire to test internal +implementation is often a sign that the class is doing too much. Consider +extracting an implementation class, and testing it. Then use that implementation +class in the original class. + +If you absolutely have to test non-public interface code though, you can. There +are two cases to consider: + +* Static functions ( *not* the same as static member functions!) or unnamed + namespaces, and +* Private or protected class members + +To test them, we use the following special techniques: + +* Both static functions and definitions/declarations in an unnamed namespace + are only visible within the same translation unit. To test them, you can + `#include` the entire `.cc` file being tested in your `*_test.cc` file. + (#including `.cc` files is not a good way to reuse code - you should not do + this in production code!) + + However, a better approach is to move the private code into the + `foo::internal` namespace, where `foo` is the namespace your project + normally uses, and put the private declarations in a `*-internal.h` file. + Your production `.cc` files and your tests are allowed to include this + internal header, but your clients are not. This way, you can fully test your + internal implementation without leaking it to your clients. + +* Private class members are only accessible from within the class or by + friends. To access a class' private members, you can declare your test + fixture as a friend to the class and define accessors in your fixture. Tests + using the fixture can then access the private members of your production + class via the accessors in the fixture. Note that even though your fixture + is a friend to your production class, your tests are not automatically + friends to it, as they are technically defined in sub-classes of the + fixture. + + Another way to test private members is to refactor them into an + implementation class, which is then declared in a `*-internal.h` file. Your + clients aren't allowed to include this header but your tests can. Such is + called the + [Pimpl](https://www.gamedev.net/articles/programming/general-and-gameplay-programming/the-c-pimpl-r1794/) + (Private Implementation) idiom. + + Or, you can declare an individual test as a friend of your class by adding + this line in the class body: + + ```c++ + FRIEND_TEST(TestSuiteName, TestName); + ``` + + For example, + + ```c++ + // foo.h + class Foo { + ... + private: + FRIEND_TEST(FooTest, BarReturnsZeroOnNull); + + int Bar(void* x); + }; + + // foo_test.cc + ... + TEST(FooTest, BarReturnsZeroOnNull) { + Foo foo; + EXPECT_EQ(foo.Bar(NULL), 0); // Uses Foo's private member Bar(). + } + ``` + + Pay special attention when your class is defined in a namespace, as you + should define your test fixtures and tests in the same namespace if you want + them to be friends of your class. For example, if the code to be tested + looks like: + + ```c++ + namespace my_namespace { + + class Foo { + friend class FooTest; + FRIEND_TEST(FooTest, Bar); + FRIEND_TEST(FooTest, Baz); + ... definition of the class Foo ... + }; + + } // namespace my_namespace + ``` + + Your test code should be something like: + + ```c++ + namespace my_namespace { + + class FooTest : public ::testing::Test { + protected: + ... + }; + + TEST_F(FooTest, Bar) { ... } + TEST_F(FooTest, Baz) { ... } + + } // namespace my_namespace + ``` + +## "Catching" Failures + +If you are building a testing utility on top of googletest, you'll want to test +your utility. What framework would you use to test it? googletest, of course. + +The challenge is to verify that your testing utility reports failures correctly. +In frameworks that report a failure by throwing an exception, you could catch +the exception and assert on it. But googletest doesn't use exceptions, so how do +we test that a piece of code generates an expected failure? + +gunit-spi.h contains some constructs to do this. After #including this header, +you can use + +```c++ + EXPECT_FATAL_FAILURE(statement, substring); +``` + +to assert that `statement` generates a fatal (e.g. `ASSERT_*`) failure in the +current thread whose message contains the given `substring`, or use + +```c++ + EXPECT_NONFATAL_FAILURE(statement, substring); +``` + +if you are expecting a non-fatal (e.g. `EXPECT_*`) failure. + +Only failures in the current thread are checked to determine the result of this +type of expectations. If `statement` creates new threads, failures in these +threads are also ignored. If you want to catch failures in other threads as +well, use one of the following macros instead: + +```c++ + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substring); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substring); +``` + +NOTE: Assertions from multiple threads are currently not supported on Windows. + +For technical reasons, there are some caveats: + +1. You cannot stream a failure message to either macro. + +2. `statement` in `EXPECT_FATAL_FAILURE{_ON_ALL_THREADS}()` cannot reference + local non-static variables or non-static members of `this` object. + +3. `statement` in `EXPECT_FATAL_FAILURE{_ON_ALL_THREADS}()` cannot return a + value. + +## Registering tests programmatically + +The `TEST` macros handle the vast majority of all use cases, but there are few +were runtime registration logic is required. For those cases, the framework +provides the `::testing::RegisterTest` that allows callers to register arbitrary +tests dynamically. + +This is an advanced API only to be used when the `TEST` macros are insufficient. +The macros should be preferred when possible, as they avoid most of the +complexity of calling this function. + +It provides the following signature: + +```c++ +template +TestInfo* RegisterTest(const char* test_suite_name, const char* test_name, + const char* type_param, const char* value_param, + const char* file, int line, Factory factory); +``` + +The `factory` argument is a factory callable (move-constructible) object or +function pointer that creates a new instance of the Test object. It handles +ownership to the caller. The signature of the callable is `Fixture*()`, where +`Fixture` is the test fixture class for the test. All tests registered with the +same `test_suite_name` must return the same fixture type. This is checked at +runtime. + +The framework will infer the fixture class from the factory and will call the +`SetUpTestSuite` and `TearDownTestSuite` for it. + +Must be called before `RUN_ALL_TESTS()` is invoked, otherwise behavior is +undefined. + +Use case example: + +```c++ +class MyFixture : public ::testing::Test { + public: + // All of these optional, just like in regular macro usage. + static void SetUpTestSuite() { ... } + static void TearDownTestSuite() { ... } + void SetUp() override { ... } + void TearDown() override { ... } +}; + +class MyTest : public MyFixture { + public: + explicit MyTest(int data) : data_(data) {} + void TestBody() override { ... } + + private: + int data_; +}; + +void RegisterMyTests(const std::vector& values) { + for (int v : values) { + ::testing::RegisterTest( + "MyFixture", ("Test" + std::to_string(v)).c_str(), nullptr, + std::to_string(v).c_str(), + __FILE__, __LINE__, + // Important to use the fixture type as the return type here. + [=]() -> MyFixture* { return new MyTest(v); }); + } +} +... +int main(int argc, char** argv) { + std::vector values_to_test = LoadValuesFromConfig(); + RegisterMyTests(values_to_test); + ... + return RUN_ALL_TESTS(); +} +``` +## Getting the Current Test's Name + +Sometimes a function may need to know the name of the currently running test. +For example, you may be using the `SetUp()` method of your test fixture to set +the golden file name based on which test is running. The `::testing::TestInfo` +class has this information: + +```c++ +namespace testing { + +class TestInfo { + public: + // Returns the test suite name and the test name, respectively. + // + // Do NOT delete or free the return value - it's managed by the + // TestInfo class. + const char* test_suite_name() const; + const char* name() const; +}; + +} +``` + +To obtain a `TestInfo` object for the currently running test, call +`current_test_info()` on the `UnitTest` singleton object: + +```c++ + // Gets information about the currently running test. + // Do NOT delete the returned object - it's managed by the UnitTest class. + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + + + printf("We are in test %s of test suite %s.\n", + test_info->name(), + test_info->test_suite_name()); +``` + +`current_test_info()` returns a null pointer if no test is running. In +particular, you cannot find the test suite name in `TestSuiteSetUp()`, +`TestSuiteTearDown()` (where you know the test suite name implicitly), or +functions called from them. + +## Extending googletest by Handling Test Events + +googletest provides an **event listener API** to let you receive notifications +about the progress of a test program and test failures. The events you can +listen to include the start and end of the test program, a test suite, or a test +method, among others. You may use this API to augment or replace the standard +console output, replace the XML output, or provide a completely different form +of output, such as a GUI or a database. You can also use test events as +checkpoints to implement a resource leak checker, for example. + +### Defining Event Listeners + +To define a event listener, you subclass either testing::TestEventListener or +testing::EmptyTestEventListener The former is an (abstract) interface, where +*each pure virtual method can be overridden to handle a test event* (For +example, when a test starts, the `OnTestStart()` method will be called.). The +latter provides an empty implementation of all methods in the interface, such +that a subclass only needs to override the methods it cares about. + +When an event is fired, its context is passed to the handler function as an +argument. The following argument types are used: + +* UnitTest reflects the state of the entire test program, +* TestSuite has information about a test suite, which can contain one or more + tests, +* TestInfo contains the state of a test, and +* TestPartResult represents the result of a test assertion. + +An event handler function can examine the argument it receives to find out +interesting information about the event and the test program's state. + +Here's an example: + +```c++ + class MinimalistPrinter : public ::testing::EmptyTestEventListener { + // Called before a test starts. + virtual void OnTestStart(const ::testing::TestInfo& test_info) { + printf("*** Test %s.%s starting.\n", + test_info.test_suite_name(), test_info.name()); + } + + // Called after a failed assertion or a SUCCESS(). + virtual void OnTestPartResult(const ::testing::TestPartResult& test_part_result) { + printf("%s in %s:%d\n%s\n", + test_part_result.failed() ? "*** Failure" : "Success", + test_part_result.file_name(), + test_part_result.line_number(), + test_part_result.summary()); + } + + // Called after a test ends. + virtual void OnTestEnd(const ::testing::TestInfo& test_info) { + printf("*** Test %s.%s ending.\n", + test_info.test_suite_name(), test_info.name()); + } + }; +``` + +### Using Event Listeners + +To use the event listener you have defined, add an instance of it to the +googletest event listener list (represented by class TestEventListeners - note +the "s" at the end of the name) in your `main()` function, before calling +`RUN_ALL_TESTS()`: + +```c++ +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + // Gets hold of the event listener list. + ::testing::TestEventListeners& listeners = + ::testing::UnitTest::GetInstance()->listeners(); + // Adds a listener to the end. googletest takes the ownership. + listeners.Append(new MinimalistPrinter); + return RUN_ALL_TESTS(); +} +``` + +There's only one problem: the default test result printer is still in effect, so +its output will mingle with the output from your minimalist printer. To suppress +the default printer, just release it from the event listener list and delete it. +You can do so by adding one line: + +```c++ + ... + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new MinimalistPrinter); + return RUN_ALL_TESTS(); +``` + +Now, sit back and enjoy a completely different output from your tests. For more +details, see [sample9_unittest.cc]. + +[sample9_unittest.cc]: ../samples/sample9_unittest.cc "Event listener example" + +You may append more than one listener to the list. When an `On*Start()` or +`OnTestPartResult()` event is fired, the listeners will receive it in the order +they appear in the list (since new listeners are added to the end of the list, +the default text printer and the default XML generator will receive the event +first). An `On*End()` event will be received by the listeners in the *reverse* +order. This allows output by listeners added later to be framed by output from +listeners added earlier. + +### Generating Failures in Listeners + +You may use failure-raising macros (`EXPECT_*()`, `ASSERT_*()`, `FAIL()`, etc) +when processing an event. There are some restrictions: + +1. You cannot generate any failure in `OnTestPartResult()` (otherwise it will + cause `OnTestPartResult()` to be called recursively). +2. A listener that handles `OnTestPartResult()` is not allowed to generate any + failure. + +When you add listeners to the listener list, you should put listeners that +handle `OnTestPartResult()` *before* listeners that can generate failures. This +ensures that failures generated by the latter are attributed to the right test +by the former. + +See [sample10_unittest.cc] for an example of a failure-raising listener. + +[sample10_unittest.cc]: ../samples/sample10_unittest.cc "Failure-raising listener example" + +## Running Test Programs: Advanced Options + +googletest test programs are ordinary executables. Once built, you can run them +directly and affect their behavior via the following environment variables +and/or command line flags. For the flags to work, your programs must call +`::testing::InitGoogleTest()` before calling `RUN_ALL_TESTS()`. + +To see a list of supported flags and their usage, please run your test program +with the `--help` flag. You can also use `-h`, `-?`, or `/?` for short. + +If an option is specified both by an environment variable and by a flag, the +latter takes precedence. + +### Selecting Tests + +#### Listing Test Names + +Sometimes it is necessary to list the available tests in a program before +running them so that a filter may be applied if needed. Including the flag +`--gtest_list_tests` overrides all other flags and lists tests in the following +format: + +```none +TestSuite1. + TestName1 + TestName2 +TestSuite2. + TestName +``` + +None of the tests listed are actually run if the flag is provided. There is no +corresponding environment variable for this flag. + +#### Running a Subset of the Tests + +By default, a googletest program runs all tests the user has defined. Sometimes, +you want to run only a subset of the tests (e.g. for debugging or quickly +verifying a change). If you set the `GTEST_FILTER` environment variable or the +`--gtest_filter` flag to a filter string, googletest will only run the tests +whose full names (in the form of `TestSuiteName.TestName`) match the filter. + +The format of a filter is a '`:`'-separated list of wildcard patterns (called +the *positive patterns*) optionally followed by a '`-`' and another +'`:`'-separated pattern list (called the *negative patterns*). A test matches +the filter if and only if it matches any of the positive patterns but does not +match any of the negative patterns. + +A pattern may contain `'*'` (matches any string) or `'?'` (matches any single +character). For convenience, the filter `'*-NegativePatterns'` can be also +written as `'-NegativePatterns'`. + +For example: + +* `./foo_test` Has no flag, and thus runs all its tests. +* `./foo_test --gtest_filter=*` Also runs everything, due to the single + match-everything `*` value. +* `./foo_test --gtest_filter=FooTest.*` Runs everything in test suite + `FooTest` . +* `./foo_test --gtest_filter=*Null*:*Constructor*` Runs any test whose full + name contains either `"Null"` or `"Constructor"` . +* `./foo_test --gtest_filter=-*DeathTest.*` Runs all non-death tests. +* `./foo_test --gtest_filter=FooTest.*-FooTest.Bar` Runs everything in test + suite `FooTest` except `FooTest.Bar`. +* `./foo_test --gtest_filter=FooTest.*:BarTest.*-FooTest.Bar:BarTest.Foo` Runs + everything in test suite `FooTest` except `FooTest.Bar` and everything in + test suite `BarTest` except `BarTest.Foo`. + +#### Temporarily Disabling Tests + +If you have a broken test that you cannot fix right away, you can add the +`DISABLED_` prefix to its name. This will exclude it from execution. This is +better than commenting out the code or using `#if 0`, as disabled tests are +still compiled (and thus won't rot). + +If you need to disable all tests in a test suite, you can either add `DISABLED_` +to the front of the name of each test, or alternatively add it to the front of +the test suite name. + +For example, the following tests won't be run by googletest, even though they +will still be compiled: + +```c++ +// Tests that Foo does Abc. +TEST(FooTest, DISABLED_DoesAbc) { ... } + +class DISABLED_BarTest : public ::testing::Test { ... }; + +// Tests that Bar does Xyz. +TEST_F(DISABLED_BarTest, DoesXyz) { ... } +``` + +NOTE: This feature should only be used for temporary pain-relief. You still have +to fix the disabled tests at a later date. As a reminder, googletest will print +a banner warning you if a test program contains any disabled tests. + +TIP: You can easily count the number of disabled tests you have using `gsearch` +and/or `grep`. This number can be used as a metric for improving your test +quality. + +#### Temporarily Enabling Disabled Tests + +To include disabled tests in test execution, just invoke the test program with +the `--gtest_also_run_disabled_tests` flag or set the +`GTEST_ALSO_RUN_DISABLED_TESTS` environment variable to a value other than `0`. +You can combine this with the `--gtest_filter` flag to further select which +disabled tests to run. + +### Repeating the Tests + +Once in a while you'll run into a test whose result is hit-or-miss. Perhaps it +will fail only 1% of the time, making it rather hard to reproduce the bug under +a debugger. This can be a major source of frustration. + +The `--gtest_repeat` flag allows you to repeat all (or selected) test methods in +a program many times. Hopefully, a flaky test will eventually fail and give you +a chance to debug. Here's how to use it: + +```none +$ foo_test --gtest_repeat=1000 +Repeat foo_test 1000 times and don't stop at failures. + +$ foo_test --gtest_repeat=-1 +A negative count means repeating forever. + +$ foo_test --gtest_repeat=1000 --gtest_break_on_failure +Repeat foo_test 1000 times, stopping at the first failure. This +is especially useful when running under a debugger: when the test +fails, it will drop into the debugger and you can then inspect +variables and stacks. + +$ foo_test --gtest_repeat=1000 --gtest_filter=FooBar.* +Repeat the tests whose name matches the filter 1000 times. +``` + +If your test program contains +[global set-up/tear-down](#global-set-up-and-tear-down) code, it will be +repeated in each iteration as well, as the flakiness may be in it. You can also +specify the repeat count by setting the `GTEST_REPEAT` environment variable. + +### Shuffling the Tests + +You can specify the `--gtest_shuffle` flag (or set the `GTEST_SHUFFLE` +environment variable to `1`) to run the tests in a program in a random order. +This helps to reveal bad dependencies between tests. + +By default, googletest uses a random seed calculated from the current time. +Therefore you'll get a different order every time. The console output includes +the random seed value, such that you can reproduce an order-related test failure +later. To specify the random seed explicitly, use the `--gtest_random_seed=SEED` +flag (or set the `GTEST_RANDOM_SEED` environment variable), where `SEED` is an +integer in the range [0, 99999]. The seed value 0 is special: it tells +googletest to do the default behavior of calculating the seed from the current +time. + +If you combine this with `--gtest_repeat=N`, googletest will pick a different +random seed and re-shuffle the tests in each iteration. + +### Controlling Test Output + +#### Colored Terminal Output + +googletest can use colors in its terminal output to make it easier to spot the +important information: + + +...
+ [----------] 1 test from + FooTest
+ [ RUN      ] + FooTest.DoesAbc
+ [       OK ] + FooTest.DoesAbc
+ [----------] + 2 tests from BarTest
+ [ RUN      ] + BarTest.HasXyzProperty
+ [       OK ] + BarTest.HasXyzProperty
+ [ RUN      ] + BarTest.ReturnsTrueOnSuccess ... some error messages ...
+ [   FAILED ] + BarTest.ReturnsTrueOnSuccess ...
+ [==========] + 30 tests from 14 test suites ran.
+ [   PASSED ] + 28 tests.
+ [   FAILED ] + 2 tests, listed below:
+ [   FAILED ] + BarTest.ReturnsTrueOnSuccess
+ [   FAILED ] + AnotherTest.DoesXyz
+
+ 2 FAILED TESTS +
+
+ +You can set the `GTEST_COLOR` environment variable or the `--gtest_color` +command line flag to `yes`, `no`, or `auto` (the default) to enable colors, +disable colors, or let googletest decide. When the value is `auto`, googletest +will use colors if and only if the output goes to a terminal and (on non-Windows +platforms) the `TERM` environment variable is set to `xterm` or `xterm-color`. + +#### Suppressing the Elapsed Time + +By default, googletest prints the time it takes to run each test. To disable +that, run the test program with the `--gtest_print_time=0` command line flag, or +set the GTEST_PRINT_TIME environment variable to `0`. + +#### Suppressing UTF-8 Text Output + +In case of assertion failures, googletest prints expected and actual values of +type `string` both as hex-encoded strings as well as in readable UTF-8 text if +they contain valid non-ASCII UTF-8 characters. If you want to suppress the UTF-8 +text because, for example, you don't have an UTF-8 compatible output medium, run +the test program with `--gtest_print_utf8=0` or set the `GTEST_PRINT_UTF8` +environment variable to `0`. + + + +#### Generating an XML Report + +googletest can emit a detailed XML report to a file in addition to its normal +textual output. The report contains the duration of each test, and thus can help +you identify slow tests. The report is also used by the http://unittest +dashboard to show per-test-method error messages. + +To generate the XML report, set the `GTEST_OUTPUT` environment variable or the +`--gtest_output` flag to the string `"xml:path_to_output_file"`, which will +create the file at the given location. You can also just use the string `"xml"`, +in which case the output can be found in the `test_detail.xml` file in the +current directory. + +If you specify a directory (for example, `"xml:output/directory/"` on Linux or +`"xml:output\directory\"` on Windows), googletest will create the XML file in +that directory, named after the test executable (e.g. `foo_test.xml` for test +program `foo_test` or `foo_test.exe`). If the file already exists (perhaps left +over from a previous run), googletest will pick a different name (e.g. +`foo_test_1.xml`) to avoid overwriting it. + +The report is based on the `junitreport` Ant task. Since that format was +originally intended for Java, a little interpretation is required to make it +apply to googletest tests, as shown here: + +```xml + + + + + + + + + +``` + +* The root `` element corresponds to the entire test program. +* `` elements correspond to googletest test suites. +* `` elements correspond to googletest test functions. + +For instance, the following program + +```c++ +TEST(MathTest, Addition) { ... } +TEST(MathTest, Subtraction) { ... } +TEST(LogicTest, NonContradiction) { ... } +``` + +could generate this report: + +```xml + + + + + ... + ... + + + + + + + + + +``` + +Things to note: + +* The `tests` attribute of a `` or `` element tells how + many test functions the googletest program or test suite contains, while the + `failures` attribute tells how many of them failed. + +* The `time` attribute expresses the duration of the test, test suite, or + entire test program in seconds. + +* The `timestamp` attribute records the local date and time of the test + execution. + +* Each `` element corresponds to a single failed googletest + assertion. + +#### Generating a JSON Report + +googletest can also emit a JSON report as an alternative format to XML. To +generate the JSON report, set the `GTEST_OUTPUT` environment variable or the +`--gtest_output` flag to the string `"json:path_to_output_file"`, which will +create the file at the given location. You can also just use the string +`"json"`, in which case the output can be found in the `test_detail.json` file +in the current directory. + +The report format conforms to the following JSON Schema: + +```json +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "definitions": { + "TestCase": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "tests": { "type": "integer" }, + "failures": { "type": "integer" }, + "disabled": { "type": "integer" }, + "time": { "type": "string" }, + "testsuite": { + "type": "array", + "items": { + "$ref": "#/definitions/TestInfo" + } + } + } + }, + "TestInfo": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "status": { + "type": "string", + "enum": ["RUN", "NOTRUN"] + }, + "time": { "type": "string" }, + "classname": { "type": "string" }, + "failures": { + "type": "array", + "items": { + "$ref": "#/definitions/Failure" + } + } + } + }, + "Failure": { + "type": "object", + "properties": { + "failures": { "type": "string" }, + "type": { "type": "string" } + } + } + }, + "properties": { + "tests": { "type": "integer" }, + "failures": { "type": "integer" }, + "disabled": { "type": "integer" }, + "errors": { "type": "integer" }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "time": { "type": "string" }, + "name": { "type": "string" }, + "testsuites": { + "type": "array", + "items": { + "$ref": "#/definitions/TestCase" + } + } + } +} +``` + +The report uses the format that conforms to the following Proto3 using the +[JSON encoding](https://developers.google.com/protocol-buffers/docs/proto3#json): + +```proto +syntax = "proto3"; + +package googletest; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/duration.proto"; + +message UnitTest { + int32 tests = 1; + int32 failures = 2; + int32 disabled = 3; + int32 errors = 4; + google.protobuf.Timestamp timestamp = 5; + google.protobuf.Duration time = 6; + string name = 7; + repeated TestCase testsuites = 8; +} + +message TestCase { + string name = 1; + int32 tests = 2; + int32 failures = 3; + int32 disabled = 4; + int32 errors = 5; + google.protobuf.Duration time = 6; + repeated TestInfo testsuite = 7; +} + +message TestInfo { + string name = 1; + enum Status { + RUN = 0; + NOTRUN = 1; + } + Status status = 2; + google.protobuf.Duration time = 3; + string classname = 4; + message Failure { + string failures = 1; + string type = 2; + } + repeated Failure failures = 5; +} +``` + +For instance, the following program + +```c++ +TEST(MathTest, Addition) { ... } +TEST(MathTest, Subtraction) { ... } +TEST(LogicTest, NonContradiction) { ... } +``` + +could generate this report: + +```json +{ + "tests": 3, + "failures": 1, + "errors": 0, + "time": "0.035s", + "timestamp": "2011-10-31T18:52:42Z", + "name": "AllTests", + "testsuites": [ + { + "name": "MathTest", + "tests": 2, + "failures": 1, + "errors": 0, + "time": "0.015s", + "testsuite": [ + { + "name": "Addition", + "status": "RUN", + "time": "0.007s", + "classname": "", + "failures": [ + { + "message": "Value of: add(1, 1)\n Actual: 3\nExpected: 2", + "type": "" + }, + { + "message": "Value of: add(1, -1)\n Actual: 1\nExpected: 0", + "type": "" + } + ] + }, + { + "name": "Subtraction", + "status": "RUN", + "time": "0.005s", + "classname": "" + } + ] + }, + { + "name": "LogicTest", + "tests": 1, + "failures": 0, + "errors": 0, + "time": "0.005s", + "testsuite": [ + { + "name": "NonContradiction", + "status": "RUN", + "time": "0.005s", + "classname": "" + } + ] + } + ] +} +``` + +IMPORTANT: The exact format of the JSON document is subject to change. + +### Controlling How Failures Are Reported + +#### Turning Assertion Failures into Break-Points + +When running test programs under a debugger, it's very convenient if the +debugger can catch an assertion failure and automatically drop into interactive +mode. googletest's *break-on-failure* mode supports this behavior. + +To enable it, set the `GTEST_BREAK_ON_FAILURE` environment variable to a value +other than `0`. Alternatively, you can use the `--gtest_break_on_failure` +command line flag. + +#### Disabling Catching Test-Thrown Exceptions + +googletest can be used either with or without exceptions enabled. If a test +throws a C++ exception or (on Windows) a structured exception (SEH), by default +googletest catches it, reports it as a test failure, and continues with the next +test method. This maximizes the coverage of a test run. Also, on Windows an +uncaught exception will cause a pop-up window, so catching the exceptions allows +you to run the tests automatically. + +When debugging the test failures, however, you may instead want the exceptions +to be handled by the debugger, such that you can examine the call stack when an +exception is thrown. To achieve that, set the `GTEST_CATCH_EXCEPTIONS` +environment variable to `0`, or use the `--gtest_catch_exceptions=0` flag when +running the tests. diff --git a/3rdparty/gtest/docs/faq.md b/3rdparty/gtest/docs/faq.md new file mode 100644 index 0000000..960a827 --- /dev/null +++ b/3rdparty/gtest/docs/faq.md @@ -0,0 +1,753 @@ +# Googletest FAQ + + + +## Why should test suite names and test names not contain underscore? + +Underscore (`_`) is special, as C++ reserves the following to be used by the +compiler and the standard library: + +1. any identifier that starts with an `_` followed by an upper-case letter, and +2. any identifier that contains two consecutive underscores (i.e. `__`) + *anywhere* in its name. + +User code is *prohibited* from using such identifiers. + +Now let's look at what this means for `TEST` and `TEST_F`. + +Currently `TEST(TestSuiteName, TestName)` generates a class named +`TestSuiteName_TestName_Test`. What happens if `TestSuiteName` or `TestName` +contains `_`? + +1. If `TestSuiteName` starts with an `_` followed by an upper-case letter (say, + `_Foo`), we end up with `_Foo_TestName_Test`, which is reserved and thus + invalid. +2. If `TestSuiteName` ends with an `_` (say, `Foo_`), we get + `Foo__TestName_Test`, which is invalid. +3. If `TestName` starts with an `_` (say, `_Bar`), we get + `TestSuiteName__Bar_Test`, which is invalid. +4. If `TestName` ends with an `_` (say, `Bar_`), we get + `TestSuiteName_Bar__Test`, which is invalid. + +So clearly `TestSuiteName` and `TestName` cannot start or end with `_` +(Actually, `TestSuiteName` can start with `_` -- as long as the `_` isn't +followed by an upper-case letter. But that's getting complicated. So for +simplicity we just say that it cannot start with `_`.). + +It may seem fine for `TestSuiteName` and `TestName` to contain `_` in the +middle. However, consider this: + +```c++ +TEST(Time, Flies_Like_An_Arrow) { ... } +TEST(Time_Flies, Like_An_Arrow) { ... } +``` + +Now, the two `TEST`s will both generate the same class +(`Time_Flies_Like_An_Arrow_Test`). That's not good. + +So for simplicity, we just ask the users to avoid `_` in `TestSuiteName` and +`TestName`. The rule is more constraining than necessary, but it's simple and +easy to remember. It also gives googletest some wiggle room in case its +implementation needs to change in the future. + +If you violate the rule, there may not be immediate consequences, but your test +may (just may) break with a new compiler (or a new version of the compiler you +are using) or with a new version of googletest. Therefore it's best to follow +the rule. + +## Why does googletest support `EXPECT_EQ(NULL, ptr)` and `ASSERT_EQ(NULL, ptr)` but not `EXPECT_NE(NULL, ptr)` and `ASSERT_NE(NULL, ptr)`? + +First of all you can use `EXPECT_NE(nullptr, ptr)` and `ASSERT_NE(nullptr, +ptr)`. This is the preferred syntax in the style guide because nullptr does not +have the type problems that NULL does. Which is why NULL does not work. + +Due to some peculiarity of C++, it requires some non-trivial template meta +programming tricks to support using `NULL` as an argument of the `EXPECT_XX()` +and `ASSERT_XX()` macros. Therefore we only do it where it's most needed +(otherwise we make the implementation of googletest harder to maintain and more +error-prone than necessary). + +The `EXPECT_EQ()` macro takes the *expected* value as its first argument and the +*actual* value as the second. It's reasonable that someone wants to write +`EXPECT_EQ(NULL, some_expression)`, and this indeed was requested several times. +Therefore we implemented it. + +The need for `EXPECT_NE(NULL, ptr)` isn't nearly as strong. When the assertion +fails, you already know that `ptr` must be `NULL`, so it doesn't add any +information to print `ptr` in this case. That means `EXPECT_TRUE(ptr != NULL)` +works just as well. + +If we were to support `EXPECT_NE(NULL, ptr)`, for consistency we'll have to +support `EXPECT_NE(ptr, NULL)` as well, as unlike `EXPECT_EQ`, we don't have a +convention on the order of the two arguments for `EXPECT_NE`. This means using +the template meta programming tricks twice in the implementation, making it even +harder to understand and maintain. We believe the benefit doesn't justify the +cost. + +Finally, with the growth of the gMock matcher library, we are encouraging people +to use the unified `EXPECT_THAT(value, matcher)` syntax more often in tests. One +significant advantage of the matcher approach is that matchers can be easily +combined to form new matchers, while the `EXPECT_NE`, etc, macros cannot be +easily combined. Therefore we want to invest more in the matchers than in the +`EXPECT_XX()` macros. + +## I need to test that different implementations of an interface satisfy some common requirements. Should I use typed tests or value-parameterized tests? + +For testing various implementations of the same interface, either typed tests or +value-parameterized tests can get it done. It's really up to you the user to +decide which is more convenient for you, depending on your particular case. Some +rough guidelines: + +* Typed tests can be easier to write if instances of the different + implementations can be created the same way, modulo the type. For example, + if all these implementations have a public default constructor (such that + you can write `new TypeParam`), or if their factory functions have the same + form (e.g. `CreateInstance()`). +* Value-parameterized tests can be easier to write if you need different code + patterns to create different implementations' instances, e.g. `new Foo` vs + `new Bar(5)`. To accommodate for the differences, you can write factory + function wrappers and pass these function pointers to the tests as their + parameters. +* When a typed test fails, the default output includes the name of the type, + which can help you quickly identify which implementation is wrong. + Value-parameterized tests only show the number of the failed iteration by + default. You will need to define a function that returns the iteration name + and pass it as the third parameter to INSTANTIATE_TEST_SUITE_P to have more + useful output. +* When using typed tests, you need to make sure you are testing against the + interface type, not the concrete types (in other words, you want to make + sure `implicit_cast(my_concrete_impl)` works, not just that + `my_concrete_impl` works). It's less likely to make mistakes in this area + when using value-parameterized tests. + +I hope I didn't confuse you more. :-) If you don't mind, I'd suggest you to give +both approaches a try. Practice is a much better way to grasp the subtle +differences between the two tools. Once you have some concrete experience, you +can much more easily decide which one to use the next time. + +## I got some run-time errors about invalid proto descriptors when using `ProtocolMessageEquals`. Help! + +**Note:** `ProtocolMessageEquals` and `ProtocolMessageEquiv` are *deprecated* +now. Please use `EqualsProto`, etc instead. + +`ProtocolMessageEquals` and `ProtocolMessageEquiv` were redefined recently and +are now less tolerant of invalid protocol buffer definitions. In particular, if +you have a `foo.proto` that doesn't fully qualify the type of a protocol message +it references (e.g. `message` where it should be `message`), you +will now get run-time errors like: + +``` +... descriptor.cc:...] Invalid proto descriptor for file "path/to/foo.proto": +... descriptor.cc:...] blah.MyMessage.my_field: ".Bar" is not defined. +``` + +If you see this, your `.proto` file is broken and needs to be fixed by making +the types fully qualified. The new definition of `ProtocolMessageEquals` and +`ProtocolMessageEquiv` just happen to reveal your bug. + +## My death test modifies some state, but the change seems lost after the death test finishes. Why? + +Death tests (`EXPECT_DEATH`, etc) are executed in a sub-process s.t. the +expected crash won't kill the test program (i.e. the parent process). As a +result, any in-memory side effects they incur are observable in their respective +sub-processes, but not in the parent process. You can think of them as running +in a parallel universe, more or less. + +In particular, if you use mocking and the death test statement invokes some mock +methods, the parent process will think the calls have never occurred. Therefore, +you may want to move your `EXPECT_CALL` statements inside the `EXPECT_DEATH` +macro. + +## EXPECT_EQ(htonl(blah), blah_blah) generates weird compiler errors in opt mode. Is this a googletest bug? + +Actually, the bug is in `htonl()`. + +According to `'man htonl'`, `htonl()` is a *function*, which means it's valid to +use `htonl` as a function pointer. However, in opt mode `htonl()` is defined as +a *macro*, which breaks this usage. + +Worse, the macro definition of `htonl()` uses a `gcc` extension and is *not* +standard C++. That hacky implementation has some ad hoc limitations. In +particular, it prevents you from writing `Foo()`, where `Foo` +is a template that has an integral argument. + +The implementation of `EXPECT_EQ(a, b)` uses `sizeof(... a ...)` inside a +template argument, and thus doesn't compile in opt mode when `a` contains a call +to `htonl()`. It is difficult to make `EXPECT_EQ` bypass the `htonl()` bug, as +the solution must work with different compilers on various platforms. + +`htonl()` has some other problems as described in `//util/endian/endian.h`, +which defines `ghtonl()` to replace it. `ghtonl()` does the same thing `htonl()` +does, only without its problems. We suggest you to use `ghtonl()` instead of +`htonl()`, both in your tests and production code. + +`//util/endian/endian.h` also defines `ghtons()`, which solves similar problems +in `htons()`. + +Don't forget to add `//util/endian` to the list of dependencies in the `BUILD` +file wherever `ghtonl()` and `ghtons()` are used. The library consists of a +single header file and will not bloat your binary. + +## The compiler complains about "undefined references" to some static const member variables, but I did define them in the class body. What's wrong? + +If your class has a static data member: + +```c++ +// foo.h +class Foo { + ... + static const int kBar = 100; +}; +``` + +You also need to define it *outside* of the class body in `foo.cc`: + +```c++ +const int Foo::kBar; // No initializer here. +``` + +Otherwise your code is **invalid C++**, and may break in unexpected ways. In +particular, using it in googletest comparison assertions (`EXPECT_EQ`, etc) will +generate an "undefined reference" linker error. The fact that "it used to work" +doesn't mean it's valid. It just means that you were lucky. :-) + +## Can I derive a test fixture from another? + +Yes. + +Each test fixture has a corresponding and same named test suite. This means only +one test suite can use a particular fixture. Sometimes, however, multiple test +cases may want to use the same or slightly different fixtures. For example, you +may want to make sure that all of a GUI library's test suites don't leak +important system resources like fonts and brushes. + +In googletest, you share a fixture among test suites by putting the shared logic +in a base test fixture, then deriving from that base a separate fixture for each +test suite that wants to use this common logic. You then use `TEST_F()` to write +tests using each derived fixture. + +Typically, your code looks like this: + +```c++ +// Defines a base test fixture. +class BaseTest : public ::testing::Test { + protected: + ... +}; + +// Derives a fixture FooTest from BaseTest. +class FooTest : public BaseTest { + protected: + void SetUp() override { + BaseTest::SetUp(); // Sets up the base fixture first. + ... additional set-up work ... + } + + void TearDown() override { + ... clean-up work for FooTest ... + BaseTest::TearDown(); // Remember to tear down the base fixture + // after cleaning up FooTest! + } + + ... functions and variables for FooTest ... +}; + +// Tests that use the fixture FooTest. +TEST_F(FooTest, Bar) { ... } +TEST_F(FooTest, Baz) { ... } + +... additional fixtures derived from BaseTest ... +``` + +If necessary, you can continue to derive test fixtures from a derived fixture. +googletest has no limit on how deep the hierarchy can be. + +For a complete example using derived test fixtures, see +[sample5_unittest.cc](../samples/sample5_unittest.cc). + +## My compiler complains "void value not ignored as it ought to be." What does this mean? + +You're probably using an `ASSERT_*()` in a function that doesn't return `void`. +`ASSERT_*()` can only be used in `void` functions, due to exceptions being +disabled by our build system. Please see more details +[here](advanced.md#assertion-placement). + +## My death test hangs (or seg-faults). How do I fix it? + +In googletest, death tests are run in a child process and the way they work is +delicate. To write death tests you really need to understand how they work. +Please make sure you have read [this](advanced.md#how-it-works). + +In particular, death tests don't like having multiple threads in the parent +process. So the first thing you can try is to eliminate creating threads outside +of `EXPECT_DEATH()`. For example, you may want to use mocks or fake objects +instead of real ones in your tests. + +Sometimes this is impossible as some library you must use may be creating +threads before `main()` is even reached. In this case, you can try to minimize +the chance of conflicts by either moving as many activities as possible inside +`EXPECT_DEATH()` (in the extreme case, you want to move everything inside), or +leaving as few things as possible in it. Also, you can try to set the death test +style to `"threadsafe"`, which is safer but slower, and see if it helps. + +If you go with thread-safe death tests, remember that they rerun the test +program from the beginning in the child process. Therefore make sure your +program can run side-by-side with itself and is deterministic. + +In the end, this boils down to good concurrent programming. You have to make +sure that there is no race conditions or dead locks in your program. No silver +bullet - sorry! + +## Should I use the constructor/destructor of the test fixture or SetUp()/TearDown()? {#CtorVsSetUp} + +The first thing to remember is that googletest does **not** reuse the same test +fixture object across multiple tests. For each `TEST_F`, googletest will create +a **fresh** test fixture object, immediately call `SetUp()`, run the test body, +call `TearDown()`, and then delete the test fixture object. + +When you need to write per-test set-up and tear-down logic, you have the choice +between using the test fixture constructor/destructor or `SetUp()/TearDown()`. +The former is usually preferred, as it has the following benefits: + +* By initializing a member variable in the constructor, we have the option to + make it `const`, which helps prevent accidental changes to its value and + makes the tests more obviously correct. +* In case we need to subclass the test fixture class, the subclass' + constructor is guaranteed to call the base class' constructor *first*, and + the subclass' destructor is guaranteed to call the base class' destructor + *afterward*. With `SetUp()/TearDown()`, a subclass may make the mistake of + forgetting to call the base class' `SetUp()/TearDown()` or call them at the + wrong time. + +You may still want to use `SetUp()/TearDown()` in the following cases: + +* C++ does not allow virtual function calls in constructors and destructors. + You can call a method declared as virtual, but it will not use dynamic + dispatch, it will use the definition from the class the constructor of which + is currently executing. This is because calling a virtual method before the + derived class constructor has a chance to run is very dangerous - the + virtual method might operate on uninitialized data. Therefore, if you need + to call a method that will be overridden in a derived class, you have to use + `SetUp()/TearDown()`. +* In the body of a constructor (or destructor), it's not possible to use the + `ASSERT_xx` macros. Therefore, if the set-up operation could cause a fatal + test failure that should prevent the test from running, it's necessary to + use `abort` and abort the whole test executable, + or to use `SetUp()` instead of a constructor. +* If the tear-down operation could throw an exception, you must use + `TearDown()` as opposed to the destructor, as throwing in a destructor leads + to undefined behavior and usually will kill your program right away. Note + that many standard libraries (like STL) may throw when exceptions are + enabled in the compiler. Therefore you should prefer `TearDown()` if you + want to write portable tests that work with or without exceptions. +* The googletest team is considering making the assertion macros throw on + platforms where exceptions are enabled (e.g. Windows, Mac OS, and Linux + client-side), which will eliminate the need for the user to propagate + failures from a subroutine to its caller. Therefore, you shouldn't use + googletest assertions in a destructor if your code could run on such a + platform. + +## The compiler complains "no matching function to call" when I use ASSERT_PRED*. How do I fix it? + +If the predicate function you use in `ASSERT_PRED*` or `EXPECT_PRED*` is +overloaded or a template, the compiler will have trouble figuring out which +overloaded version it should use. `ASSERT_PRED_FORMAT*` and +`EXPECT_PRED_FORMAT*` don't have this problem. + +If you see this error, you might want to switch to +`(ASSERT|EXPECT)_PRED_FORMAT*`, which will also give you a better failure +message. If, however, that is not an option, you can resolve the problem by +explicitly telling the compiler which version to pick. + +For example, suppose you have + +```c++ +bool IsPositive(int n) { + return n > 0; +} + +bool IsPositive(double x) { + return x > 0; +} +``` + +you will get a compiler error if you write + +```c++ +EXPECT_PRED1(IsPositive, 5); +``` + +However, this will work: + +```c++ +EXPECT_PRED1(static_cast(IsPositive), 5); +``` + +(The stuff inside the angled brackets for the `static_cast` operator is the type +of the function pointer for the `int`-version of `IsPositive()`.) + +As another example, when you have a template function + +```c++ +template +bool IsNegative(T x) { + return x < 0; +} +``` + +you can use it in a predicate assertion like this: + +```c++ +ASSERT_PRED1(IsNegative, -5); +``` + +Things are more interesting if your template has more than one parameters. The +following won't compile: + +```c++ +ASSERT_PRED2(GreaterThan, 5, 0); +``` + +as the C++ pre-processor thinks you are giving `ASSERT_PRED2` 4 arguments, which +is one more than expected. The workaround is to wrap the predicate function in +parentheses: + +```c++ +ASSERT_PRED2((GreaterThan), 5, 0); +``` + +## My compiler complains about "ignoring return value" when I call RUN_ALL_TESTS(). Why? + +Some people had been ignoring the return value of `RUN_ALL_TESTS()`. That is, +instead of + +```c++ + return RUN_ALL_TESTS(); +``` + +they write + +```c++ + RUN_ALL_TESTS(); +``` + +This is **wrong and dangerous**. The testing services needs to see the return +value of `RUN_ALL_TESTS()` in order to determine if a test has passed. If your +`main()` function ignores it, your test will be considered successful even if it +has a googletest assertion failure. Very bad. + +We have decided to fix this (thanks to Michael Chastain for the idea). Now, your +code will no longer be able to ignore `RUN_ALL_TESTS()` when compiled with +`gcc`. If you do so, you'll get a compiler error. + +If you see the compiler complaining about you ignoring the return value of +`RUN_ALL_TESTS()`, the fix is simple: just make sure its value is used as the +return value of `main()`. + +But how could we introduce a change that breaks existing tests? Well, in this +case, the code was already broken in the first place, so we didn't break it. :-) + +## My compiler complains that a constructor (or destructor) cannot return a value. What's going on? + +Due to a peculiarity of C++, in order to support the syntax for streaming +messages to an `ASSERT_*`, e.g. + +```c++ + ASSERT_EQ(1, Foo()) << "blah blah" << foo; +``` + +we had to give up using `ASSERT*` and `FAIL*` (but not `EXPECT*` and +`ADD_FAILURE*`) in constructors and destructors. The workaround is to move the +content of your constructor/destructor to a private void member function, or +switch to `EXPECT_*()` if that works. This +[section](advanced.md#assertion-placement) in the user's guide explains it. + +## My SetUp() function is not called. Why? + +C++ is case-sensitive. Did you spell it as `Setup()`? + +Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and +wonder why it's never called. + + +## I have several test suites which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious. + +You don't have to. Instead of + +```c++ +class FooTest : public BaseTest {}; + +TEST_F(FooTest, Abc) { ... } +TEST_F(FooTest, Def) { ... } + +class BarTest : public BaseTest {}; + +TEST_F(BarTest, Abc) { ... } +TEST_F(BarTest, Def) { ... } +``` + +you can simply `typedef` the test fixtures: + +```c++ +typedef BaseTest FooTest; + +TEST_F(FooTest, Abc) { ... } +TEST_F(FooTest, Def) { ... } + +typedef BaseTest BarTest; + +TEST_F(BarTest, Abc) { ... } +TEST_F(BarTest, Def) { ... } +``` + +## googletest output is buried in a whole bunch of LOG messages. What do I do? + +The googletest output is meant to be a concise and human-friendly report. If +your test generates textual output itself, it will mix with the googletest +output, making it hard to read. However, there is an easy solution to this +problem. + +Since `LOG` messages go to stderr, we decided to let googletest output go to +stdout. This way, you can easily separate the two using redirection. For +example: + +```shell +$ ./my_test > gtest_output.txt +``` + +## Why should I prefer test fixtures over global variables? + +There are several good reasons: + +1. It's likely your test needs to change the states of its global variables. + This makes it difficult to keep side effects from escaping one test and + contaminating others, making debugging difficult. By using fixtures, each + test has a fresh set of variables that's different (but with the same + names). Thus, tests are kept independent of each other. +2. Global variables pollute the global namespace. +3. Test fixtures can be reused via subclassing, which cannot be done easily + with global variables. This is useful if many test suites have something in + common. + +## What can the statement argument in ASSERT_DEATH() be? + +`ASSERT_DEATH(*statement*, *regex*)` (or any death assertion macro) can be used +wherever `*statement*` is valid. So basically `*statement*` can be any C++ +statement that makes sense in the current context. In particular, it can +reference global and/or local variables, and can be: + +* a simple function call (often the case), +* a complex expression, or +* a compound statement. + +Some examples are shown here: + +```c++ +// A death test can be a simple function call. +TEST(MyDeathTest, FunctionCall) { + ASSERT_DEATH(Xyz(5), "Xyz failed"); +} + +// Or a complex expression that references variables and functions. +TEST(MyDeathTest, ComplexExpression) { + const bool c = Condition(); + ASSERT_DEATH((c ? Func1(0) : object2.Method("test")), + "(Func1|Method) failed"); +} + +// Death assertions can be used any where in a function. In +// particular, they can be inside a loop. +TEST(MyDeathTest, InsideLoop) { + // Verifies that Foo(0), Foo(1), ..., and Foo(4) all die. + for (int i = 0; i < 5; i++) { + EXPECT_DEATH_M(Foo(i), "Foo has \\d+ errors", + ::testing::Message() << "where i is " << i); + } +} + +// A death assertion can contain a compound statement. +TEST(MyDeathTest, CompoundStatement) { + // Verifies that at lease one of Bar(0), Bar(1), ..., and + // Bar(4) dies. + ASSERT_DEATH({ + for (int i = 0; i < 5; i++) { + Bar(i); + } + }, + "Bar has \\d+ errors"); +} +``` + +gtest-death-test_test.cc contains more examples if you are interested. + +## I have a fixture class `FooTest`, but `TEST_F(FooTest, Bar)` gives me error ``"no matching function for call to `FooTest::FooTest()'"``. Why? + +Googletest needs to be able to create objects of your test fixture class, so it +must have a default constructor. Normally the compiler will define one for you. +However, there are cases where you have to define your own: + +* If you explicitly declare a non-default constructor for class `FooTest` + (`DISALLOW_EVIL_CONSTRUCTORS()` does this), then you need to define a + default constructor, even if it would be empty. +* If `FooTest` has a const non-static data member, then you have to define the + default constructor *and* initialize the const member in the initializer + list of the constructor. (Early versions of `gcc` doesn't force you to + initialize the const member. It's a bug that has been fixed in `gcc 4`.) + +## Why does ASSERT_DEATH complain about previous threads that were already joined? + +With the Linux pthread library, there is no turning back once you cross the line +from single thread to multiple threads. The first time you create a thread, a +manager thread is created in addition, so you get 3, not 2, threads. Later when +the thread you create joins the main thread, the thread count decrements by 1, +but the manager thread will never be killed, so you still have 2 threads, which +means you cannot safely run a death test. + +The new NPTL thread library doesn't suffer from this problem, as it doesn't +create a manager thread. However, if you don't control which machine your test +runs on, you shouldn't depend on this. + +## Why does googletest require the entire test suite, instead of individual tests, to be named *DeathTest when it uses ASSERT_DEATH? + +googletest does not interleave tests from different test suites. That is, it +runs all tests in one test suite first, and then runs all tests in the next test +suite, and so on. googletest does this because it needs to set up a test suite +before the first test in it is run, and tear it down afterwords. Splitting up +the test case would require multiple set-up and tear-down processes, which is +inefficient and makes the semantics unclean. + +If we were to determine the order of tests based on test name instead of test +case name, then we would have a problem with the following situation: + +```c++ +TEST_F(FooTest, AbcDeathTest) { ... } +TEST_F(FooTest, Uvw) { ... } + +TEST_F(BarTest, DefDeathTest) { ... } +TEST_F(BarTest, Xyz) { ... } +``` + +Since `FooTest.AbcDeathTest` needs to run before `BarTest.Xyz`, and we don't +interleave tests from different test suites, we need to run all tests in the +`FooTest` case before running any test in the `BarTest` case. This contradicts +with the requirement to run `BarTest.DefDeathTest` before `FooTest.Uvw`. + +## But I don't like calling my entire test suite \*DeathTest when it contains both death tests and non-death tests. What do I do? + +You don't have to, but if you like, you may split up the test suite into +`FooTest` and `FooDeathTest`, where the names make it clear that they are +related: + +```c++ +class FooTest : public ::testing::Test { ... }; + +TEST_F(FooTest, Abc) { ... } +TEST_F(FooTest, Def) { ... } + +using FooDeathTest = FooTest; + +TEST_F(FooDeathTest, Uvw) { ... EXPECT_DEATH(...) ... } +TEST_F(FooDeathTest, Xyz) { ... ASSERT_DEATH(...) ... } +``` + +## googletest prints the LOG messages in a death test's child process only when the test fails. How can I see the LOG messages when the death test succeeds? + +Printing the LOG messages generated by the statement inside `EXPECT_DEATH()` +makes it harder to search for real problems in the parent's log. Therefore, +googletest only prints them when the death test has failed. + +If you really need to see such LOG messages, a workaround is to temporarily +break the death test (e.g. by changing the regex pattern it is expected to +match). Admittedly, this is a hack. We'll consider a more permanent solution +after the fork-and-exec-style death tests are implemented. + +## The compiler complains about "no match for 'operator<<'" when I use an assertion. What gives? + +If you use a user-defined type `FooType` in an assertion, you must make sure +there is an `std::ostream& operator<<(std::ostream&, const FooType&)` function +defined such that we can print a value of `FooType`. + +In addition, if `FooType` is declared in a name space, the `<<` operator also +needs to be defined in the *same* name space. See https://abseil.io/tips/49 for details. + +## How do I suppress the memory leak messages on Windows? + +Since the statically initialized googletest singleton requires allocations on +the heap, the Visual C++ memory leak detector will report memory leaks at the +end of the program run. The easiest way to avoid this is to use the +`_CrtMemCheckpoint` and `_CrtMemDumpAllObjectsSince` calls to not report any +statically initialized heap objects. See MSDN for more details and additional +heap check/debug routines. + +## How can my code detect if it is running in a test? + +If you write code that sniffs whether it's running in a test and does different +things accordingly, you are leaking test-only logic into production code and +there is no easy way to ensure that the test-only code paths aren't run by +mistake in production. Such cleverness also leads to +[Heisenbugs](https://en.wikipedia.org/wiki/Heisenbug). Therefore we strongly +advise against the practice, and googletest doesn't provide a way to do it. + +In general, the recommended way to cause the code to behave differently under +test is [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection). You can inject +different functionality from the test and from the production code. Since your +production code doesn't link in the for-test logic at all (the +[`testonly`](https://docs.bazel.build/versions/master/be/common-definitions.html#common.testonly) attribute for BUILD targets helps to ensure +that), there is no danger in accidentally running it. + +However, if you *really*, *really*, *really* have no choice, and if you follow +the rule of ending your test program names with `_test`, you can use the +*horrible* hack of sniffing your executable name (`argv[0]` in `main()`) to know +whether the code is under test. + +## How do I temporarily disable a test? + +If you have a broken test that you cannot fix right away, you can add the +DISABLED_ prefix to its name. This will exclude it from execution. This is +better than commenting out the code or using #if 0, as disabled tests are still +compiled (and thus won't rot). + +To include disabled tests in test execution, just invoke the test program with +the --gtest_also_run_disabled_tests flag. + +## Is it OK if I have two separate `TEST(Foo, Bar)` test methods defined in different namespaces? + +Yes. + +The rule is **all test methods in the same test suite must use the same fixture +class.** This means that the following is **allowed** because both tests use the +same fixture class (`::testing::Test`). + +```c++ +namespace foo { +TEST(CoolTest, DoSomething) { + SUCCEED(); +} +} // namespace foo + +namespace bar { +TEST(CoolTest, DoSomething) { + SUCCEED(); +} +} // namespace bar +``` + +However, the following code is **not allowed** and will produce a runtime error +from googletest because the test methods are using different test fixture +classes with the same test suite name. + +```c++ +namespace foo { +class CoolTest : public ::testing::Test {}; // Fixture foo::CoolTest +TEST_F(CoolTest, DoSomething) { + SUCCEED(); +} +} // namespace foo + +namespace bar { +class CoolTest : public ::testing::Test {}; // Fixture: bar::CoolTest +TEST_F(CoolTest, DoSomething) { + SUCCEED(); +} +} // namespace bar +``` diff --git a/3rdparty/gtest/docs/pkgconfig.md b/3rdparty/gtest/docs/pkgconfig.md new file mode 100644 index 0000000..6dc0673 --- /dev/null +++ b/3rdparty/gtest/docs/pkgconfig.md @@ -0,0 +1,141 @@ +## Using GoogleTest from various build systems + +GoogleTest comes with pkg-config files that can be used to determine all +necessary flags for compiling and linking to GoogleTest (and GoogleMock). +Pkg-config is a standardised plain-text format containing + +* the includedir (-I) path +* necessary macro (-D) definitions +* further required flags (-pthread) +* the library (-L) path +* the library (-l) to link to + +All current build systems support pkg-config in one way or another. For all +examples here we assume you want to compile the sample +`samples/sample3_unittest.cc`. + +### CMake + +Using `pkg-config` in CMake is fairly easy: + +```cmake +cmake_minimum_required(VERSION 3.0) + +cmake_policy(SET CMP0048 NEW) +project(my_gtest_pkgconfig VERSION 0.0.1 LANGUAGES CXX) + +find_package(PkgConfig) +pkg_search_module(GTEST REQUIRED gtest_main) + +add_executable(testapp samples/sample3_unittest.cc) +target_link_libraries(testapp ${GTEST_LDFLAGS}) +target_compile_options(testapp PUBLIC ${GTEST_CFLAGS}) + +include(CTest) +add_test(first_and_only_test testapp) +``` + +It is generally recommended that you use `target_compile_options` + `_CFLAGS` +over `target_include_directories` + `_INCLUDE_DIRS` as the former includes not +just -I flags (GoogleTest might require a macro indicating to internal headers +that all libraries have been compiled with threading enabled. In addition, +GoogleTest might also require `-pthread` in the compiling step, and as such +splitting the pkg-config `Cflags` variable into include dirs and macros for +`target_compile_definitions()` might still miss this). The same recommendation +goes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which happens +to discard `-L` flags and `-pthread`. + +### Autotools + +Finding GoogleTest in Autoconf and using it from Automake is also fairly easy: + +In your `configure.ac`: + +``` +AC_PREREQ([2.69]) +AC_INIT([my_gtest_pkgconfig], [0.0.1]) +AC_CONFIG_SRCDIR([samples/sample3_unittest.cc]) +AC_PROG_CXX + +PKG_CHECK_MODULES([GTEST], [gtest_main]) + +AM_INIT_AUTOMAKE([foreign subdir-objects]) +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT +``` + +and in your `Makefile.am`: + +``` +check_PROGRAMS = testapp +TESTS = $(check_PROGRAMS) + +testapp_SOURCES = samples/sample3_unittest.cc +testapp_CXXFLAGS = $(GTEST_CFLAGS) +testapp_LDADD = $(GTEST_LIBS) +``` + +### Meson + +Meson natively uses pkgconfig to query dependencies: + +``` +project('my_gtest_pkgconfig', 'cpp', version : '0.0.1') + +gtest_dep = dependency('gtest_main') + +testapp = executable( + 'testapp', + files(['samples/sample3_unittest.cc']), + dependencies : gtest_dep, + install : false) + +test('first_and_only_test', testapp) +``` + +### Plain Makefiles + +Since `pkg-config` is a small Unix command-line utility, it can be used in +handwritten `Makefile`s too: + +```makefile +GTEST_CFLAGS = `pkg-config --cflags gtest_main` +GTEST_LIBS = `pkg-config --libs gtest_main` + +.PHONY: tests all + +tests: all + ./testapp + +all: testapp + +testapp: testapp.o + $(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $@ $(GTEST_LIBS) + +testapp.o: samples/sample3_unittest.cc + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $< -c -o $@ $(GTEST_CFLAGS) +``` + +### Help! pkg-config can't find GoogleTest! + +Let's say you have a `CMakeLists.txt` along the lines of the one in this +tutorial and you try to run `cmake`. It is very possible that you get a failure +along the lines of: + +``` +-- Checking for one of the modules 'gtest_main' +CMake Error at /usr/share/cmake/Modules/FindPkgConfig.cmake:640 (message): + None of the required 'gtest_main' found +``` + +These failures are common if you installed GoogleTest yourself and have not +sourced it from a distro or other package manager. If so, you need to tell +pkg-config where it can find the `.pc` files containing the information. Say you +installed GoogleTest to `/usr/local`, then it might be that the `.pc` files are +installed under `/usr/local/lib64/pkgconfig`. If you set + +``` +export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig +``` + +pkg-config will also try to look in `PKG_CONFIG_PATH` to find `gtest_main.pc`. diff --git a/3rdparty/gtest/docs/primer.md b/3rdparty/gtest/docs/primer.md new file mode 100644 index 0000000..0317692 --- /dev/null +++ b/3rdparty/gtest/docs/primer.md @@ -0,0 +1,567 @@ +# Googletest Primer + +## Introduction: Why googletest? + +*googletest* helps you write better C++ tests. + +googletest is a testing framework developed by the Testing Technology team with +Google's specific requirements and constraints in mind. Whether you work on +Linux, Windows, or a Mac, if you write C++ code, googletest can help you. And it +supports *any* kind of tests, not just unit tests. + +So what makes a good test, and how does googletest fit in? We believe: + +1. Tests should be *independent* and *repeatable*. It's a pain to debug a test + that succeeds or fails as a result of other tests. googletest isolates the + tests by running each of them on a different object. When a test fails, + googletest allows you to run it in isolation for quick debugging. +2. Tests should be well *organized* and reflect the structure of the tested + code. googletest groups related tests into test suites that can share data + and subroutines. This common pattern is easy to recognize and makes tests + easy to maintain. Such consistency is especially helpful when people switch + projects and start to work on a new code base. +3. Tests should be *portable* and *reusable*. Google has a lot of code that is + platform-neutral; its tests should also be platform-neutral. googletest + works on different OSes, with different compilers, with or without + exceptions, so googletest tests can work with a variety of configurations. +4. When tests fail, they should provide as much *information* about the problem + as possible. googletest doesn't stop at the first test failure. Instead, it + only stops the current test and continues with the next. You can also set up + tests that report non-fatal failures after which the current test continues. + Thus, you can detect and fix multiple bugs in a single run-edit-compile + cycle. +5. The testing framework should liberate test writers from housekeeping chores + and let them focus on the test *content*. googletest automatically keeps + track of all tests defined, and doesn't require the user to enumerate them + in order to run them. +6. Tests should be *fast*. With googletest, you can reuse shared resources + across tests and pay for the set-up/tear-down only once, without making + tests depend on each other. + +Since googletest is based on the popular xUnit architecture, you'll feel right +at home if you've used JUnit or PyUnit before. If not, it will take you about 10 +minutes to learn the basics and get started. So let's go! + +## Beware of the nomenclature + +_Note:_ There might be some confusion arising from different definitions of the +terms _Test_, _Test Case_ and _Test Suite_, so beware of misunderstanding these. + +Historically, googletest started to use the term _Test Case_ for grouping +related tests, whereas current publications, including International Software +Testing Qualifications Board ([ISTQB](http://www.istqb.org/)) materials and +various textbooks on software quality, use the term +_[Test Suite][istqb test suite]_ for this. + +The related term _Test_, as it is used in googletest, corresponds to the term +_[Test Case][istqb test case]_ of ISTQB and others. + +The term _Test_ is commonly of broad enough sense, including ISTQB's definition +of _Test Case_, so it's not much of a problem here. But the term _Test Case_ as +was used in Google Test is of contradictory sense and thus confusing. + +googletest recently started replacing the term _Test Case_ with _Test Suite_. +The preferred API is *TestSuite*. The older TestCase API is being slowly +deprecated and refactored away. + +So please be aware of the different definitions of the terms: + + + +Meaning | googletest Term | [ISTQB](http://www.istqb.org/) Term +:----------------------------------------------------------------------------------- | :---------------------- | :---------------------------------- +Exercise a particular program path with specific input values and verify the results | [TEST()](#simple-tests) | [Test Case][istqb test case] + + + +[istqb test case]: http://glossary.istqb.org/en/search/test%20case +[istqb test suite]: http://glossary.istqb.org/en/search/test%20suite + +## Basic Concepts + +When using googletest, you start by writing *assertions*, which are statements +that check whether a condition is true. An assertion's result can be *success*, +*nonfatal failure*, or *fatal failure*. If a fatal failure occurs, it aborts the +current function; otherwise the program continues normally. + +*Tests* use assertions to verify the tested code's behavior. If a test crashes +or has a failed assertion, then it *fails*; otherwise it *succeeds*. + +A *test suite* contains one or many tests. You should group your tests into test +suites that reflect the structure of the tested code. When multiple tests in a +test suite need to share common objects and subroutines, you can put them into a +*test fixture* class. + +A *test program* can contain multiple test suites. + +We'll now explain how to write a test program, starting at the individual +assertion level and building up to tests and test suites. + +## Assertions + +googletest assertions are macros that resemble function calls. You test a class +or function by making assertions about its behavior. When an assertion fails, +googletest prints the assertion's source file and line number location, along +with a failure message. You may also supply a custom failure message which will +be appended to googletest's message. + +The assertions come in pairs that test the same thing but have different effects +on the current function. `ASSERT_*` versions generate fatal failures when they +fail, and **abort the current function**. `EXPECT_*` versions generate nonfatal +failures, which don't abort the current function. Usually `EXPECT_*` are +preferred, as they allow more than one failure to be reported in a test. +However, you should use `ASSERT_*` if it doesn't make sense to continue when the +assertion in question fails. + +Since a failed `ASSERT_*` returns from the current function immediately, +possibly skipping clean-up code that comes after it, it may cause a space leak. +Depending on the nature of the leak, it may or may not be worth fixing - so keep +this in mind if you get a heap checker error in addition to assertion errors. + +To provide a custom failure message, simply stream it into the macro using the +`<<` operator or a sequence of such operators. An example: + +```c++ +ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length"; + +for (int i = 0; i < x.size(); ++i) { + EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i; +} +``` + +Anything that can be streamed to an `ostream` can be streamed to an assertion +macro--in particular, C strings and `string` objects. If a wide string +(`wchar_t*`, `TCHAR*` in `UNICODE` mode on Windows, or `std::wstring`) is +streamed to an assertion, it will be translated to UTF-8 when printed. + +### Basic Assertions + +These assertions do basic true/false condition testing. + +Fatal assertion | Nonfatal assertion | Verifies +-------------------------- | -------------------------- | -------------------- +`ASSERT_TRUE(condition);` | `EXPECT_TRUE(condition);` | `condition` is true +`ASSERT_FALSE(condition);` | `EXPECT_FALSE(condition);` | `condition` is false + +Remember, when they fail, `ASSERT_*` yields a fatal failure and returns from the +current function, while `EXPECT_*` yields a nonfatal failure, allowing the +function to continue running. In either case, an assertion failure means its +containing test fails. + +**Availability**: Linux, Windows, Mac. + +### Binary Comparison + +This section describes assertions that compare two values. + +Fatal assertion | Nonfatal assertion | Verifies +------------------------ | ------------------------ | -------------- +`ASSERT_EQ(val1, val2);` | `EXPECT_EQ(val1, val2);` | `val1 == val2` +`ASSERT_NE(val1, val2);` | `EXPECT_NE(val1, val2);` | `val1 != val2` +`ASSERT_LT(val1, val2);` | `EXPECT_LT(val1, val2);` | `val1 < val2` +`ASSERT_LE(val1, val2);` | `EXPECT_LE(val1, val2);` | `val1 <= val2` +`ASSERT_GT(val1, val2);` | `EXPECT_GT(val1, val2);` | `val1 > val2` +`ASSERT_GE(val1, val2);` | `EXPECT_GE(val1, val2);` | `val1 >= val2` + +Value arguments must be comparable by the assertion's comparison operator or +you'll get a compiler error. We used to require the arguments to support the +`<<` operator for streaming to an `ostream`, but this is no longer necessary. If +`<<` is supported, it will be called to print the arguments when the assertion +fails; otherwise googletest will attempt to print them in the best way it can. +For more details and how to customize the printing of the arguments, see the +[documentation](../../googlemock/docs/cook_book.md#teaching-gmock-how-to-print-your-values). + +These assertions can work with a user-defined type, but only if you define the +corresponding comparison operator (e.g., `==` or `<`). Since this is discouraged +by the Google +[C++ Style Guide](https://google.github.io/styleguide/cppguide.html#Operator_Overloading), +you may need to use `ASSERT_TRUE()` or `EXPECT_TRUE()` to assert the equality of +two objects of a user-defined type. + +However, when possible, `ASSERT_EQ(actual, expected)` is preferred to +`ASSERT_TRUE(actual == expected)`, since it tells you `actual` and `expected`'s +values on failure. + +Arguments are always evaluated exactly once. Therefore, it's OK for the +arguments to have side effects. However, as with any ordinary C/C++ function, +the arguments' evaluation order is undefined (i.e., the compiler is free to +choose any order), and your code should not depend on any particular argument +evaluation order. + +`ASSERT_EQ()` does pointer equality on pointers. If used on two C strings, it +tests if they are in the same memory location, not if they have the same value. +Therefore, if you want to compare C strings (e.g. `const char*`) by value, use +`ASSERT_STREQ()`, which will be described later on. In particular, to assert +that a C string is `NULL`, use `ASSERT_STREQ(c_string, NULL)`. Consider using +`ASSERT_EQ(c_string, nullptr)` if c++11 is supported. To compare two `string` +objects, you should use `ASSERT_EQ`. + +When doing pointer comparisons use `*_EQ(ptr, nullptr)` and `*_NE(ptr, nullptr)` +instead of `*_EQ(ptr, NULL)` and `*_NE(ptr, NULL)`. This is because `nullptr` is +typed, while `NULL` is not. See the [FAQ](faq.md) for more details. + +If you're working with floating point numbers, you may want to use the floating +point variations of some of these macros in order to avoid problems caused by +rounding. See [Advanced googletest Topics](advanced.md) for details. + +Macros in this section work with both narrow and wide string objects (`string` +and `wstring`). + +**Availability**: Linux, Windows, Mac. + +**Historical note**: Before February 2016 `*_EQ` had a convention of calling it +as `ASSERT_EQ(expected, actual)`, so lots of existing code uses this order. Now +`*_EQ` treats both parameters in the same way. + +### String Comparison + +The assertions in this group compare two **C strings**. If you want to compare +two `string` objects, use `EXPECT_EQ`, `EXPECT_NE`, and etc instead. + + + +| Fatal assertion | Nonfatal assertion | Verifies | +| -------------------------- | ------------------------------ | -------------------------------------------------------- | +| `ASSERT_STREQ(str1,str2);` | `EXPECT_STREQ(str1,str2);` | the two C strings have the same content | +| `ASSERT_STRNE(str1,str2);` | `EXPECT_STRNE(str1,str2);` | the two C strings have different contents | +| `ASSERT_STRCASEEQ(str1,str2);` | `EXPECT_STRCASEEQ(str1,str2);` | the two C strings have the same content, ignoring case | +| `ASSERT_STRCASENE(str1,str2);` | `EXPECT_STRCASENE(str1,str2);` | the two C strings have different contents, ignoring case | + + + +Note that "CASE" in an assertion name means that case is ignored. A `NULL` +pointer and an empty string are considered *different*. + +`*STREQ*` and `*STRNE*` also accept wide C strings (`wchar_t*`). If a comparison +of two wide strings fails, their values will be printed as UTF-8 narrow strings. + +**Availability**: Linux, Windows, Mac. + +**See also**: For more string comparison tricks (substring, prefix, suffix, and +regular expression matching, for example), see [this](advanced.md) in the +Advanced googletest Guide. + +## Simple Tests + +To create a test: + +1. Use the `TEST()` macro to define and name a test function. These are + ordinary C++ functions that don't return a value. +2. In this function, along with any valid C++ statements you want to include, + use the various googletest assertions to check values. +3. The test's result is determined by the assertions; if any assertion in the + test fails (either fatally or non-fatally), or if the test crashes, the + entire test fails. Otherwise, it succeeds. + +```c++ +TEST(TestSuiteName, TestName) { + ... test body ... +} +``` + +`TEST()` arguments go from general to specific. The *first* argument is the name +of the test suite, and the *second* argument is the test's name within the test +case. Both names must be valid C++ identifiers, and they should not contain +any underscores (`_`). A test's *full name* consists of its containing test suite and +its individual name. Tests from different test suites can have the same +individual name. + +For example, let's take a simple integer function: + +```c++ +int Factorial(int n); // Returns the factorial of n +``` + +A test suite for this function might look like: + +```c++ +// Tests factorial of 0. +TEST(FactorialTest, HandlesZeroInput) { + EXPECT_EQ(Factorial(0), 1); +} + +// Tests factorial of positive numbers. +TEST(FactorialTest, HandlesPositiveInput) { + EXPECT_EQ(Factorial(1), 1); + EXPECT_EQ(Factorial(2), 2); + EXPECT_EQ(Factorial(3), 6); + EXPECT_EQ(Factorial(8), 40320); +} +``` + +googletest groups the test results by test suites, so logically related tests +should be in the same test suite; in other words, the first argument to their +`TEST()` should be the same. In the above example, we have two tests, +`HandlesZeroInput` and `HandlesPositiveInput`, that belong to the same test +suite `FactorialTest`. + +When naming your test suites and tests, you should follow the same convention as +for +[naming functions and classes](https://google.github.io/styleguide/cppguide.html#Function_Names). + +**Availability**: Linux, Windows, Mac. + +## Test Fixtures: Using the Same Data Configuration for Multiple Tests {#same-data-multiple-tests} + +If you find yourself writing two or more tests that operate on similar data, you +can use a *test fixture*. This allows you to reuse the same configuration of +objects for several different tests. + +To create a fixture: + +1. Derive a class from `::testing::Test` . Start its body with `protected:`, as + we'll want to access fixture members from sub-classes. +2. Inside the class, declare any objects you plan to use. +3. If necessary, write a default constructor or `SetUp()` function to prepare + the objects for each test. A common mistake is to spell `SetUp()` as + **`Setup()`** with a small `u` - Use `override` in C++11 to make sure you + spelled it correctly. +4. If necessary, write a destructor or `TearDown()` function to release any + resources you allocated in `SetUp()` . To learn when you should use the + constructor/destructor and when you should use `SetUp()/TearDown()`, read + the [FAQ](faq.md#CtorVsSetUp). +5. If needed, define subroutines for your tests to share. + +When using a fixture, use `TEST_F()` instead of `TEST()` as it allows you to +access objects and subroutines in the test fixture: + +```c++ +TEST_F(TestFixtureName, TestName) { + ... test body ... +} +``` + +Like `TEST()`, the first argument is the test suite name, but for `TEST_F()` +this must be the name of the test fixture class. You've probably guessed: `_F` +is for fixture. + +Unfortunately, the C++ macro system does not allow us to create a single macro +that can handle both types of tests. Using the wrong macro causes a compiler +error. + +Also, you must first define a test fixture class before using it in a +`TEST_F()`, or you'll get the compiler error "`virtual outside class +declaration`". + +For each test defined with `TEST_F()`, googletest will create a *fresh* test +fixture at runtime, immediately initialize it via `SetUp()`, run the test, +clean up by calling `TearDown()`, and then delete the test fixture. Note that +different tests in the same test suite have different test fixture objects, and +googletest always deletes a test fixture before it creates the next one. +googletest does **not** reuse the same test fixture for multiple tests. Any +changes one test makes to the fixture do not affect other tests. + +As an example, let's write tests for a FIFO queue class named `Queue`, which has +the following interface: + +```c++ +template // E is the element type. +class Queue { + public: + Queue(); + void Enqueue(const E& element); + E* Dequeue(); // Returns NULL if the queue is empty. + size_t size() const; + ... +}; +``` + +First, define a fixture class. By convention, you should give it the name +`FooTest` where `Foo` is the class being tested. + +```c++ +class QueueTest : public ::testing::Test { + protected: + void SetUp() override { + q1_.Enqueue(1); + q2_.Enqueue(2); + q2_.Enqueue(3); + } + + // void TearDown() override {} + + Queue q0_; + Queue q1_; + Queue q2_; +}; +``` + +In this case, `TearDown()` is not needed since we don't have to clean up after +each test, other than what's already done by the destructor. + +Now we'll write tests using `TEST_F()` and this fixture. + +```c++ +TEST_F(QueueTest, IsEmptyInitially) { + EXPECT_EQ(q0_.size(), 0); +} + +TEST_F(QueueTest, DequeueWorks) { + int* n = q0_.Dequeue(); + EXPECT_EQ(n, nullptr); + + n = q1_.Dequeue(); + ASSERT_NE(n, nullptr); + EXPECT_EQ(*n, 1); + EXPECT_EQ(q1_.size(), 0); + delete n; + + n = q2_.Dequeue(); + ASSERT_NE(n, nullptr); + EXPECT_EQ(*n, 2); + EXPECT_EQ(q2_.size(), 1); + delete n; +} +``` + +The above uses both `ASSERT_*` and `EXPECT_*` assertions. The rule of thumb is +to use `EXPECT_*` when you want the test to continue to reveal more errors after +the assertion failure, and use `ASSERT_*` when continuing after failure doesn't +make sense. For example, the second assertion in the `Dequeue` test is +`ASSERT_NE(nullptr, n)`, as we need to dereference the pointer `n` later, which +would lead to a segfault when `n` is `NULL`. + +When these tests run, the following happens: + +1. googletest constructs a `QueueTest` object (let's call it `t1`). +2. `t1.SetUp()` initializes `t1`. +3. The first test (`IsEmptyInitially`) runs on `t1`. +4. `t1.TearDown()` cleans up after the test finishes. +5. `t1` is destructed. +6. The above steps are repeated on another `QueueTest` object, this time + running the `DequeueWorks` test. + +**Availability**: Linux, Windows, Mac. + +## Invoking the Tests + +`TEST()` and `TEST_F()` implicitly register their tests with googletest. So, +unlike with many other C++ testing frameworks, you don't have to re-list all +your defined tests in order to run them. + +After defining your tests, you can run them with `RUN_ALL_TESTS()`, which +returns `0` if all the tests are successful, or `1` otherwise. Note that +`RUN_ALL_TESTS()` runs *all tests* in your link unit--they can be from +different test suites, or even different source files. + +When invoked, the `RUN_ALL_TESTS()` macro: + +* Saves the state of all googletest flags. + +* Creates a test fixture object for the first test. + +* Initializes it via `SetUp()`. + +* Runs the test on the fixture object. + +* Cleans up the fixture via `TearDown()`. + +* Deletes the fixture. + +* Restores the state of all googletest flags. + +* Repeats the above steps for the next test, until all tests have run. + +If a fatal failure happens the subsequent steps will be skipped. + +> IMPORTANT: You must **not** ignore the return value of `RUN_ALL_TESTS()`, or +> you will get a compiler error. The rationale for this design is that the +> automated testing service determines whether a test has passed based on its +> exit code, not on its stdout/stderr output; thus your `main()` function must +> return the value of `RUN_ALL_TESTS()`. +> +> Also, you should call `RUN_ALL_TESTS()` only **once**. Calling it more than +> once conflicts with some advanced googletest features (e.g., thread-safe +> [death tests](advanced.md#death-tests)) and thus is not supported. + +**Availability**: Linux, Windows, Mac. + +## Writing the main() Function + +Write your own main() function, which should return the value of +`RUN_ALL_TESTS()`. + +You can start from this boilerplate: + +```c++ +#include "this/package/foo.h" +#include "gtest/gtest.h" + +namespace { + +// The fixture for testing class Foo. +class FooTest : public ::testing::Test { + protected: + // You can remove any or all of the following functions if its body + // is empty. + + FooTest() { + // You can do set-up work for each test here. + } + + ~FooTest() override { + // You can do clean-up work that doesn't throw exceptions here. + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + + void SetUp() override { + // Code here will be called immediately after the constructor (right + // before each test). + } + + void TearDown() override { + // Code here will be called immediately after each test (right + // before the destructor). + } + + // Objects declared here can be used by all tests in the test suite for Foo. +}; + +// Tests that the Foo::Bar() method does Abc. +TEST_F(FooTest, MethodBarDoesAbc) { + const std::string input_filepath = "this/package/testdata/myinputfile.dat"; + const std::string output_filepath = "this/package/testdata/myoutputfile.dat"; + Foo f; + EXPECT_EQ(f.Bar(input_filepath, output_filepath), 0); +} + +// Tests that Foo does Xyz. +TEST_F(FooTest, DoesXyz) { + // Exercises the Xyz feature of Foo. +} + +} // namespace + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +``` + +The `::testing::InitGoogleTest()` function parses the command line for +googletest flags, and removes all recognized flags. This allows the user to +control a test program's behavior via various flags, which we'll cover in +the [AdvancedGuide](advanced.md). You **must** call this function before calling +`RUN_ALL_TESTS()`, or the flags won't be properly initialized. + +On Windows, `InitGoogleTest()` also works with wide strings, so it can be used +in programs compiled in `UNICODE` mode as well. + +But maybe you think that writing all those main() functions is too much work? We +agree with you completely, and that's why Google Test provides a basic +implementation of main(). If it fits your needs, then just link your test with +gtest\_main library and you are good to go. + +NOTE: `ParseGUnitFlags()` is deprecated in favor of `InitGoogleTest()`. + +## Known Limitations + +* Google Test is designed to be thread-safe. The implementation is thread-safe + on systems where the `pthreads` library is available. It is currently + _unsafe_ to use Google Test assertions from two threads concurrently on + other systems (e.g. Windows). In most tests this is not an issue as usually + the assertions are done in the main thread. If you want to help, you can + volunteer to implement the necessary synchronization primitives in + `gtest-port.h` for your platform. diff --git a/3rdparty/gtest/docs/pump_manual.md b/3rdparty/gtest/docs/pump_manual.md new file mode 100644 index 0000000..10b3c5f --- /dev/null +++ b/3rdparty/gtest/docs/pump_manual.md @@ -0,0 +1,190 @@ +Pump is Useful for Meta Programming. + +# The Problem + +Template and macro libraries often need to define many classes, functions, or +macros that vary only (or almost only) in the number of arguments they take. +It's a lot of repetitive, mechanical, and error-prone work. + +Variadic templates and variadic macros can alleviate the problem. However, while +both are being considered by the C++ committee, neither is in the standard yet +or widely supported by compilers. Thus they are often not a good choice, +especially when your code needs to be portable. And their capabilities are still +limited. + +As a result, authors of such libraries often have to write scripts to generate +their implementation. However, our experience is that it's tedious to write such +scripts, which tend to reflect the structure of the generated code poorly and +are often hard to read and edit. For example, a small change needed in the +generated code may require some non-intuitive, non-trivial changes in the +script. This is especially painful when experimenting with the code. + +# Our Solution + +Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta +Programming, or Practical Utility for Meta Programming, whichever you prefer) is +a simple meta-programming tool for C++. The idea is that a programmer writes a +`foo.pump` file which contains C++ code plus meta code that manipulates the C++ +code. The meta code can handle iterations over a range, nested iterations, local +meta variable definitions, simple arithmetic, and conditional expressions. You +can view it as a small Domain-Specific Language. The meta language is designed +to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, for example) and +concise, making Pump code intuitive and easy to maintain. + +## Highlights + +* The implementation is in a single Python script and thus ultra portable: no + build or installation is needed and it works cross platforms. +* Pump tries to be smart with respect to + [Google's style guide](https://github.com/google/styleguide): it breaks long + lines (easy to have when they are generated) at acceptable places to fit + within 80 columns and indent the continuation lines correctly. +* The format is human-readable and more concise than XML. +* The format works relatively well with Emacs' C++ mode. + +## Examples + +The following Pump code (where meta keywords start with `$`, `[[` and `]]` are +meta brackets, and `$$` starts a meta comment that ends with the line): + +``` +$var n = 3 $$ Defines a meta variable n. +$range i 0..n $$ Declares the range of meta iterator i (inclusive). +$for i [[ + $$ Meta loop. +// Foo$i does blah for $i-ary predicates. +$range j 1..i +template +class Foo$i { +$if i == 0 [[ + blah a; +]] $elif i <= 2 [[ + blah b; +]] $else [[ + blah c; +]] +}; + +]] +``` + +will be translated by the Pump compiler to: + +```cpp +// Foo0 does blah for 0-ary predicates. +template +class Foo0 { + blah a; +}; + +// Foo1 does blah for 1-ary predicates. +template +class Foo1 { + blah b; +}; + +// Foo2 does blah for 2-ary predicates. +template +class Foo2 { + blah b; +}; + +// Foo3 does blah for 3-ary predicates. +template +class Foo3 { + blah c; +}; +``` + +In another example, + +``` +$range i 1..n +Func($for i + [[a$i]]); +$$ The text between i and [[ is the separator between iterations. +``` + +will generate one of the following lines (without the comments), depending on +the value of `n`: + +```cpp +Func(); // If n is 0. +Func(a1); // If n is 1. +Func(a1 + a2); // If n is 2. +Func(a1 + a2 + a3); // If n is 3. +// And so on... +``` + +## Constructs + +We support the following meta programming constructs: + +| `$var id = exp` | Defines a named constant value. `$id` is | +: : valid util the end of the current meta : +: : lexical block. : +| :------------------------------- | :--------------------------------------- | +| `$range id exp..exp` | Sets the range of an iteration variable, | +: : which can be reused in multiple loops : +: : later. : +| `$for id sep [[ code ]]` | Iteration. The range of `id` must have | +: : been defined earlier. `$id` is valid in : +: : `code`. : +| `$($)` | Generates a single `$` character. | +| `$id` | Value of the named constant or iteration | +: : variable. : +| `$(exp)` | Value of the expression. | +| `$if exp [[ code ]] else_branch` | Conditional. | +| `[[ code ]]` | Meta lexical block. | +| `cpp_code` | Raw C++ code. | +| `$$ comment` | Meta comment. | + +**Note:** To give the user some freedom in formatting the Pump source code, Pump +ignores a new-line character if it's right after `$for foo` or next to `[[` or +`]]`. Without this rule you'll often be forced to write very long lines to get +the desired output. Therefore sometimes you may need to insert an extra new-line +in such places for a new-line to show up in your output. + +## Grammar + +```ebnf +code ::= atomic_code* +atomic_code ::= $var id = exp + | $var id = [[ code ]] + | $range id exp..exp + | $for id sep [[ code ]] + | $($) + | $id + | $(exp) + | $if exp [[ code ]] else_branch + | [[ code ]] + | cpp_code +sep ::= cpp_code | empty_string +else_branch ::= $else [[ code ]] + | $elif exp [[ code ]] else_branch + | empty_string +exp ::= simple_expression_in_Python_syntax +``` + +## Code + +You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py). +It is still very unpolished and lacks automated tests, although it has been +successfully used many times. If you find a chance to use it in your project, +please let us know what you think! We also welcome help on improving Pump. + +## Real Examples + +You can find real-world applications of Pump in +[Google Test](https://github.com/google/googletest/tree/master/googletest) and +[Google Mock](https://github.com/google/googletest/tree/master/googlemock). The +source file `foo.h.pump` generates `foo.h`. + +## Tips + +* If a meta variable is followed by a letter or digit, you can separate them + using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` + generate `Foo1Helper` when `j` is 1. +* To avoid extra-long Pump source lines, you can break a line anywhere you + want by inserting `[[]]` followed by a new line. Since any new-line + character next to `[[` or `]]` is ignored, the generated code won't contain + this new line. diff --git a/3rdparty/gtest/docs/samples.md b/3rdparty/gtest/docs/samples.md new file mode 100644 index 0000000..aaa5883 --- /dev/null +++ b/3rdparty/gtest/docs/samples.md @@ -0,0 +1,22 @@ +# Googletest Samples {#samples} + +If you're like us, you'd like to look at +[googletest samples.](https://github.com/google/googletest/tree/master/googletest/samples) +The sample directory has a number of well-commented samples showing how to use a +variety of googletest features. + +* Sample #1 shows the basic steps of using googletest to test C++ functions. +* Sample #2 shows a more complex unit test for a class with multiple member + functions. +* Sample #3 uses a test fixture. +* Sample #4 teaches you how to use googletest and `googletest.h` together to + get the best of both libraries. +* Sample #5 puts shared testing logic in a base test fixture, and reuses it in + derived fixtures. +* Sample #6 demonstrates type-parameterized tests. +* Sample #7 teaches the basics of value-parameterized tests. +* Sample #8 shows using `Combine()` in value-parameterized tests. +* Sample #9 shows use of the listener API to modify Google Test's console + output and the use of its reflection API to inspect test results. +* Sample #10 shows use of the listener API to implement a primitive memory + leak checker. diff --git a/3rdparty/gtest/include/gtest/gtest-death-test.h b/3rdparty/gtest/include/gtest/gtest-death-test.h new file mode 100644 index 0000000..dc878ff --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest-death-test.h @@ -0,0 +1,343 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This header file defines the public API for death tests. It is +// #included by gtest.h so a user doesn't need to include this +// directly. +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +#include "gtest/internal/gtest-death-test-internal.h" + +namespace testing { + +// This flag controls the style of death tests. Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +GTEST_API_ bool InDeathTestChild(); + +} // namespace internal + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +// 1. It generates a warning if there is more than one active +// thread. This is because it's safe to fork() or clone() only +// when there is a single thread. +// +// 2. The parent process clone()s a sub-process and runs the death +// test in it; the sub-process exits with code 0 at the end of the +// death test, if it hasn't exited already. +// +// 3. The parent process waits for the sub-process to terminate. +// +// 4. The parent process checks the exit code and error message of +// the sub-process. +// +// Examples: +// +// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +// for (int i = 0; i < 5; i++) { +// EXPECT_DEATH(server.ProcessRequest(i), +// "Invalid request .* in ProcessRequest()") +// << "Failed to die on request " << i; +// } +// +// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +// bool KilledBySIGHUP(int exit_code) { +// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +// } +// +// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// On the regular expressions used in death tests: +// +// GOOGLETEST_CM0005 DO NOT DELETE +// On POSIX-compliant systems (*nix), we use the library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows or Mac), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// +// Known caveats: +// +// A "threadsafe" style death test obtains the path to the test +// program from argv[0] and re-executes it in the sub-process. For +// simplicity, the current implementation doesn't search the PATH +// when launching the sub-process. This means that the user must +// invoke the test program via a path that contains at least one +// path separator (e.g. path/to/foo_test and +// /absolute/path/to/bar_test are fine, but foo_test is not). This +// is rarely a problem as people usually don't put the test binary +// directory in PATH. +// + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +# define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test suite, if any: +# define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +# define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test suite, if any: +# define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class GTEST_API_ ExitedWithCode { + public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; + private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; +}; + +# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +// Tests that an exit code describes an exit due to termination by a +// given signal. +// GOOGLETEST_CM0006 DO NOT DELETE +class GTEST_API_ KilledBySignal { + public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + private: + const int signum_; +}; +# endif // !GTEST_OS_WINDOWS + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +// if (sideeffect) { +// *sideeffect = 12; +// } +// LOG(DFATAL) << "death"; +// return 12; +// } +// +// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) { +// int sideeffect = 0; +// // Only asserts in dbg. +// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +// // opt-mode has sideeffect visible. +// EXPECT_EQ(12, sideeffect); +// #else +// // dbg-mode no visible sideeffect. +// EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects. A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +// // Side-effects here will have an effect after this statement in +// // opt mode, but none in debug mode. +// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +# ifdef NDEBUG + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# else + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) + +# endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters +// on systems that support death tests. This allows one to write such a macro on +// a system that does not support death tests and be sure that it will compile +// on a death-test supporting system. It is exposed publicly so that systems +// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST +// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and +// ASSERT_DEATH_IF_SUPPORTED. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter if and only if EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +# define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, ) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return) +#endif + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/3rdparty/gtest/include/gtest/gtest-matchers.h b/3rdparty/gtest/include/gtest/gtest-matchers.h new file mode 100644 index 0000000..9de6c2e --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest-matchers.h @@ -0,0 +1,750 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This file implements just enough of the matcher interface to allow +// EXPECT_DEATH and friends to accept a matcher argument. + +// IWYU pragma: private, include "testing/base/public/gunit.h" +// IWYU pragma: friend third_party/googletest/googlemock/.* +// IWYU pragma: friend third_party/googletest/googletest/.* + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ + +#include +#include +#include +#include + +#include "gtest/gtest-printers.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-port.h" + +// MSVC warning C5046 is new as of VS2017 version 15.8. +#if defined(_MSC_VER) && _MSC_VER >= 1915 +#define GTEST_MAYBE_5046_ 5046 +#else +#define GTEST_MAYBE_5046_ +#endif + +GTEST_DISABLE_MSC_WARNINGS_PUSH_( + 4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by + clients of class B */ + /* Symbol involving type with internal linkage not defined */) + +namespace testing { + +// To implement a matcher Foo for type T, define: +// 1. a class FooMatcherImpl that implements the +// MatcherInterface interface, and +// 2. a factory function that creates a Matcher object from a +// FooMatcherImpl*. +// +// The two-level delegation design makes it possible to allow a user +// to write "v" instead of "Eq(v)" where a Matcher is expected, which +// is impossible if we pass matchers by pointers. It also eases +// ownership management as Matcher objects can now be copied like +// plain values. + +// MatchResultListener is an abstract class. Its << operator can be +// used by a matcher to explain why a value matches or doesn't match. +// +class MatchResultListener { + public: + // Creates a listener object with the given underlying ostream. The + // listener does not own the ostream, and does not dereference it + // in the constructor or destructor. + explicit MatchResultListener(::std::ostream* os) : stream_(os) {} + virtual ~MatchResultListener() = 0; // Makes this class abstract. + + // Streams x to the underlying ostream; does nothing if the ostream + // is NULL. + template + MatchResultListener& operator<<(const T& x) { + if (stream_ != nullptr) *stream_ << x; + return *this; + } + + // Returns the underlying ostream. + ::std::ostream* stream() { return stream_; } + + // Returns true if and only if the listener is interested in an explanation + // of the match result. A matcher's MatchAndExplain() method can use + // this information to avoid generating the explanation when no one + // intends to hear it. + bool IsInterested() const { return stream_ != nullptr; } + + private: + ::std::ostream* const stream_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener); +}; + +inline MatchResultListener::~MatchResultListener() { +} + +// An instance of a subclass of this knows how to describe itself as a +// matcher. +class MatcherDescriberInterface { + public: + virtual ~MatcherDescriberInterface() {} + + // Describes this matcher to an ostream. The function should print + // a verb phrase that describes the property a value matching this + // matcher should have. The subject of the verb phrase is the value + // being matched. For example, the DescribeTo() method of the Gt(7) + // matcher prints "is greater than 7". + virtual void DescribeTo(::std::ostream* os) const = 0; + + // Describes the negation of this matcher to an ostream. For + // example, if the description of this matcher is "is greater than + // 7", the negated description could be "is not greater than 7". + // You are not required to override this when implementing + // MatcherInterface, but it is highly advised so that your matcher + // can produce good error messages. + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "not ("; + DescribeTo(os); + *os << ")"; + } +}; + +// The implementation of a matcher. +template +class MatcherInterface : public MatcherDescriberInterface { + public: + // Returns true if and only if the matcher matches x; also explains the + // match result to 'listener' if necessary (see the next paragraph), in + // the form of a non-restrictive relative clause ("which ...", + // "whose ...", etc) that describes x. For example, the + // MatchAndExplain() method of the Pointee(...) matcher should + // generate an explanation like "which points to ...". + // + // Implementations of MatchAndExplain() should add an explanation of + // the match result *if and only if* they can provide additional + // information that's not already present (or not obvious) in the + // print-out of x and the matcher's description. Whether the match + // succeeds is not a factor in deciding whether an explanation is + // needed, as sometimes the caller needs to print a failure message + // when the match succeeds (e.g. when the matcher is used inside + // Not()). + // + // For example, a "has at least 10 elements" matcher should explain + // what the actual element count is, regardless of the match result, + // as it is useful information to the reader; on the other hand, an + // "is empty" matcher probably only needs to explain what the actual + // size is when the match fails, as it's redundant to say that the + // size is 0 when the value is already known to be empty. + // + // You should override this method when defining a new matcher. + // + // It's the responsibility of the caller (Google Test) to guarantee + // that 'listener' is not NULL. This helps to simplify a matcher's + // implementation when it doesn't care about the performance, as it + // can talk to 'listener' without checking its validity first. + // However, in order to implement dummy listeners efficiently, + // listener->stream() may be NULL. + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; + + // Inherits these methods from MatcherDescriberInterface: + // virtual void DescribeTo(::std::ostream* os) const = 0; + // virtual void DescribeNegationTo(::std::ostream* os) const; +}; + +namespace internal { + +// Converts a MatcherInterface to a MatcherInterface. +template +class MatcherInterfaceAdapter : public MatcherInterface { + public: + explicit MatcherInterfaceAdapter(const MatcherInterface* impl) + : impl_(impl) {} + ~MatcherInterfaceAdapter() override { delete impl_; } + + void DescribeTo(::std::ostream* os) const override { impl_->DescribeTo(os); } + + void DescribeNegationTo(::std::ostream* os) const override { + impl_->DescribeNegationTo(os); + } + + bool MatchAndExplain(const T& x, + MatchResultListener* listener) const override { + return impl_->MatchAndExplain(x, listener); + } + + private: + const MatcherInterface* const impl_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter); +}; + +struct AnyEq { + template + bool operator()(const A& a, const B& b) const { return a == b; } +}; +struct AnyNe { + template + bool operator()(const A& a, const B& b) const { return a != b; } +}; +struct AnyLt { + template + bool operator()(const A& a, const B& b) const { return a < b; } +}; +struct AnyGt { + template + bool operator()(const A& a, const B& b) const { return a > b; } +}; +struct AnyLe { + template + bool operator()(const A& a, const B& b) const { return a <= b; } +}; +struct AnyGe { + template + bool operator()(const A& a, const B& b) const { return a >= b; } +}; + +// A match result listener that ignores the explanation. +class DummyMatchResultListener : public MatchResultListener { + public: + DummyMatchResultListener() : MatchResultListener(nullptr) {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener); +}; + +// A match result listener that forwards the explanation to a given +// ostream. The difference between this and MatchResultListener is +// that the former is concrete. +class StreamMatchResultListener : public MatchResultListener { + public: + explicit StreamMatchResultListener(::std::ostream* os) + : MatchResultListener(os) {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener); +}; + +// An internal class for implementing Matcher, which will derive +// from it. We put functionalities common to all Matcher +// specializations here to avoid code duplication. +template +class MatcherBase { + public: + // Returns true if and only if the matcher matches x; also explains the + // match result to 'listener'. + bool MatchAndExplain(const T& x, MatchResultListener* listener) const { + return impl_->MatchAndExplain(x, listener); + } + + // Returns true if and only if this matcher matches x. + bool Matches(const T& x) const { + DummyMatchResultListener dummy; + return MatchAndExplain(x, &dummy); + } + + // Describes this matcher to an ostream. + void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } + + // Describes the negation of this matcher to an ostream. + void DescribeNegationTo(::std::ostream* os) const { + impl_->DescribeNegationTo(os); + } + + // Explains why x matches, or doesn't match, the matcher. + void ExplainMatchResultTo(const T& x, ::std::ostream* os) const { + StreamMatchResultListener listener(os); + MatchAndExplain(x, &listener); + } + + // Returns the describer for this matcher object; retains ownership + // of the describer, which is only guaranteed to be alive when + // this matcher object is alive. + const MatcherDescriberInterface* GetDescriber() const { + return impl_.get(); + } + + protected: + MatcherBase() {} + + // Constructs a matcher from its implementation. + explicit MatcherBase(const MatcherInterface* impl) : impl_(impl) {} + + template + explicit MatcherBase( + const MatcherInterface* impl, + typename std::enable_if::value>::type* = + nullptr) + : impl_(new internal::MatcherInterfaceAdapter(impl)) {} + + MatcherBase(const MatcherBase&) = default; + MatcherBase& operator=(const MatcherBase&) = default; + MatcherBase(MatcherBase&&) = default; + MatcherBase& operator=(MatcherBase&&) = default; + + virtual ~MatcherBase() {} + + private: + std::shared_ptr> impl_; +}; + +} // namespace internal + +// A Matcher is a copyable and IMMUTABLE (except by assignment) +// object that can check whether a value of type T matches. The +// implementation of Matcher is just a std::shared_ptr to const +// MatcherInterface. Don't inherit from Matcher! +template +class Matcher : public internal::MatcherBase { + public: + // Constructs a null matcher. Needed for storing Matcher objects in STL + // containers. A default-constructed matcher is not yet initialized. You + // cannot use it until a valid value has been assigned to it. + explicit Matcher() {} // NOLINT + + // Constructs a matcher from its implementation. + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + template + explicit Matcher( + const MatcherInterface* impl, + typename std::enable_if::value>::type* = + nullptr) + : internal::MatcherBase(impl) {} + + // Implicit constructor here allows people to write + // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes + Matcher(T value); // NOLINT +}; + +// The following two specializations allow the user to write str +// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string +// matcher is expected. +template <> +class GTEST_API_ Matcher + : public internal::MatcherBase { + public: + Matcher() {} + + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a std::string object. + Matcher(const std::string& s); // NOLINT + + // Allows the user to write "foo" instead of Eq("foo") sometimes. + Matcher(const char* s); // NOLINT +}; + +template <> +class GTEST_API_ Matcher + : public internal::MatcherBase { + public: + Matcher() {} + + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a string object. + Matcher(const std::string& s); // NOLINT + + // Allows the user to write "foo" instead of Eq("foo") sometimes. + Matcher(const char* s); // NOLINT +}; + +#if GTEST_HAS_ABSL +// The following two specializations allow the user to write str +// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view +// matcher is expected. +template <> +class GTEST_API_ Matcher + : public internal::MatcherBase { + public: + Matcher() {} + + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a std::string object. + Matcher(const std::string& s); // NOLINT + + // Allows the user to write "foo" instead of Eq("foo") sometimes. + Matcher(const char* s); // NOLINT + + // Allows the user to pass absl::string_views directly. + Matcher(absl::string_view s); // NOLINT +}; + +template <> +class GTEST_API_ Matcher + : public internal::MatcherBase { + public: + Matcher() {} + + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a std::string object. + Matcher(const std::string& s); // NOLINT + + // Allows the user to write "foo" instead of Eq("foo") sometimes. + Matcher(const char* s); // NOLINT + + // Allows the user to pass absl::string_views directly. + Matcher(absl::string_view s); // NOLINT +}; +#endif // GTEST_HAS_ABSL + +// Prints a matcher in a human-readable format. +template +std::ostream& operator<<(std::ostream& os, const Matcher& matcher) { + matcher.DescribeTo(&os); + return os; +} + +// The PolymorphicMatcher class template makes it easy to implement a +// polymorphic matcher (i.e. a matcher that can match values of more +// than one type, e.g. Eq(n) and NotNull()). +// +// To define a polymorphic matcher, a user should provide an Impl +// class that has a DescribeTo() method and a DescribeNegationTo() +// method, and define a member function (or member function template) +// +// bool MatchAndExplain(const Value& value, +// MatchResultListener* listener) const; +// +// See the definition of NotNull() for a complete example. +template +class PolymorphicMatcher { + public: + explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {} + + // Returns a mutable reference to the underlying matcher + // implementation object. + Impl& mutable_impl() { return impl_; } + + // Returns an immutable reference to the underlying matcher + // implementation object. + const Impl& impl() const { return impl_; } + + template + operator Matcher() const { + return Matcher(new MonomorphicImpl(impl_)); + } + + private: + template + class MonomorphicImpl : public MatcherInterface { + public: + explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} + + virtual void DescribeTo(::std::ostream* os) const { impl_.DescribeTo(os); } + + virtual void DescribeNegationTo(::std::ostream* os) const { + impl_.DescribeNegationTo(os); + } + + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + return impl_.MatchAndExplain(x, listener); + } + + private: + const Impl impl_; + }; + + Impl impl_; +}; + +// Creates a matcher from its implementation. +// DEPRECATED: Especially in the generic code, prefer: +// Matcher(new MyMatcherImpl(...)); +// +// MakeMatcher may create a Matcher that accepts its argument by value, which +// leads to unnecessary copies & lack of support for non-copyable types. +template +inline Matcher MakeMatcher(const MatcherInterface* impl) { + return Matcher(impl); +} + +// Creates a polymorphic matcher from its implementation. This is +// easier to use than the PolymorphicMatcher constructor as it +// doesn't require you to explicitly write the template argument, e.g. +// +// MakePolymorphicMatcher(foo); +// vs +// PolymorphicMatcher(foo); +template +inline PolymorphicMatcher MakePolymorphicMatcher(const Impl& impl) { + return PolymorphicMatcher(impl); +} + +namespace internal { +// Implements a matcher that compares a given value with a +// pre-supplied value using one of the ==, <=, <, etc, operators. The +// two values being compared don't have to have the same type. +// +// The matcher defined here is polymorphic (for example, Eq(5) can be +// used to match an int, a short, a double, etc). Therefore we use +// a template type conversion operator in the implementation. +// +// The following template definition assumes that the Rhs parameter is +// a "bare" type (i.e. neither 'const T' nor 'T&'). +template +class ComparisonBase { + public: + explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} + template + operator Matcher() const { + return Matcher(new Impl(rhs_)); + } + + private: + template + static const T& Unwrap(const T& v) { return v; } + template + static const T& Unwrap(std::reference_wrapper v) { return v; } + + template + class Impl : public MatcherInterface { + public: + explicit Impl(const Rhs& rhs) : rhs_(rhs) {} + bool MatchAndExplain(Lhs lhs, + MatchResultListener* /* listener */) const override { + return Op()(lhs, Unwrap(rhs_)); + } + void DescribeTo(::std::ostream* os) const override { + *os << D::Desc() << " "; + UniversalPrint(Unwrap(rhs_), os); + } + void DescribeNegationTo(::std::ostream* os) const override { + *os << D::NegatedDesc() << " "; + UniversalPrint(Unwrap(rhs_), os); + } + + private: + Rhs rhs_; + }; + Rhs rhs_; +}; + +template +class EqMatcher : public ComparisonBase, Rhs, AnyEq> { + public: + explicit EqMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyEq>(rhs) { } + static const char* Desc() { return "is equal to"; } + static const char* NegatedDesc() { return "isn't equal to"; } +}; +template +class NeMatcher : public ComparisonBase, Rhs, AnyNe> { + public: + explicit NeMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyNe>(rhs) { } + static const char* Desc() { return "isn't equal to"; } + static const char* NegatedDesc() { return "is equal to"; } +}; +template +class LtMatcher : public ComparisonBase, Rhs, AnyLt> { + public: + explicit LtMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyLt>(rhs) { } + static const char* Desc() { return "is <"; } + static const char* NegatedDesc() { return "isn't <"; } +}; +template +class GtMatcher : public ComparisonBase, Rhs, AnyGt> { + public: + explicit GtMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyGt>(rhs) { } + static const char* Desc() { return "is >"; } + static const char* NegatedDesc() { return "isn't >"; } +}; +template +class LeMatcher : public ComparisonBase, Rhs, AnyLe> { + public: + explicit LeMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyLe>(rhs) { } + static const char* Desc() { return "is <="; } + static const char* NegatedDesc() { return "isn't <="; } +}; +template +class GeMatcher : public ComparisonBase, Rhs, AnyGe> { + public: + explicit GeMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyGe>(rhs) { } + static const char* Desc() { return "is >="; } + static const char* NegatedDesc() { return "isn't >="; } +}; + +// Implements polymorphic matchers MatchesRegex(regex) and +// ContainsRegex(regex), which can be used as a Matcher as long as +// T can be converted to a string. +class MatchesRegexMatcher { + public: + MatchesRegexMatcher(const RE* regex, bool full_match) + : regex_(regex), full_match_(full_match) {} + +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + return MatchAndExplain(std::string(s), listener); + } +#endif // GTEST_HAS_ABSL + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(std::string(s), listener); + } + + // Matches anything that can convert to std::string. + // + // This is a template, not just a plain function with const std::string&, + // because absl::string_view has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const std::string& s2(s); + return full_match_ ? RE::FullMatch(s2, *regex_) + : RE::PartialMatch(s2, *regex_); + } + + void DescribeTo(::std::ostream* os) const { + *os << (full_match_ ? "matches" : "contains") << " regular expression "; + UniversalPrinter::Print(regex_->pattern(), os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't " << (full_match_ ? "match" : "contain") + << " regular expression "; + UniversalPrinter::Print(regex_->pattern(), os); + } + + private: + const std::shared_ptr regex_; + const bool full_match_; +}; +} // namespace internal + +// Matches a string that fully matches regular expression 'regex'. +// The matcher takes ownership of 'regex'. +inline PolymorphicMatcher MatchesRegex( + const internal::RE* regex) { + return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true)); +} +inline PolymorphicMatcher MatchesRegex( + const std::string& regex) { + return MatchesRegex(new internal::RE(regex)); +} + +// Matches a string that contains regular expression 'regex'. +// The matcher takes ownership of 'regex'. +inline PolymorphicMatcher ContainsRegex( + const internal::RE* regex) { + return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false)); +} +inline PolymorphicMatcher ContainsRegex( + const std::string& regex) { + return ContainsRegex(new internal::RE(regex)); +} + +// Creates a polymorphic matcher that matches anything equal to x. +// Note: if the parameter of Eq() were declared as const T&, Eq("foo") +// wouldn't compile. +template +inline internal::EqMatcher Eq(T x) { return internal::EqMatcher(x); } + +// Constructs a Matcher from a 'value' of type T. The constructed +// matcher matches any value that's equal to 'value'. +template +Matcher::Matcher(T value) { *this = Eq(value); } + +// Creates a monomorphic matcher that matches anything with type Lhs +// and equal to rhs. A user may need to use this instead of Eq(...) +// in order to resolve an overloading ambiguity. +// +// TypedEq(x) is just a convenient short-hand for Matcher(Eq(x)) +// or Matcher(x), but more readable than the latter. +// +// We could define similar monomorphic matchers for other comparison +// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do +// it yet as those are used much less than Eq() in practice. A user +// can always write Matcher(Lt(5)) to be explicit about the type, +// for example. +template +inline Matcher TypedEq(const Rhs& rhs) { return Eq(rhs); } + +// Creates a polymorphic matcher that matches anything >= x. +template +inline internal::GeMatcher Ge(Rhs x) { + return internal::GeMatcher(x); +} + +// Creates a polymorphic matcher that matches anything > x. +template +inline internal::GtMatcher Gt(Rhs x) { + return internal::GtMatcher(x); +} + +// Creates a polymorphic matcher that matches anything <= x. +template +inline internal::LeMatcher Le(Rhs x) { + return internal::LeMatcher(x); +} + +// Creates a polymorphic matcher that matches anything < x. +template +inline internal::LtMatcher Lt(Rhs x) { + return internal::LtMatcher(x); +} + +// Creates a polymorphic matcher that matches anything != x. +template +inline internal::NeMatcher Ne(Rhs x) { + return internal::NeMatcher(x); +} +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 + +#endif // GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ diff --git a/3rdparty/gtest/include/gtest/gtest-message.h b/3rdparty/gtest/include/gtest/gtest-message.h new file mode 100644 index 0000000..4a80e11 --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest-message.h @@ -0,0 +1,218 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include +#include + +#include "gtest/internal/gtest-port.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +// Ensures that there is at least one operator<< in the global namespace. +// See Message& operator<<(...) below for why. +void operator<<(const testing::internal::Secret&, int); + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +// 1. You stream a bunch of values to a Message object. +// It will remember the text in a stringstream. +// 2. Then you stream the Message object to an ostream. +// This causes the text in the Message to be streamed +// to the ostream. +// +// For example; +// +// testing::Message foo; +// foo << 1 << " != " << 2; +// std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from. In particular, its +// destructor is not virtual. +// +// Note that stringstream behaves differently in gcc and in MSVC. You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do). The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class GTEST_API_ Message { + private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: + // Constructs an empty Message. + Message(); + + // Copy constructor. + Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT + *ss_ << msg.GetString(); + } + + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new ::std::stringstream) { + *ss_ << str; + } + + // Streams a non-pointer value to this object. + template + inline Message& operator <<(const T& val) { + // Some libraries overload << for STL containers. These + // overloads are defined in the global namespace instead of ::std. + // + // C++'s symbol lookup rule (i.e. Koenig lookup) says that these + // overloads are visible in either the std namespace or the global + // namespace, but not other namespaces, including the testing + // namespace which Google Test's Message class is in. + // + // To allow STL containers (and other types that has a << operator + // defined in the global namespace) to be used in Google Test + // assertions, testing::Message must access the custom << operator + // from the global namespace. With this using declaration, + // overloads of << defined in the global namespace and those + // visible via Koenig lookup are both exposed in this function. + using ::operator <<; + *ss_ << val; + return *this; + } + + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template + inline Message& operator <<(T* const& pointer) { // NOLINT + if (pointer == nullptr) { + *ss_ << "(null)"; + } else { + *ss_ << pointer; + } + return *this; + } + + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator <<(BasicNarrowIoManip val) { + *ss_ << val; + return *this; + } + + // Instead of 1/0, we want to see true/false for bool values. + Message& operator <<(bool b) { + return *this << (b ? "true" : "false"); + } + + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator <<(const wchar_t* wide_c_str); + Message& operator <<(wchar_t* wide_c_str); + +#if GTEST_HAS_STD_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::std::wstring& wstr); +#endif // GTEST_HAS_STD_WSTRING + + // Gets the text streamed to this object so far as an std::string. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + std::string GetString() const; + + private: + // We'll hold the text streamed to this object here. + const std::unique_ptr< ::std::stringstream> ss_; + + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { + return os << sb.GetString(); +} + +namespace internal { + +// Converts a streamable value to an std::string. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +template +std::string StreamableToString(const T& streamable) { + return (Message() << streamable).GetString(); +} + +} // namespace internal +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ diff --git a/3rdparty/gtest/include/gtest/gtest-param-test.h b/3rdparty/gtest/include/gtest/gtest-param-test.h new file mode 100644 index 0000000..c2e6eae --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest-param-test.h @@ -0,0 +1,503 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing and Mocking Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// GOOGLETEST_CM0001 DO NOT DELETE +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test suite +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_SUITE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more than once) the first argument to the +// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the +// actual test suite name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests +// in the given test suite, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_SUITE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} + +#endif // 0 + +#include +#include + +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-port.h" + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test suite is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test suite FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template +internal::ParamGenerator Range(T start, T end, IncrementT step) { + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); +} + +template +internal::ParamGenerator Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test suite StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings)); +// +// This instantiates tests from test suite StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_SUITE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list GetParameterChars() { +// ::std::list list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list l = GetParameterChars(); +// INSTANTIATE_TEST_SUITE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template +internal::ParamGenerator< + typename std::iterator_traits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename std::iterator_traits::value_type ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); +} + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template +internal::ParamGenerator ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test suite BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_SUITE_P(NumSequence, +// BarTest, +// Values("one", "two", "three")); +// +// This instantiates tests from test suite BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// +template +internal::ValueArray Values(T... v) { + return internal::ValueArray(std::move(v)...); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test suite FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator Bool() { + return Values(false, true); +} + +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// std::tuple where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. +// +// Example: +// +// This will instantiate tests in test suite AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// std::tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +template +internal::CartesianProductHolder Combine(const Generator&... g) { + return internal::CartesianProductHolder(g...); +} + +#define TEST_P(test_suite_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ + : public test_suite_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ + virtual void TestBody(); \ + \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance() \ + ->parameterized_test_registry() \ + .GetTestSuitePatternHolder( \ + #test_suite_name, \ + ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ + ->AddTestPattern( \ + GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name), \ + new ::testing::internal::TestMetaFactory()); \ + return 0; \ + } \ + static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() + +// The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify +// generator and an optional function or functor that generates custom test name +// suffixes based on the test parameters. Such a function or functor should +// accept one argument of type testing::TestParamInfo, and +// return std::string. +// +// testing::PrintToStringParamName is a builtin test suffix generator that +// returns the value of testing::PrintToString(GetParam()). +// +// Note: test names must be non-empty, unique, and may only contain ASCII +// alphanumeric characters or underscore. Because PrintToString adds quotes +// to std::string and C strings, it won't work for these types. + +#define GTEST_EXPAND_(arg) arg +#define GTEST_GET_FIRST_(first, ...) first +#define GTEST_GET_SECOND_(first, second, ...) second + +#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \ + static ::testing::internal::ParamGenerator \ + gtest_##prefix##test_suite_name##_EvalGenerator_() { \ + return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \ + } \ + static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \ + const ::testing::TestParamInfo& info) { \ + if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \ + __VA_ARGS__, \ + ::testing::internal::DefaultParamName, \ + DUMMY_PARAM_))); \ + auto t = std::make_tuple(__VA_ARGS__); \ + static_assert(std::tuple_size::value <= 2, \ + "Too Many Args!"); \ + } \ + return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \ + __VA_ARGS__, \ + ::testing::internal::DefaultParamName, \ + DUMMY_PARAM_))))(info); \ + } \ + static int gtest_##prefix##test_suite_name##_dummy_ \ + GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::UnitTest::GetInstance() \ + ->parameterized_test_registry() \ + .GetTestSuitePatternHolder( \ + #test_suite_name, \ + ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ + ->AddTestSuiteInstantiation( \ + #prefix, >est_##prefix##test_suite_name##_EvalGenerator_, \ + >est_##prefix##test_suite_name##_EvalGenerateName_, \ + __FILE__, __LINE__) + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +#define INSTANTIATE_TEST_CASE_P \ + static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \ + ""); \ + INSTANTIATE_TEST_SUITE_P +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/3rdparty/gtest/include/gtest/gtest-printers.h b/3rdparty/gtest/include/gtest/gtest-printers.h new file mode 100644 index 0000000..56a0545 --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest-printers.h @@ -0,0 +1,928 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Test - The Google C++ Testing and Mocking Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// A user can teach this function how to print a class type T by +// defining either operator<<() or PrintTo() in the namespace that +// defines T. More specifically, the FIRST defined function in the +// following list will be used (assuming T is defined in namespace +// foo): +// +// 1. foo::PrintTo(const T&, ostream*) +// 2. operator<<(ostream&, const T&) defined in either foo or the +// global namespace. +// +// However if T is an STL-style container then it is printed element-wise +// unless foo::PrintTo(const T&, ostream*) is defined. Note that +// operator<<() is ignored for container types. +// +// If none of the above is defined, it will print the debug string of +// the value if it is a protocol buffer, or print the raw bytes in the +// value otherwise. +// +// To aid debugging: when T is a reference type, the address of the +// value is also printed; when T is a (const) char pointer, both the +// pointer value and the NUL-terminated string it points to are +// printed. +// +// We also provide some convenient wrappers: +// +// // Prints a value to a string. For a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// std::string ::testing::PrintToString(const T& value); +// +// // Prints a value tersely: for a reference type, the referenced +// // value (but not the address) is printed; for a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// void ::testing::internal::UniversalTersePrint(const T& value, ostream*); +// +// // Prints value using the type inferred by the compiler. The difference +// // from UniversalTersePrint() is that this function prints both the +// // pointer and the NUL-terminated string for a (const or not) char pointer. +// void ::testing::internal::UniversalPrint(const T& value, ostream*); +// +// // Prints the fields of a tuple tersely to a string vector, one +// // element for each field. Tuple support must be enabled in +// // gtest-port.h. +// std::vector UniversalTersePrintTupleFieldsToStrings( +// const Tuple& value); +// +// Known limitation: +// +// The print primitives print the elements of an STL-style container +// using the compiler-inferred type of *iter where iter is a +// const_iterator of the container. When const_iterator is an input +// iterator but not a forward iterator, this inferred type may not +// match value_type, and the print output may be incorrect. In +// practice, this is rarely a problem as for most containers +// const_iterator is a forward iterator. We'll fix this if there's an +// actual need for it. Note that this fix cannot rely on value_type +// being defined as many user-defined container types don't have +// value_type. + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ + +#include +#include // NOLINT +#include +#include +#include +#include +#include +#include +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_ABSL +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "absl/types/variant.h" +#endif // GTEST_HAS_ABSL + +namespace testing { + +// Definitions in the 'internal' and 'internal2' name spaces are +// subject to change without notice. DO NOT USE THEM IN USER CODE! +namespace internal2 { + +// Prints the given number of bytes in the given object to the given +// ostream. +GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, + size_t count, + ::std::ostream* os); + +// For selecting which printer to use when a given type has neither << +// nor PrintTo(). +enum TypeKind { + kProtobuf, // a protobuf type + kConvertibleToInteger, // a type implicitly convertible to BiggestInt + // (e.g. a named or unnamed enum type) +#if GTEST_HAS_ABSL + kConvertibleToStringView, // a type implicitly convertible to + // absl::string_view +#endif + kOtherType // anything else +}; + +// TypeWithoutFormatter::PrintValue(value, os) is called +// by the universal printer to print a value of type T when neither +// operator<< nor PrintTo() is defined for T, where kTypeKind is the +// "kind" of T as defined by enum TypeKind. +template +class TypeWithoutFormatter { + public: + // This default version is called when kTypeKind is kOtherType. + static void PrintValue(const T& value, ::std::ostream* os) { + PrintBytesInObjectTo( + static_cast( + reinterpret_cast(std::addressof(value))), + sizeof(value), os); + } +}; + +// We print a protobuf using its ShortDebugString() when the string +// doesn't exceed this many characters; otherwise we print it using +// DebugString() for better readability. +const size_t kProtobufOneLinerMaxLength = 50; + +template +class TypeWithoutFormatter { + public: + static void PrintValue(const T& value, ::std::ostream* os) { + std::string pretty_str = value.ShortDebugString(); + if (pretty_str.length() > kProtobufOneLinerMaxLength) { + pretty_str = "\n" + value.DebugString(); + } + *os << ("<" + pretty_str + ">"); + } +}; + +template +class TypeWithoutFormatter { + public: + // Since T has no << operator or PrintTo() but can be implicitly + // converted to BiggestInt, we print it as a BiggestInt. + // + // Most likely T is an enum type (either named or unnamed), in which + // case printing it as an integer is the desired behavior. In case + // T is not an enum, printing it as an integer is the best we can do + // given that it has no user-defined printer. + static void PrintValue(const T& value, ::std::ostream* os) { + const internal::BiggestInt kBigInt = value; + *os << kBigInt; + } +}; + +#if GTEST_HAS_ABSL +template +class TypeWithoutFormatter { + public: + // Since T has neither operator<< nor PrintTo() but can be implicitly + // converted to absl::string_view, we print it as a absl::string_view. + // + // Note: the implementation is further below, as it depends on + // internal::PrintTo symbol which is defined later in the file. + static void PrintValue(const T& value, ::std::ostream* os); +}; +#endif + +// Prints the given value to the given ostream. If the value is a +// protocol message, its debug string is printed; if it's an enum or +// of a type implicitly convertible to BiggestInt, it's printed as an +// integer; otherwise the bytes in the value are printed. This is +// what UniversalPrinter::Print() does when it knows nothing about +// type T and T has neither << operator nor PrintTo(). +// +// A user can override this behavior for a class type Foo by defining +// a << operator in the namespace where Foo is defined. +// +// We put this operator in namespace 'internal2' instead of 'internal' +// to simplify the implementation, as much code in 'internal' needs to +// use << in STL, which would conflict with our own << were it defined +// in 'internal'. +// +// Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream, const Foo&) is more +// specific. +template +::std::basic_ostream& operator<<( + ::std::basic_ostream& os, const T& x) { + TypeWithoutFormatter::value + ? kProtobuf + : std::is_convertible< + const T&, internal::BiggestInt>::value + ? kConvertibleToInteger + : +#if GTEST_HAS_ABSL + std::is_convertible< + const T&, absl::string_view>::value + ? kConvertibleToStringView + : +#endif + kOtherType)>::PrintValue(x, &os); + return os; +} + +} // namespace internal2 +} // namespace testing + +// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up +// magic needed for implementing UniversalPrinter won't work. +namespace testing_internal { + +// Used to print a value that is not an STL-style container when the +// user doesn't define PrintTo() for it. +template +void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { + // With the following statement, during unqualified name lookup, + // testing::internal2::operator<< appears as if it was declared in + // the nearest enclosing namespace that contains both + // ::testing_internal and ::testing::internal2, i.e. the global + // namespace. For more details, refer to the C++ Standard section + // 7.3.4-1 [namespace.udir]. This allows us to fall back onto + // testing::internal2::operator<< in case T doesn't come with a << + // operator. + // + // We cannot write 'using ::testing::internal2::operator<<;', which + // gcc 3.3 fails to compile due to a compiler bug. + using namespace ::testing::internal2; // NOLINT + + // Assuming T is defined in namespace foo, in the next statement, + // the compiler will consider all of: + // + // 1. foo::operator<< (thanks to Koenig look-up), + // 2. ::operator<< (as the current namespace is enclosed in ::), + // 3. testing::internal2::operator<< (thanks to the using statement above). + // + // The operator<< whose type matches T best will be picked. + // + // We deliberately allow #2 to be a candidate, as sometimes it's + // impossible to define #1 (e.g. when foo is ::std, defining + // anything in it is undefined behavior unless you are a compiler + // vendor.). + *os << value; +} + +} // namespace testing_internal + +namespace testing { +namespace internal { + +// FormatForComparison::Format(value) formats a +// value of type ToPrint that is an operand of a comparison assertion +// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in +// the comparison, and is used to help determine the best way to +// format the value. In particular, when the value is a C string +// (char pointer) and the other operand is an STL string object, we +// want to format the C string as a string, since we know it is +// compared by value with the string object. If the value is a char +// pointer but the other operand is not an STL string object, we don't +// know whether the pointer is supposed to point to a NUL-terminated +// string, and thus want to print it as a pointer to be safe. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// The default case. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint& value) { + return ::testing::PrintToString(value); + } +}; + +// Array. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint* value) { + return FormatForComparison::Format(value); + } +}; + +// By default, print C string as pointers to be safe, as we don't know +// whether they actually point to a NUL-terminated string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ + template \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(static_cast(value)); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ + +// If a C string is compared with an STL string object, we know it's meant +// to point to a NUL-terminated string, and thus can print it as a string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ + template <> \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(value); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); + +#if GTEST_HAS_STD_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); +#endif + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message. The type (but not value) +// of the other operand may affect the format. This allows us to +// print a char* as a raw pointer when it is compared against another +// char* or void*, and print it as a C string when it is compared +// against an std::string object, for example. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +std::string FormatForComparisonFailureMessage( + const T1& value, const T2& /* other_operand */) { + return FormatForComparison::Format(value); +} + +// UniversalPrinter::Print(value, ostream_ptr) prints the given +// value to the given ostream. The caller must ensure that +// 'ostream_ptr' is not NULL, or the behavior is undefined. +// +// We define UniversalPrinter as a class template (as opposed to a +// function template), as we need to partially specialize it for +// reference types, which cannot be done with function templates. +template +class UniversalPrinter; + +template +void UniversalPrint(const T& value, ::std::ostream* os); + +enum DefaultPrinterType { + kPrintContainer, + kPrintPointer, + kPrintFunctionPointer, + kPrintOther, +}; +template struct WrapPrinterType {}; + +// Used to print an STL-style container when the user doesn't define +// a PrintTo() for it. +template +void DefaultPrintTo(WrapPrinterType /* dummy */, + const C& container, ::std::ostream* os) { + const size_t kMaxCount = 32; // The maximum number of elements to print. + *os << '{'; + size_t count = 0; + for (typename C::const_iterator it = container.begin(); + it != container.end(); ++it, ++count) { + if (count > 0) { + *os << ','; + if (count == kMaxCount) { // Enough has been printed. + *os << " ..."; + break; + } + } + *os << ' '; + // We cannot call PrintTo(*it, os) here as PrintTo() doesn't + // handle *it being a native array. + internal::UniversalPrint(*it, os); + } + + if (count > 0) { + *os << ' '; + } + *os << '}'; +} + +// Used to print a pointer that is neither a char pointer nor a member +// pointer, when the user doesn't define PrintTo() for it. (A member +// variable pointer or member function pointer doesn't really point to +// a location in the address space. Their representation is +// implementation-defined. Therefore they will be printed as raw +// bytes.) +template +void DefaultPrintTo(WrapPrinterType /* dummy */, + T* p, ::std::ostream* os) { + if (p == nullptr) { + *os << "NULL"; + } else { + // T is not a function type. We just call << to print p, + // relying on ADL to pick up user-defined << for their pointer + // types, if any. + *os << p; + } +} +template +void DefaultPrintTo(WrapPrinterType /* dummy */, + T* p, ::std::ostream* os) { + if (p == nullptr) { + *os << "NULL"; + } else { + // T is a function type, so '*os << p' doesn't do what we want + // (it just prints p as bool). We want to print p as a const + // void*. + *os << reinterpret_cast(p); + } +} + +// Used to print a non-container, non-pointer value when the user +// doesn't define PrintTo() for it. +template +void DefaultPrintTo(WrapPrinterType /* dummy */, + const T& value, ::std::ostream* os) { + ::testing_internal::DefaultPrintNonContainerTo(value, os); +} + +// Prints the given value using the << operator if it has one; +// otherwise prints the bytes in it. This is what +// UniversalPrinter::Print() does when PrintTo() is not specialized +// or overloaded for type T. +// +// A user can override this behavior for a class type Foo by defining +// an overload of PrintTo() in the namespace where Foo is defined. We +// give the user this option as sometimes defining a << operator for +// Foo is not desirable (e.g. the coding style may prevent doing it, +// or there is already a << operator but it doesn't do what the user +// wants). +template +void PrintTo(const T& value, ::std::ostream* os) { + // DefaultPrintTo() is overloaded. The type of its first argument + // determines which version will be picked. + // + // Note that we check for container types here, prior to we check + // for protocol message types in our operator<<. The rationale is: + // + // For protocol messages, we want to give people a chance to + // override Google Mock's format by defining a PrintTo() or + // operator<<. For STL containers, other formats can be + // incompatible with Google Mock's format for the container + // elements; therefore we check for container types here to ensure + // that our format is used. + // + // Note that MSVC and clang-cl do allow an implicit conversion from + // pointer-to-function to pointer-to-object, but clang-cl warns on it. + // So don't use ImplicitlyConvertible if it can be helped since it will + // cause this warning, and use a separate overload of DefaultPrintTo for + // function pointers so that the `*os << p` in the object pointer overload + // doesn't cause that warning either. + DefaultPrintTo( + WrapPrinterType < + (sizeof(IsContainerTest(0)) == sizeof(IsContainer)) && + !IsRecursiveContainer::value + ? kPrintContainer + : !std::is_pointer::value + ? kPrintOther + : std::is_function::type>::value + ? kPrintFunctionPointer + : kPrintPointer > (), + value, os); +} + +// The following list of PrintTo() overloads tells +// UniversalPrinter::Print() how to print standard types (built-in +// types, strings, plain arrays, and pointers). + +// Overloads for various char types. +GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); +GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); +inline void PrintTo(char c, ::std::ostream* os) { + // When printing a plain char, we always treat it as unsigned. This + // way, the output won't be affected by whether the compiler thinks + // char is signed or not. + PrintTo(static_cast(c), os); +} + +// Overloads for other simple built-in types. +inline void PrintTo(bool x, ::std::ostream* os) { + *os << (x ? "true" : "false"); +} + +// Overload for wchar_t type. +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its decimal code (except for L'\0'). +// The L'\0' char is printed as "L'\\0'". The decimal code is printed +// as signed integer when wchar_t is implemented by the compiler +// as a signed type and is printed as an unsigned integer when wchar_t +// is implemented as an unsigned type. +GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); + +// Overloads for C strings. +GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); +inline void PrintTo(char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// signed/unsigned char is often used for representing binary data, so +// we print pointers to it as void* to be safe. +inline void PrintTo(const signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(const unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// MSVC can be configured to define wchar_t as a typedef of unsigned +// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native +// type. When wchar_t is a typedef, defining an overload for const +// wchar_t* would cause unsigned short* be printed as a wide string, +// possibly causing invalid memory accesses. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Overloads for wide C strings +GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); +inline void PrintTo(wchar_t* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +#endif + +// Overload for C arrays. Multi-dimensional arrays are printed +// properly. + +// Prints the given number of elements in an array, without printing +// the curly braces. +template +void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { + UniversalPrint(a[0], os); + for (size_t i = 1; i != count; i++) { + *os << ", "; + UniversalPrint(a[i], os); + } +} + +// Overloads for ::std::string. +GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); +inline void PrintTo(const ::std::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} + +// Overloads for ::std::wstring. +#if GTEST_HAS_STD_WSTRING +GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_ABSL +// Overload for absl::string_view. +inline void PrintTo(absl::string_view sp, ::std::ostream* os) { + PrintTo(::std::string(sp), os); +} +#endif // GTEST_HAS_ABSL + +inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; } + +template +void PrintTo(std::reference_wrapper ref, ::std::ostream* os) { + UniversalPrinter::Print(ref.get(), os); +} + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T&, std::integral_constant, + ::std::ostream*) {} + +template +void PrintTupleTo(const T& t, std::integral_constant, + ::std::ostream* os) { + PrintTupleTo(t, std::integral_constant(), os); + GTEST_INTENTIONAL_CONST_COND_PUSH_() + if (I > 1) { + GTEST_INTENTIONAL_CONST_COND_POP_() + *os << ", "; + } + UniversalPrinter::type>::Print( + std::get(t), os); +} + +template +void PrintTo(const ::std::tuple& t, ::std::ostream* os) { + *os << "("; + PrintTupleTo(t, std::integral_constant(), os); + *os << ")"; +} + +// Overload for std::pair. +template +void PrintTo(const ::std::pair& value, ::std::ostream* os) { + *os << '('; + // We cannot use UniversalPrint(value.first, os) here, as T1 may be + // a reference type. The same for printing value.second. + UniversalPrinter::Print(value.first, os); + *os << ", "; + UniversalPrinter::Print(value.second, os); + *os << ')'; +} + +// Implements printing a non-reference type T by letting the compiler +// pick the right overload of PrintTo() for T. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) + + // Note: we deliberately don't call this PrintTo(), as that name + // conflicts with ::testing::internal::PrintTo in the body of the + // function. + static void Print(const T& value, ::std::ostream* os) { + // By default, ::testing::internal::PrintTo() is used for printing + // the value. + // + // Thanks to Koenig look-up, if T is a class and has its own + // PrintTo() function defined in its namespace, that function will + // be visible here. Since it is more specific than the generic ones + // in ::testing::internal, it will be picked by the compiler in the + // following statement - exactly what we want. + PrintTo(value, os); + } + + GTEST_DISABLE_MSC_WARNINGS_POP_() +}; + +#if GTEST_HAS_ABSL + +// Printer for absl::optional + +template +class UniversalPrinter<::absl::optional> { + public: + static void Print(const ::absl::optional& value, ::std::ostream* os) { + *os << '('; + if (!value) { + *os << "nullopt"; + } else { + UniversalPrint(*value, os); + } + *os << ')'; + } +}; + +// Printer for absl::variant + +template +class UniversalPrinter<::absl::variant> { + public: + static void Print(const ::absl::variant& value, ::std::ostream* os) { + *os << '('; + absl::visit(Visitor{os}, value); + *os << ')'; + } + + private: + struct Visitor { + template + void operator()(const U& u) const { + *os << "'" << GetTypeName() << "' with value "; + UniversalPrint(u, os); + } + ::std::ostream* os; + }; +}; + +#endif // GTEST_HAS_ABSL + +// UniversalPrintArray(begin, len, os) prints an array of 'len' +// elements, starting at address 'begin'. +template +void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { + if (len == 0) { + *os << "{}"; + } else { + *os << "{ "; + const size_t kThreshold = 18; + const size_t kChunkSize = 8; + // If the array has more than kThreshold elements, we'll have to + // omit some details by printing only the first and the last + // kChunkSize elements. + if (len <= kThreshold) { + PrintRawArrayTo(begin, len, os); + } else { + PrintRawArrayTo(begin, kChunkSize, os); + *os << ", ..., "; + PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); + } + *os << " }"; + } +} +// This overload prints a (const) char array compactly. +GTEST_API_ void UniversalPrintArray( + const char* begin, size_t len, ::std::ostream* os); + +// This overload prints a (const) wchar_t array compactly. +GTEST_API_ void UniversalPrintArray( + const wchar_t* begin, size_t len, ::std::ostream* os); + +// Implements printing an array type T[N]. +template +class UniversalPrinter { + public: + // Prints the given array, omitting some elements when there are too + // many. + static void Print(const T (&a)[N], ::std::ostream* os) { + UniversalPrintArray(a, N, os); + } +}; + +// Implements printing a reference type T&. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) + + static void Print(const T& value, ::std::ostream* os) { + // Prints the address of the value. We use reinterpret_cast here + // as static_cast doesn't compile when T is a function type. + *os << "@" << reinterpret_cast(&value) << " "; + + // Then prints the value itself. + UniversalPrint(value, os); + } + + GTEST_DISABLE_MSC_WARNINGS_POP_() +}; + +// Prints a value tersely: for a reference type, the referenced value +// (but not the address) is printed; for a (const) char pointer, the +// NUL-terminated string (but not the pointer) is printed. + +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T (&value)[N], ::std::ostream* os) { + UniversalPrinter::Print(value, os); + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(const char* str, ::std::ostream* os) { + if (str == nullptr) { + *os << "NULL"; + } else { + UniversalPrint(std::string(str), os); + } + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(char* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +#if GTEST_HAS_STD_WSTRING +template <> +class UniversalTersePrinter { + public: + static void Print(const wchar_t* str, ::std::ostream* os) { + if (str == nullptr) { + *os << "NULL"; + } else { + UniversalPrint(::std::wstring(str), os); + } + } +}; +#endif + +template <> +class UniversalTersePrinter { + public: + static void Print(wchar_t* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +template +void UniversalTersePrint(const T& value, ::std::ostream* os) { + UniversalTersePrinter::Print(value, os); +} + +// Prints a value using the type inferred by the compiler. The +// difference between this and UniversalTersePrint() is that for a +// (const) char pointer, this prints both the pointer and the +// NUL-terminated string. +template +void UniversalPrint(const T& value, ::std::ostream* os) { + // A workarond for the bug in VC++ 7.1 that prevents us from instantiating + // UniversalPrinter with T directly. + typedef T T1; + UniversalPrinter::Print(value, os); +} + +typedef ::std::vector< ::std::string> Strings; + + // Tersely prints the first N fields of a tuple to a string vector, + // one element for each field. +template +void TersePrintPrefixToStrings(const Tuple&, std::integral_constant, + Strings*) {} +template +void TersePrintPrefixToStrings(const Tuple& t, + std::integral_constant, + Strings* strings) { + TersePrintPrefixToStrings(t, std::integral_constant(), + strings); + ::std::stringstream ss; + UniversalTersePrint(std::get(t), &ss); + strings->push_back(ss.str()); +} + +// Prints the fields of a tuple tersely to a string vector, one +// element for each field. See the comment before +// UniversalTersePrint() for how we define "tersely". +template +Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { + Strings result; + TersePrintPrefixToStrings( + value, std::integral_constant::value>(), + &result); + return result; +} + +} // namespace internal + +#if GTEST_HAS_ABSL +namespace internal2 { +template +void TypeWithoutFormatter::PrintValue( + const T& value, ::std::ostream* os) { + internal::PrintTo(absl::string_view(value), os); +} +} // namespace internal2 +#endif + +template +::std::string PrintToString(const T& value) { + ::std::stringstream ss; + internal::UniversalTersePrinter::Print(value, &ss); + return ss.str(); +} + +} // namespace testing + +// Include any custom printer added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +#include "gtest/internal/custom/gtest-printers.h" + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ diff --git a/3rdparty/gtest/include/gtest/gtest-spi.h b/3rdparty/gtest/include/gtest/gtest-spi.h new file mode 100644 index 0000000..aa38870 --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest-spi.h @@ -0,0 +1,238 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +// GOOGLETEST_CM0004 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include "gtest/gtest.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + ~ScopedFakeTestPartResultReporter() override; + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + void ReportTestPartResult(const TestPartResult& result) override; + + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, const std::string& substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const std::string substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/3rdparty/gtest/include/gtest/gtest-test-part.h b/3rdparty/gtest/include/gtest/gtest-test-part.h new file mode 100644 index 0000000..05a7985 --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest-test-part.h @@ -0,0 +1,184 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include +#include +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class GTEST_API_ TestPartResult { + public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure, // Failed and the test should be terminated. + kSkip // Skipped. + }; + + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, const char* a_file_name, int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name == nullptr ? "" : a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) {} + + // Gets the outcome of the test part. + Type type() const { return type_; } + + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const { + return file_name_.empty() ? nullptr : file_name_.c_str(); + } + + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } + + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } + + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } + + // Returns true if and only if the test part was skipped. + bool skipped() const { return type_ == kSkip; } + + // Returns true if and only if the test part passed. + bool passed() const { return type_ == kSuccess; } + + // Returns true if and only if the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + + // Returns true if and only if the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } + + // Returns true if and only if the test part failed. + bool failed() const { return fatally_failed() || nonfatally_failed(); } + + private: + Type type_; + + // Gets the summary of the failure message by omitting the stack + // trace in it. + static std::string ExtractSummary(const char* message); + + // The name of the source file where the test part took place, or + // "" if the source file is unknown. + std::string file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + std::string summary_; // The test failure summary. + std::string message_; // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class GTEST_API_ TestPartResultArray { + public: + TestPartResultArray() {} + + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); + + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; + + // Returns the number of TestPartResult objects in the array. + int size() const; + + private: + std::vector array_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class GTEST_API_ TestPartResultReporterInterface { + public: + virtual ~TestPartResultReporterInterface() {} + + virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { + public: + HasNewFatalFailureHelper(); + ~HasNewFatalFailureHelper() override; + void ReportTestPartResult(const TestPartResult& result) override; + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +} // namespace internal + +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ diff --git a/3rdparty/gtest/include/gtest/gtest-typed-test.h b/3rdparty/gtest/include/gtest/gtest-typed-test.h new file mode 100644 index 0000000..095ce05 --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest-typed-test.h @@ -0,0 +1,330 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list. You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + public: + ... + typedef std::list List; + static T shared_; + T value_; +}; + +// Next, associate a list of types with the test suite, which will be +// repeated for each type in the list. The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types MyTypes; +TYPED_TEST_SUITE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// TYPED_TEST_SUITE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test suite as you want. +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to the special name TypeParam to get the type + // parameter. Since we are inside a derived class template, C++ requires + // us to visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the TestFixture:: + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the "typename + // TestFixture::" prefix. + typename TestFixture::List values; + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +// TYPED_TEST_SUITE takes an optional third argument which allows to specify a +// class that generates custom test name suffixes based on the type. This should +// be a class which has a static template function GetName(int index) returning +// a string for each type. The provided integer index equals the index of the +// type in the provided type list. In many cases the index can be ignored. +// +// For example: +// class MyTypeNames { +// public: +// template +// static std::string GetName(int) { +// if (std::is_same()) return "char"; +// if (std::is_same()) return "int"; +// if (std::is_same()) return "unsignedInt"; +// } +// }; +// TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames); + +#endif // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type. Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are. The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have. Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly. Here's an example: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + ... +}; + +// Next, declare that you will define a type-parameterized test suite +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_SUITE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test suite as you want. +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them. The first argument of the macro is the +// test suite name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_SUITE_P(FooTest, + DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want. If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test suite name. Remember to pick unique prefixes for +// different instances. +typedef testing::Types MyTypes; +INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int); +// +// Similar to the optional argument of TYPED_TEST_SUITE above, +// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to +// generate custom names. +// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames); + +#endif // 0 + +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-type-util.h" + +// Implements typed tests. + +#if GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test suite. +#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_ + +// Expands to the name of the typedef for the NameGenerator, responsible for +// creating the suffixes of the name. +#define GTEST_NAME_GENERATOR_(TestSuiteName) \ + gtest_type_params_##TestSuiteName##_NameGenerator + +#define TYPED_TEST_SUITE(CaseName, Types, ...) \ + typedef ::testing::internal::TypeList::type GTEST_TYPE_PARAMS_( \ + CaseName); \ + typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \ + GTEST_NAME_GENERATOR_(CaseName) + +# define TYPED_TEST(CaseName, TestName) \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##CaseName##_##TestName##_registered_ \ + GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel, \ + GTEST_TYPE_PARAMS_( \ + CaseName)>::Register("", \ + ::testing::internal::CodeLocation( \ + __FILE__, __LINE__), \ + #CaseName, #TestName, 0, \ + ::testing::internal::GenerateNames< \ + GTEST_NAME_GENERATOR_(CaseName), \ + GTEST_TYPE_PARAMS_(CaseName)>()); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, \ + TestName)::TestBody() + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +#define TYPED_TEST_CASE \ + static_assert(::testing::internal::TypedTestCaseIsDeprecated(), ""); \ + TYPED_TEST_SUITE +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +#endif // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#if GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test suite are defined in. The exact +// name of the namespace is subject to change without notice. +#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test suite. +#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \ + gtest_typed_test_suite_p_state_##TestSuiteName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test suite. +#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \ + gtest_registered_test_names_##TestSuiteName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +#define TYPED_TEST_SUITE_P(SuiteName) \ + static ::testing::internal::TypedTestSuitePState \ + GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName) + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +#define TYPED_TEST_CASE_P \ + static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), ""); \ + TYPED_TEST_SUITE_P +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +#define TYPED_TEST_P(SuiteName, TestName) \ + namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ + template \ + class TestName : public SuiteName { \ + private: \ + typedef SuiteName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ + __FILE__, __LINE__, #SuiteName, #TestName); \ + } \ + template \ + void GTEST_SUITE_NAMESPACE_( \ + SuiteName)::TestName::TestBody() + +#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \ + namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_( \ + SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \ + __FILE__, __LINE__, #__VA_ARGS__) + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +#define REGISTER_TYPED_TEST_CASE_P \ + static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \ + ""); \ + REGISTER_TYPED_TEST_SUITE_P +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ + static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTestSuite< \ + SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ + ::testing::internal::TypeList::type>:: \ + Register(#Prefix, \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), #SuiteName, \ + GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ + ::testing::internal::GenerateNames< \ + ::testing::internal::NameGeneratorSelector< \ + __VA_ARGS__>::type, \ + ::testing::internal::TypeList::type>()) + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +#define INSTANTIATE_TYPED_TEST_CASE_P \ + static_assert( \ + ::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), ""); \ + INSTANTIATE_TYPED_TEST_SUITE_P +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ diff --git a/3rdparty/gtest/include/gtest/gtest.h b/3rdparty/gtest/include/gtest/gtest.h new file mode 100644 index 0000000..dbe5b1c --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest.h @@ -0,0 +1,2478 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This header file defines the public API for Google Test. It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +#include +#include +#include +#include +#include +#include + +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" +#include "gtest/gtest-death-test.h" +#include "gtest/gtest-matchers.h" +#include "gtest/gtest-message.h" +#include "gtest/gtest-param-test.h" +#include "gtest/gtest-printers.h" +#include "gtest/gtest_prod.h" +#include "gtest/gtest-test-part.h" +#include "gtest/gtest-typed-test.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { + +// Silence C4100 (unreferenced formal parameter) and 4805 +// unsafe mix of type 'const int' and type 'const bool' +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4805) +# pragma warning(disable:4100) +#endif + + +// Declares the flags. + +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag controls whether Google Test installs a signal handler that dumps +// debugging information when fatal signals are raised. +GTEST_DECLARE_bool_(install_failure_signal_handler); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flags control whether Google Test prints UTF8 characters as text. +GTEST_DECLARE_bool_(print_utf8); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. For use with an external test framework. +GTEST_DECLARE_bool_(throw_on_failure); + +// When this flag is set with a "host:port" string, on supported +// platforms test results are streamed to the specified port on +// the specified host machine. +GTEST_DECLARE_string_(stream_result_to); + +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +GTEST_DECLARE_string_(flagfile); +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +namespace internal { + +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; +class GTestFlagSaver; +class StreamingListenerTest; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class UnitTestRecordPropertyTestHelper; +class WindowsDeathTest; +class FuchsiaDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message); + +} // namespace internal + +// The friend relationship of some of these classes is cyclic. +// If we don't forward declare them the compiler might confuse the classes +// in friendship clauses with same named classes on the scope. +class Test; +class TestSuite; + +// Old API is still available but deprecated +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +using TestCase = TestSuite; +#endif +class TestInfo; +class UnitTest; + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + +#if defined(_MSC_VER) && _MSC_VER < 1910 + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) +#endif + + // Used in the EXPECT_TRUE/FALSE(bool_expression). + // + // T must be contextually convertible to bool. + // + // The second parameter prevents this overload from being considered if + // the argument is implicitly convertible to AssertionResult. In that case + // we want AssertionResult's copy constructor to be used. + template + explicit AssertionResult( + const T& success, + typename std::enable_if< + !std::is_convertible::value>::type* + /*enabler*/ + = nullptr) + : success_(success) {} + +#if defined(_MSC_VER) && _MSC_VER < 1910 + GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif + + // Assignment operator. + AssertionResult& operator=(AssertionResult other) { + swap(other); + return *this; + } + + // Returns true if and only if the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != nullptr ? message_->c_str() : ""; + } + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template AssertionResult& operator<<(const T& value) { + AppendMessage(Message() << value); + return *this; + } + + // Allows streaming basic output manipulators such as endl or flush into + // this object. + AssertionResult& operator<<( + ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { + AppendMessage(Message() << basic_manipulator); + return *this; + } + + private: + // Appends the contents of message to message_. + void AppendMessage(const Message& a_message) { + if (message_.get() == nullptr) message_.reset(new ::std::string); + message_->append(a_message.GetString().c_str()); + } + + // Swap the contents of this AssertionResult with other. + void swap(AssertionResult& other); + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + std::unique_ptr< ::std::string> message_; +}; + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +} // namespace testing + +// Includes the auto-generated header that implements a family of generic +// predicate assertion macros. This include comes late because it relies on +// APIs declared above. +#include "gtest/gtest_pred_impl.h" + +namespace testing { + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestSuites, and +// each TestSuite contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used in a TEST_F. For example: +// +// class FooTest : public testing::Test { +// protected: +// void SetUp() override { ... } +// void TearDown() override { ... } +// ... +// }; +// +// TEST_F(FooTest, Bar) { ... } +// TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class GTEST_API_ Test { + public: + friend class TestInfo; + + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); + + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestSuite() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestSuite() method to shadow the one defined in the super + // class. + // Failures that happen during SetUpTestSuite are logged but otherwise + // ignored. + static void SetUpTestSuite() {} + + // Tears down the stuff shared by all tests in this test suite. + // + // Google Test will call Foo::TearDownTestSuite() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestSuite() method to shadow the one defined in the super + // class. + // Failures that happen during TearDownTestSuite are logged but otherwise + // ignored. + static void TearDownTestSuite() {} + + // Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + static void TearDownTestCase() {} + static void SetUpTestCase() {} +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + // Returns true if and only if the current test has a fatal failure. + static bool HasFatalFailure(); + + // Returns true if and only if the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true if and only if the current test was skipped. + static bool IsSkipped(); + + // Returns true if and only if the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + + // Logs a property for the current test, test suite, or for the entire + // invocation of the test program when used outside of the context of a + // test suite. Only the last value for a given key is remembered. These + // are public static so they can be called from utility functions that are + // not members of the test fixture. Calls to RecordProperty made during + // lifespan of the test (from the moment its constructor starts to the + // moment its destructor finishes) will be output in XML as attributes of + // the element. Properties recorded from fixture's + // SetUpTestSuite or TearDownTestSuite are logged as attributes of the + // corresponding element. Calls to RecordProperty made in the + // global context (before or after invocation of RUN_ALL_TESTS and from + // SetUp/TearDown method of Environment objects registered with Google + // Test) will be output as attributes of the element. + static void RecordProperty(const std::string& key, const std::string& value); + static void RecordProperty(const std::string& key, int value); + + protected: + // Creates a Test object. + Test(); + + // Sets up the test fixture. + virtual void SetUp(); + + // Tears down the test fixture. + virtual void TearDown(); + + private: + // Returns true if and only if the current test has the same fixture class + // as the first test in the current test suite. + static bool HasSameFixtureClass(); + + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; + + // Sets up, executes, and tears down the test. + void Run(); + + // Deletes self. We deliberately pick an unusual name for this + // internal method to avoid clashing with names used in user TESTs. + void DeleteSelf_() { delete this; } + + const std::unique_ptr gtest_flag_saver_; + + // Often a user misspells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if void Setup() is declared in the user's + // test fixture. + // + // - This method is private, so it will be another compiler error + // if the method is called from the user's test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; } + + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const std::string& a_key, const std::string& a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const std::string& new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + std::string key_; + // The value supplied by the user. + std::string value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true if and only if the test passed (i.e. no test part failed). + bool Passed() const { return !Skipped() && !Failed(); } + + // Returns true if and only if the test was skipped. + bool Skipped() const; + + // Returns true if and only if the test failed. + bool Failed() const; + + // Returns true if and only if the test fatally failed. + bool HasFatalFailure() const; + + // Returns true if and only if the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Gets the time of the test case start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } + + // Returns the i-th test part result among all the results. i can range from 0 + // to total_part_count() - 1. If i is not in that range, aborts the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class TestSuite; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + friend class internal::FuchsiaDeathTest; + + // Gets the vector of TestPartResults. + const std::vector& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector& test_properties() const { + return test_properties_; + } + + // Sets the start time. + void set_start_timestamp(TimeInMillis start) { start_timestamp_ = start; } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. xml_element specifies the element for which the property is being + // recorded and is used for validation. + void RecordProperty(const std::string& xml_element, + const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testsuite tags. Returns true if the property is valid. + // FIXME: Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const std::string& xml_element, + const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector test_part_results_; + // The vector of TestProperties + std::vector test_properties_; + // Running count of death tests. + int death_test_count_; + // The start time, in milliseconds since UNIX Epoch. + TimeInMillis start_timestamp_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult + +// A TestInfo object stores the following information about a test: +// +// Test suite name +// Test name +// Whether the test should be run +// A function pointer that creates the test object when invoked +// Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class GTEST_API_ TestInfo { + public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); + + // Returns the test suite name. + const char* test_suite_name() const { return test_suite_name_.c_str(); } + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + const char* test_case_name() const { return test_suite_name(); } +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + // Returns the test name. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a typed + // or a type-parameterized test. + const char* type_param() const { + if (type_param_.get() != nullptr) return type_param_->c_str(); + return nullptr; + } + + // Returns the text representation of the value parameter, or NULL if this + // is not a value-parameterized test. + const char* value_param() const { + if (value_param_.get() != nullptr) return value_param_->c_str(); + return nullptr; + } + + // Returns the file name where this test is defined. + const char* file() const { return location_.file.c_str(); } + + // Returns the line where this test is defined. + int line() const { return location_.line; } + + // Return true if this test should not be run because it's in another shard. + bool is_in_another_shard() const { return is_in_another_shard_; } + + // Returns true if this test should run, that is if the test is not + // disabled (or it is disabled but the also_run_disabled_tests flag has + // been specified) and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test suite Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const { return should_run_; } + + // Returns true if and only if this test will appear in the XML report. + bool is_reportable() const { + // The XML report includes tests matching the filter, excluding those + // run in other shards. + return matches_filter_ && !is_in_another_shard_; + } + + // Returns the result of the test. + const TestResult* result() const { return &result_; } + + private: +#if GTEST_HAS_DEATH_TEST + friend class internal::DefaultDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestSuite; + friend class internal::UnitTestImpl; + friend class internal::StreamingListenerTest; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_suite_name, const char* name, const char* type_param, + const char* value_param, internal::CodeLocation code_location, + internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc, + internal::TearDownTestSuiteFunc tear_down_tc, + internal::TestFactoryBase* factory); + + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const std::string& test_suite_name, const std::string& name, + const char* a_type_param, // NULL if not a type-parameterized test + const char* a_value_param, // NULL if not a value-parameterized test + internal::CodeLocation a_code_location, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); + + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count() { + return result_.increment_death_test_count(); + } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + static void ClearTestResult(TestInfo* test_info) { + test_info->result_.Clear(); + } + + // These fields are immutable properties of the test. + const std::string test_suite_name_; // test suite name + const std::string name_; // Test name + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const std::unique_ptr type_param_; + // Text representation of the value parameter, or NULL if this is not a + // value-parameterized test. + const std::unique_ptr value_param_; + internal::CodeLocation location_; + const internal::TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True if and only if this test should run + bool is_disabled_; // True if and only if this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + bool is_in_another_shard_; // Will be run in another shard. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// A test suite, which consists of a vector of TestInfos. +// +// TestSuite is not copyable. +class GTEST_API_ TestSuite { + public: + // Creates a TestSuite with the given name. + // + // TestSuite does NOT have a default constructor. Always use this + // constructor to create a TestSuite object. + // + // Arguments: + // + // name: name of the test suite + // a_type_param: the name of the test's type parameter, or NULL if + // this is not a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test suite + // tear_down_tc: pointer to the function that tears down the test suite + TestSuite(const char* name, const char* a_type_param, + internal::SetUpTestSuiteFunc set_up_tc, + internal::TearDownTestSuiteFunc tear_down_tc); + + // Destructor of TestSuite. + virtual ~TestSuite(); + + // Gets the name of the TestSuite. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a + // type-parameterized test suite. + const char* type_param() const { + if (type_param_.get() != nullptr) return type_param_->c_str(); + return nullptr; + } + + // Returns true if any test in this test suite should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test suite. + int successful_test_count() const; + + // Gets the number of skipped tests in this test suite. + int skipped_test_count() const; + + // Gets the number of failed tests in this test suite. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests in this test suite. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Get the number of tests in this test suite that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test suite. + int total_test_count() const; + + // Returns true if and only if the test suite passed. + bool Passed() const { return !Failed(); } + + // Returns true if and only if the test suite failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Gets the time of the test suite start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + // Returns the TestResult that holds test properties recorded during + // execution of SetUpTestSuite and TearDownTestSuite. + const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestSuite. + std::vector& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestSuite. + const std::vector& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test suite. Will delete the TestInfo upon + // destruction of the TestSuite object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test suite. + void ClearResult(); + + // Clears the results of all tests in the given test suite. + static void ClearTestSuiteResult(TestSuite* test_suite) { + test_suite->ClearResult(); + } + + // Runs every test in this TestSuite. + void Run(); + + // Runs SetUpTestSuite() for this TestSuite. This wrapper is needed + // for catching exceptions thrown from SetUpTestSuite(). + void RunSetUpTestSuite() { + if (set_up_tc_ != nullptr) { + (*set_up_tc_)(); + } + } + + // Runs TearDownTestSuite() for this TestSuite. This wrapper is + // needed for catching exceptions thrown from TearDownTestSuite(). + void RunTearDownTestSuite() { + if (tear_down_tc_ != nullptr) { + (*tear_down_tc_)(); + } + } + + // Returns true if and only if test passed. + static bool TestPassed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Passed(); + } + + // Returns true if and only if test skipped. + static bool TestSkipped(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Skipped(); + } + + // Returns true if and only if test failed. + static bool TestFailed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Failed(); + } + + // Returns true if and only if the test is disabled and will be reported in + // the XML report. + static bool TestReportableDisabled(const TestInfo* test_info) { + return test_info->is_reportable() && test_info->is_disabled_; + } + + // Returns true if and only if test is disabled. + static bool TestDisabled(const TestInfo* test_info) { + return test_info->is_disabled_; + } + + // Returns true if and only if this test will appear in the XML report. + static bool TestReportable(const TestInfo* test_info) { + return test_info->is_reportable(); + } + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo* test_info) { + return test_info->should_run(); + } + + // Shuffles the tests in this test suite. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test suite. + std::string name_; + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const std::unique_ptr type_param_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector test_indices_; + // Pointer to the function that sets up the test suite. + internal::SetUpTestSuiteFunc set_up_tc_; + // Pointer to the function that tears down the test suite. + internal::TearDownTestSuiteFunc tear_down_tc_; + // True if and only if any test in this test suite should run. + bool should_run_; + // The start time, in milliseconds since UNIX Epoch. + TimeInMillis start_timestamp_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + // Holds test properties recorded during execution of SetUpTestSuite and + // TearDownTestSuite. + TestResult ad_hoc_test_result_; + + // We disallow copying TestSuites. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestSuite); +}; + +// An Environment object is capable of setting up and tearing down an +// environment. You should subclass this to define your own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +// 1. You cannot safely throw from a destructor. This is a problem +// as in some cases Google Test is used where exceptions are enabled, and +// we may want to implement ASSERT_* using exceptions where they are +// available. +// 2. You cannot use ASSERT_* directly in a constructor or +// destructor. +class Environment { + public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} + + // Override this to define how to set up the environment. + virtual void SetUp() {} + + // Override this to define how to tear down the environment. + virtual void TearDown() {} + private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; } +}; + +#if GTEST_HAS_EXCEPTIONS + +// Exception which can be thrown from TestEventListener::OnTestPartResult. +class GTEST_API_ AssertionException + : public internal::GoogleTestFailureException { + public: + explicit AssertionException(const TestPartResult& result) + : GoogleTestFailureException(result) {} +}; + +#endif // GTEST_HAS_EXCEPTIONS + +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test suite starts. + virtual void OnTestSuiteStart(const TestSuite& /*test_suite*/) {} + + // Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCEED() invocation. + // If you want to throw an exception from this function to skip to the next + // TEST, it must be AssertionException defined above, or inherited from it. + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test suite ends. + virtual void OnTestSuiteEnd(const TestSuite& /*test_suite*/) {} + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + void OnTestProgramStart(const UnitTest& /*unit_test*/) override {} + void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) override {} + void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {} + void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {} + void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {} +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseStart(const TestCase& /*test_case*/) override {} +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + void OnTestStart(const TestInfo& /*test_info*/) override {} + void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {} + void OnTestEnd(const TestInfo& /*test_info*/) override {} + void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {} +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseEnd(const TestCase& /*test_case*/) override {} +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {} + void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {} + void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) override {} + void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestSuite; + friend class TestInfo; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestSuites. +// +// This is a singleton class. The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called. This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class GTEST_API_ UnitTest { + public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); + + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; + + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; + + // Returns the TestSuite object for the test that's currently running, + // or NULL if no test is running. + const TestSuite* current_test_suite() const GTEST_LOCK_EXCLUDED_(mutex_); + +// Legacy API is still available but deprecated +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_); +#endif + + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_); + + // Returns the random seed used at the start of the current test run. + int random_seed() const; + + // Returns the ParameterizedTestSuiteRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_); + + // Gets the number of successful test suites. + int successful_test_suite_count() const; + + // Gets the number of failed test suites. + int failed_test_suite_count() const; + + // Gets the number of all test suites. + int total_test_suite_count() const; + + // Gets the number of all test suites that contain at least one test + // that should run. + int test_suite_to_run_count() const; + + // Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + int successful_test_case_count() const; + int failed_test_case_count() const; + int total_test_case_count() const; + int test_case_to_run_count() const; +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of skipped tests. + int skipped_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true if and only if the unit test passed (i.e. all test suites + // passed). + bool Passed() const; + + // Returns true if and only if the unit test failed (i.e. some test suite + // failed or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test suite among all the test suites. i can range from 0 to + // total_test_suite_count() - 1. If i is not in that range, returns NULL. + const TestSuite* GetTestSuite(int i) const; + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + const TestCase* GetTestCase(int i) const; +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + // Returns the TestResult containing information on test failures and + // properties logged outside of individual test suites. + const TestResult& ad_hoc_test_result() const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Adds a TestProperty to the current TestResult object when invoked from + // inside a test, to current TestSuite's ad_hoc_test_result_ when invoked + // from SetUpTestSuite or TearDownTestSuite, or to the global property set + // when invoked elsewhere. If the result already contains a property with + // the same key, the value will be updated. + void RecordProperty(const std::string& key, const std::string& value); + + // Gets the i-th test suite among all the test suites. i can range from 0 to + // total_test_suite_count() - 1. If i is not in that range, returns NULL. + TestSuite* GetMutableTestSuite(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and functions are friends as they need to access private + // members of UnitTest. + friend class ScopedTrace; + friend class Test; + friend class internal::AssertHelper; + friend class internal::StreamingListenerTest; + friend class internal::UnitTestRecordPropertyTestHelper; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const std::string& message); + + // Creates an empty UnitTest. + UnitTest(); + + // D'tor + virtual ~UnitTest(); + + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_); + + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; + + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; + + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main(). If you use gtest_main, you need to call this before main() +// starts for it to take effect. For example, you can define a global +// variable like this: +// +// testing::Environment* const foo_env = +// testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { + return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +GTEST_API_ void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); + +// This overloaded version can be used on Arduino/embedded platforms where +// there is no argc/argv. +GTEST_API_ void InitGoogleTest(); + +namespace internal { + +// Separate the error generating code from the code path to reduce the stack +// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers +// when calling EXPECT_* in a tight loop. +template +AssertionResult CmpHelperEQFailure(const char* lhs_expression, + const char* rhs_expression, + const T1& lhs, const T2& rhs) { + return EqFailure(lhs_expression, + rhs_expression, + FormatForComparisonFailureMessage(lhs, rhs), + FormatForComparisonFailureMessage(rhs, lhs), + false); +} + +// This block of code defines operator==/!= +// to block lexical scope lookup. +// It prevents using invalid operator==/!= defined at namespace scope. +struct faketype {}; +inline bool operator==(faketype, faketype) { return true; } +inline bool operator!=(faketype, faketype) { return false; } + +// The helper function for {ASSERT|EXPECT}_EQ. +template +AssertionResult CmpHelperEQ(const char* lhs_expression, + const char* rhs_expression, + const T1& lhs, + const T2& rhs) { + if (lhs == rhs) { + return AssertionSuccess(); + } + + return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +GTEST_API_ AssertionResult CmpHelperEQ(const char* lhs_expression, + const char* rhs_expression, + BiggestInt lhs, + BiggestInt rhs); + +class EqHelper { + public: + // This templatized version is for the general case. + template < + typename T1, typename T2, + // Disable this overload for cases where one argument is a pointer + // and the other is the null pointer constant. + typename std::enable_if::value || + !std::is_pointer::value>::type* = nullptr> + static AssertionResult Compare(const char* lhs_expression, + const char* rhs_expression, const T1& lhs, + const T2& rhs) { + return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); + } + + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* lhs_expression, + const char* rhs_expression, + BiggestInt lhs, + BiggestInt rhs) { + return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); + } + + template + static AssertionResult Compare( + const char* lhs_expression, const char* rhs_expression, + // Handle cases where '0' is used as a null pointer literal. + std::nullptr_t /* lhs */, T* rhs) { + // We already know that 'lhs' is a null pointer. + return CmpHelperEQ(lhs_expression, rhs_expression, static_cast(nullptr), + rhs); + } +}; + +// Separate the error generating code from the code path to reduce the stack +// frame size of CmpHelperOP. This helps reduce the overhead of some sanitizers +// when calling EXPECT_OP in a tight loop. +template +AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2, + const T1& val1, const T2& val2, + const char* op) { + return AssertionFailure() + << "Expected: (" << expr1 << ") " << op << " (" << expr2 + << "), actual: " << FormatForComparisonFailureMessage(val1, val2) + << " vs " << FormatForComparisonFailureMessage(val2, val1); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template \ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);\ + }\ +}\ +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=); +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=); +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, <); +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=); +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, >); + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +} // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves. They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression, + const char* rhs_expression, + RawType lhs_value, + RawType rhs_value) { + const FloatingPoint lhs(lhs_value), rhs(rhs_value); + + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + ::std::stringstream lhs_ss; + lhs_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << lhs_value; + + ::std::stringstream rhs_ss; + rhs_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << rhs_value; + + return EqFailure(lhs_expression, + rhs_expression, + StringStreamToString(&lhs_ss), + StringStreamToString(&rhs_ss), + false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class GTEST_API_ AssertHelper { + public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); + + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; + + private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + std::string const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; + +GTEST_API_ GTEST_ATTRIBUTE_PRINTF_(2, 3) void ColoredPrintf(GTestColor color, + const char* fmt, + ...); + +} // namespace internal + +// The pure interface class that all value-parameterized tests inherit from. +// A value-parameterized class must inherit from both ::testing::Test and +// ::testing::WithParamInterface. In most cases that just means inheriting +// from ::testing::TestWithParam, but more complicated test hierarchies +// may need to inherit from Test and WithParamInterface at different levels. +// +// This interface has support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam { +// protected: +// FooTest() { +// // Can use GetParam() here. +// } +// ~FooTest() override { +// // Can use GetParam() here. +// } +// void SetUp() override { +// // Can use GetParam() here. +// } +// void TearDown override { +// // Can use GetParam() here. +// } +// }; +// TEST_P(FooTest, DoesBar) { +// // Can use GetParam() method here. +// Foo foo; +// ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template +class WithParamInterface { + public: + typedef T ParamType; + virtual ~WithParamInterface() {} + + // The current parameter value. Is also available in the test fixture's + // constructor. + static const ParamType& GetParam() { + GTEST_CHECK_(parameter_ != nullptr) + << "GetParam() can only be called inside a value-parameterized test " + << "-- did you intend to write TEST_P instead of TEST_F?"; + return *parameter_; + } + + private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) { + parameter_ = parameter; + } + + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; + + // TestClass must be a subclass of WithParamInterface and Test. + template friend class internal::ParameterizedTestFactory; +}; + +template +const T* WithParamInterface::parameter_ = nullptr; + +// Most value-parameterized classes can ignore the existence of +// WithParamInterface, and can just inherit from ::testing::TestWithParam. + +template +class TestWithParam : public Test, public WithParamInterface { +}; + +// Macros for indicating success/failure in test code. + +// Skips test in runtime. +// Skipping test aborts current function. +// Skipped tests are neither successful nor failed. +#define GTEST_SKIP() GTEST_SKIP_("Skipped") + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied. If not, +// it behaves like ADD_FAILURE. In particular: +// +// EXPECT_TRUE verifies that a Boolean condition is true. +// EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure. People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a nonfatal failure at the given source file location with +// a generic message. +#define ADD_FAILURE_AT(file, line) \ + GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kNonFatalFailure) + +// Generates a fatal failure with a generic message. +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Like GTEST_FAIL(), but at the given source file location. +#define GTEST_FAIL_AT(file, line) \ + GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kFatalFailure) + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +# define FAIL() GTEST_FAIL() +#endif + +// Generates a success with a generic message. +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +# define SUCCEED() GTEST_SUCCEED() +#endif + +// Macros for testing exceptions. +// +// * {ASSERT|EXPECT}_THROW(statement, expected_exception): +// Tests that the statement throws the expected exception. +// * {ASSERT|EXPECT}_NO_THROW(statement): +// Tests that the statement doesn't throw any exception. +// * {ASSERT|EXPECT}_ANY_THROW(statement): +// Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2 +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values. The values must be compatible built-in types, +// or you will get a compiler error. By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +// 1. It is possible to make a user-defined type work with +// {ASSERT|EXPECT}_??(), but that requires overloading the +// comparison operators and is thus discouraged by the Google C++ +// Usage Guide. Therefore, you are advised to use the +// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +// equal. +// +// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +// pointers (in particular, C strings). Therefore, if you use it +// with two C strings, you are testing how their locations in memory +// are related, not how their content is related. To compare two C +// strings by content, use {ASSERT|EXPECT}_STR*(). +// +// 3. {ASSERT|EXPECT}_EQ(v1, v2) is preferred to +// {ASSERT|EXPECT}_TRUE(v1 == v2), as the former tells you +// what the actual value is when it fails, and similarly for the +// other comparisons. +// +// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() +// evaluate their arguments, which is undefined. +// +// 5. These macros evaluate their arguments exactly once. +// +// Examples: +// +// EXPECT_NE(Foo(), 5); +// EXPECT_EQ(a_pointer, NULL); +// ASSERT_LT(i, array_size); +// ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2) +#define EXPECT_NE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define EXPECT_LE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define GTEST_ASSERT_EQ(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2) +#define GTEST_ASSERT_NE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define GTEST_ASSERT_LE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define GTEST_ASSERT_LT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define GTEST_ASSERT_GE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define GTEST_ASSERT_GT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of +// ASSERT_XY(), which clashes with some users' own code. + +#if !GTEST_DONT_DEFINE_ASSERT_EQ +# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_NE +# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LE +# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LT +# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GE +# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GT +# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) +#endif + +// C-string Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2) +#define EXPECT_STRNE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2) +#define EXPECT_STRCASENE(s1, s2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2) +#define ASSERT_STRNE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2) +#define ASSERT_STRCASENE(s1, s2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(val1, val2): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(val1, val2): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands. See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(val1, val2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + val1, val2) + +#define EXPECT_DOUBLE_EQ(val1, val2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + val1, val2) + +#define ASSERT_FLOAT_EQ(val1, val2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + val1, val2) + +#define ASSERT_DOUBLE_EQ(val1, val2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + val1, val2) + +#define EXPECT_NEAR(val1, val2, abs_error)\ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); + + +#if GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +# define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +# define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +// EXPECT_NO_FATAL_FAILURE(Process()); +// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the given source file path and line number, +// and the given message) to be included in every test failure message generated +// by code in the scope of the lifetime of an instance of this class. The effect +// is undone with the destruction of the instance. +// +// The message argument can be anything streamable to std::ostream. +// +// Example: +// testing::ScopedTrace trace("file.cc", 123, "message"); +// +class GTEST_API_ ScopedTrace { + public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + + // Template version. Uses Message() to convert the values into strings. + // Slow, but flexible. + template + ScopedTrace(const char* file, int line, const T& message) { + PushTrace(file, line, (Message() << message).GetString()); + } + + // Optimize for some known types. + ScopedTrace(const char* file, int line, const char* message) { + PushTrace(file, line, message ? message : "(null)"); + } + + ScopedTrace(const char* file, int line, const std::string& message) { + PushTrace(file, line, message); + } + + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); + + private: + void PushTrace(const char* file, int line, std::string message); + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope. The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +// +// Assuming that each thread maintains its own stack of traces. +// Therefore, a SCOPED_TRACE() would (correctly) only affect the +// assertions in its own thread. +#define SCOPED_TRACE(message) \ + ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ + __FILE__, __LINE__, (message)) + +// Compile-time assertion for type equality. +// StaticAssertTypeEq() compiles if and only if type1 and type2 +// are the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq(); } +// }; +// +// the code: +// +// void Test1() { Foo foo; } +// +// will NOT generate a compiler error, as Foo::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo foo; foo.Bar(); } +// +// to cause a compiler error. +template +constexpr bool StaticAssertTypeEq() noexcept { + static_assert(std::is_same::value, + "type1 and type2 are not the same type"); + return true; +} + +// Defines a test. +// +// The first parameter is the name of the test suite, and the second +// parameter is the name of the test within the test suite. +// +// The convention is to end the test suite name with "Test". For +// example, a test suite for the Foo class can be named FooTest. +// +// Test code should appear between braces after an invocation of +// this macro. Example: +// +// TEST(FooTest, InitializesCorrectly) { +// Foo foo; +// EXPECT_TRUE(foo.StatusIsOK()); +// } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test. This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X. The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code. GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define GTEST_TEST(test_suite_name, test_name) \ + GTEST_TEST_(test_suite_name, test_name, ::testing::Test, \ + ::testing::internal::GetTestTypeId()) + +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name) +#endif + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test suite name. The second parameter is the +// name of the test within the test suite. +// +// A test fixture class must be declared earlier. The user should put +// the test code between braces after using this macro. Example: +// +// class FooTest : public testing::Test { +// protected: +// void SetUp() override { b_.AddElement(3); } +// +// Foo a_; +// Foo b_; +// }; +// +// TEST_F(FooTest, InitializesCorrectly) { +// EXPECT_TRUE(a_.StatusIsOK()); +// } +// +// TEST_F(FooTest, ReturnsElementCountCorrectly) { +// EXPECT_EQ(a_.size(), 0); +// EXPECT_EQ(b_.size(), 1); +// } +// +// GOOGLETEST_CM0011 DO NOT DELETE +#define TEST_F(test_fixture, test_name)\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId()) + +// Returns a path to temporary directory. +// Tries to determine an appropriate directory for the platform. +GTEST_API_ std::string TempDir(); + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// Dynamically registers a test with the framework. +// +// This is an advanced API only to be used when the `TEST` macros are +// insufficient. The macros should be preferred when possible, as they avoid +// most of the complexity of calling this function. +// +// The `factory` argument is a factory callable (move-constructible) object or +// function pointer that creates a new instance of the Test object. It +// handles ownership to the caller. The signature of the callable is +// `Fixture*()`, where `Fixture` is the test fixture class for the test. All +// tests registered with the same `test_suite_name` must return the same +// fixture type. This is checked at runtime. +// +// The framework will infer the fixture class from the factory and will call +// the `SetUpTestSuite` and `TearDownTestSuite` for it. +// +// Must be called before `RUN_ALL_TESTS()` is invoked, otherwise behavior is +// undefined. +// +// Use case example: +// +// class MyFixture : public ::testing::Test { +// public: +// // All of these optional, just like in regular macro usage. +// static void SetUpTestSuite() { ... } +// static void TearDownTestSuite() { ... } +// void SetUp() override { ... } +// void TearDown() override { ... } +// }; +// +// class MyTest : public MyFixture { +// public: +// explicit MyTest(int data) : data_(data) {} +// void TestBody() override { ... } +// +// private: +// int data_; +// }; +// +// void RegisterMyTests(const std::vector& values) { +// for (int v : values) { +// ::testing::RegisterTest( +// "MyFixture", ("Test" + std::to_string(v)).c_str(), nullptr, +// std::to_string(v).c_str(), +// __FILE__, __LINE__, +// // Important to use the fixture type as the return type here. +// [=]() -> MyFixture* { return new MyTest(v); }); +// } +// } +// ... +// int main(int argc, char** argv) { +// std::vector values_to_test = LoadValuesFromConfig(); +// RegisterMyTests(values_to_test); +// ... +// return RUN_ALL_TESTS(); +// } +// +template +TestInfo* RegisterTest(const char* test_suite_name, const char* test_name, + const char* type_param, const char* value_param, + const char* file, int line, Factory factory) { + using TestT = typename std::remove_pointer::type; + + class FactoryImpl : public internal::TestFactoryBase { + public: + explicit FactoryImpl(Factory f) : factory_(std::move(f)) {} + Test* CreateTest() override { return factory_(); } + + private: + Factory factory_; + }; + + return internal::MakeAndRegisterTestInfo( + test_suite_name, test_name, type_param, value_param, + internal::CodeLocation(file, line), internal::GetTypeId(), + internal::SuiteApiResolver::GetSetUpCaseOrSuite(file, line), + internal::SuiteApiResolver::GetTearDownCaseOrSuite(file, line), + new FactoryImpl{std::move(factory)}); +} + +} // namespace testing + +// Use this function in main() to run all tests. It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). +// +// This function was formerly a macro; thus, it is in the global +// namespace and has an all-caps name. +int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; + +inline int RUN_ALL_TESTS() { + return ::testing::UnitTest::GetInstance()->Run(); +} + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/3rdparty/gtest/include/gtest/gtest_pred_impl.h b/3rdparty/gtest/include/gtest/gtest_pred_impl.h new file mode 100644 index 0000000..d514255 --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest_pred_impl.h @@ -0,0 +1,359 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +#include "gtest/gtest.h" + +namespace testing { + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +template +AssertionResult AssertPred1Helper(const char* pred_text, + const char* e1, + Pred pred, + const T1& v1) { + if (pred(v1)) return AssertionSuccess(); + + return AssertionFailure() + << pred_text << "(" << e1 << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << ::testing::PrintToString(v1); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, v1), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +template +AssertionResult AssertPred2Helper(const char* pred_text, + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) { + if (pred(v1, v2)) return AssertionSuccess(); + + return AssertionFailure() + << pred_text << "(" << e1 << ", " << e2 + << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" + << e2 << " evaluates to " << ::testing::PrintToString(v2); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +template +AssertionResult AssertPred3Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) { + if (pred(v1, v2, v3)) return AssertionSuccess(); + + return AssertionFailure() + << pred_text << "(" << e1 << ", " << e2 << ", " << e3 + << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" + << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n" + << e3 << " evaluates to " << ::testing::PrintToString(v3); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +template +AssertionResult AssertPred4Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + + return AssertionFailure() + << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 + << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" + << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n" + << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n" + << e4 << " evaluates to " << ::testing::PrintToString(v4); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +template +AssertionResult AssertPred5Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + + return AssertionFailure() + << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 + << ", " << e5 << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" + << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n" + << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n" + << e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n" + << e5 << " evaluates to " << ::testing::PrintToString(v5); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ diff --git a/3rdparty/gtest/include/gtest/gtest_prod.h b/3rdparty/gtest/include/gtest/gtest_prod.h new file mode 100644 index 0000000..e651671 --- /dev/null +++ b/3rdparty/gtest/include/gtest/gtest_prod.h @@ -0,0 +1,61 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Google C++ Testing and Mocking Framework definitions useful in production code. +// GOOGLETEST_CM0003 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class. For example: +// +// class MyClass { +// private: +// void PrivateMethod(); +// FRIEND_TEST(MyClassTest, PrivateMethodWorks); +// }; +// +// class MyClassTest : public testing::Test { +// // ... +// }; +// +// TEST_F(MyClassTest, PrivateMethodWorks) { +// // Can call MyClass::PrivateMethod() here. +// } +// +// Note: The test class must be in the same namespace as the class being tested. +// For example, putting MyClassTest in an anonymous namespace will not work. + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ diff --git a/3rdparty/gtest/include/gtest/internal/custom/README.md b/3rdparty/gtest/include/gtest/internal/custom/README.md new file mode 100644 index 0000000..ff391fb --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/custom/README.md @@ -0,0 +1,56 @@ +# Customization Points + +The custom directory is an injection point for custom user configurations. + +## Header `gtest.h` + +### The following macros can be defined: + +* `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of + `OsStackTraceGetterInterface`. +* `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See + `testing::TempDir` for semantics and signature. + +## Header `gtest-port.h` + +The following macros can be defined: + +### Flag related macros: + +* `GTEST_FLAG(flag_name)` +* `GTEST_USE_OWN_FLAGFILE_FLAG_` - Define to 0 when the system provides its + own flagfile flag parsing. +* `GTEST_DECLARE_bool_(name)` +* `GTEST_DECLARE_int32_(name)` +* `GTEST_DECLARE_string_(name)` +* `GTEST_DEFINE_bool_(name, default_val, doc)` +* `GTEST_DEFINE_int32_(name, default_val, doc)` +* `GTEST_DEFINE_string_(name, default_val, doc)` + +### Logging: + +* `GTEST_LOG_(severity)` +* `GTEST_CHECK_(condition)` +* Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too. + +### Threading: + +* `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided. +* `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal` + are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)` + and `GTEST_DEFINE_STATIC_MUTEX_(mutex)` +* `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)` +* `GTEST_LOCK_EXCLUDED_(locks)` + +### Underlying library support features + +* `GTEST_HAS_CXXABI_H_` + +### Exporting API symbols: + +* `GTEST_API_` - Specifier for exported symbols. + +## Header `gtest-printers.h` + +* See documentation at `gtest/gtest-printers.h` for details on how to define a + custom printer. diff --git a/3rdparty/gtest/include/gtest/internal/custom/gtest-port.h b/3rdparty/gtest/include/gtest/internal/custom/gtest-port.h new file mode 100644 index 0000000..cd85d95 --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/custom/gtest-port.h @@ -0,0 +1,37 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Injection point for custom user configurations. See README for details +// +// ** Custom implementation starts here ** + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ diff --git a/3rdparty/gtest/include/gtest/internal/custom/gtest-printers.h b/3rdparty/gtest/include/gtest/internal/custom/gtest-printers.h new file mode 100644 index 0000000..eb4467a --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/custom/gtest-printers.h @@ -0,0 +1,42 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// This file provides an injection point for custom printers in a local +// installation of gTest. +// It will be included from gtest-printers.h and the overrides in this file +// will be visible to everyone. +// +// Injection point for custom user configurations. See README for details +// +// ** Custom implementation starts here ** + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ diff --git a/3rdparty/gtest/include/gtest/internal/custom/gtest.h b/3rdparty/gtest/include/gtest/internal/custom/gtest.h new file mode 100644 index 0000000..4c8e07b --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/custom/gtest.h @@ -0,0 +1,37 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Injection point for custom user configurations. See README for details +// +// ** Custom implementation starts here ** + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ diff --git a/3rdparty/gtest/include/gtest/internal/gtest-death-test-internal.h b/3rdparty/gtest/include/gtest/internal/gtest-death-test-internal.h new file mode 100644 index 0000000..68bd353 --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/gtest-death-test-internal.h @@ -0,0 +1,304 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests. They are subject to change without notice. +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +#include "gtest/gtest-matchers.h" +#include "gtest/internal/gtest-internal.h" + +#include +#include + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#if GTEST_HAS_DEATH_TEST + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status: The integer exit information in the format specified +// by wait(2) +// exit code: The integer code passed to exit(3), _exit(2), or +// returned from main() +class GTEST_API_ DeathTest { + public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, Matcher matcher, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() { } + + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) { } + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; + + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + + // An enumeration of the three reasons that a test might be aborted. + enum AbortReason { + TEST_ENCOUNTERED_RETURN_STATEMENT, + TEST_THREW_EXCEPTION, + TEST_DID_NOT_DIE + }; + + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; + + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; + + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; + + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; + + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); + + static void set_last_death_test_message(const std::string& message); + + private: + // A string containing a description of the outcome of the last death test. + static std::string last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +// Factory interface for death tests. May be mocked out for testing. +class DeathTestFactory { + public: + virtual ~DeathTestFactory() { } + virtual bool Create(const char* statement, + Matcher matcher, const char* file, + int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: + bool Create(const char* statement, Matcher matcher, + const char* file, int line, DeathTest** test) override; +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); + +// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads +// and interpreted as a regex (rather than an Eq matcher) for legacy +// compatibility. +inline Matcher MakeDeathTestMatcher( + ::testing::internal::RE regex) { + return ContainsRegex(regex.pattern()); +} +inline Matcher MakeDeathTestMatcher(const char* regex) { + return ContainsRegex(regex); +} +inline Matcher MakeDeathTestMatcher( + const ::std::string& regex) { + return ContainsRegex(regex); +} + +// If a Matcher is passed to EXPECT_DEATH (etc.), it's +// used directly. +inline Matcher MakeDeathTestMatcher( + Matcher matcher) { + return matcher; +} + +// Traps C++ exceptions escaping statement and reports them as test +// failures. Note that trapping SEH exceptions is not implemented here. +# if GTEST_HAS_EXCEPTIONS +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (const ::std::exception& gtest_exception) { \ + fprintf(\ + stderr, \ + "\n%s: Caught std::exception-derived exception escaping the " \ + "death test statement. Exception message: %s\n", \ + ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ + gtest_exception.what()); \ + fflush(stderr); \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } catch (...) { \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } + +# else +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) + +# endif + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create( \ + #statement, \ + ::testing::internal::MakeDeathTestMatcher(regex_or_matcher), \ + __FILE__, __LINE__, >est_dt)) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != nullptr) { \ + std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: { \ + ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \ + gtest_dt); \ + GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + default: \ + break; \ + } \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \ + : fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in +// NDEBUG mode. In this case we need the statements to be executed and the macro +// must accept a streamed message even though the message is never printed. +// The regex object is not evaluated, but it is used to prevent "unused" +// warnings and to avoid an expression that doesn't compile in debug mode. +#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } else if (!::testing::internal::AlwaysTrue()) { \ + ::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \ + } else \ + ::testing::Message() + +// A class representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const std::string& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + const std::string& file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + std::string file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ diff --git a/3rdparty/gtest/include/gtest/internal/gtest-filepath.h b/3rdparty/gtest/include/gtest/internal/gtest-filepath.h new file mode 100644 index 0000000..c11b101 --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/gtest-filepath.h @@ -0,0 +1,211 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included in gtest/internal/gtest-internal.h. +// Do not include this header file separately! + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + +#include "gtest/internal/gtest-string.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class GTEST_API_ FilePath { + public: + FilePath() : pathname_("") { } + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + + explicit FilePath(const std::string& pathname) : pathname_(pathname) { + Normalize(); + } + + FilePath& operator=(const FilePath& rhs) { + Set(rhs); + return *this; + } + + void Set(const FilePath& rhs) { + pathname_ = rhs.pathname_; + } + + const std::string& string() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } + + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); + + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); + + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); + + // Returns true if and only if the path is "". + bool IsEmpty() const { return pathname_.empty(); } + + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; + + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; + + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; + + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; + + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; + + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; + + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; + + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; + + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; + + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; + + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + + private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". + + void Normalize(); + + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + + std::string pathname_; +}; // class FilePath + +} // namespace internal +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ diff --git a/3rdparty/gtest/include/gtest/internal/gtest-internal.h b/3rdparty/gtest/include/gtest/internal/gtest-internal.h new file mode 100644 index 0000000..94c816a --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/gtest-internal.h @@ -0,0 +1,1380 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test. They are subject to change without notice. + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +#include "gtest/internal/gtest-port.h" + +#if GTEST_OS_LINUX +# include +# include +# include +# include +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-string.h" +#include "gtest/internal/gtest-type-util.h" + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +// Stringifies its argument. +#define GTEST_STRINGIFY_(name) #name + +namespace proto2 { class Message; } + +namespace testing { + +// Forward declarations. + +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test suites. + +template +::std::string PrintToString(const T& value); + +namespace internal { + +struct TraceInfo; // Information about a trace point. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest + +// The text used in failure messages to indicate the start of the +// stack trace. +GTEST_API_ extern const char kStackTraceMarker[]; + +// An IgnoredValue object can be implicitly constructed from ANY value. +class IgnoredValue { + struct Sink {}; + public: + // This constructor template allows any value to be implicitly + // converted to IgnoredValue. The object has no data member and + // doesn't try to remember anything about the argument. We + // deliberately omit the 'explicit' keyword in order to allow the + // conversion to be implicit. + // Disable the conversion if T already has a magical conversion operator. + // Otherwise we get ambiguity. + template ::value, + int>::type = 0> + IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit) +}; + +// Appends the user-supplied message to the Google-Test-generated message. +GTEST_API_ std::string AppendUserMessage( + const std::string& gtest_msg, const Message& user_msg); + +#if GTEST_HAS_EXCEPTIONS + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4275 \ +/* an exported class was derived from a class that was not exported */) + +// This exception is thrown by (and only by) a failed Google Test +// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions +// are enabled). We derive it from std::runtime_error, which is for +// errors presumably detectable only at run time. Since +// std::runtime_error inherits from std::exception, many testing +// frameworks know how to extract and print the message inside it. +class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure); +}; + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4275 + +#endif // GTEST_HAS_EXCEPTIONS + +namespace edit_distance { +// Returns the optimal edits to go from 'left' to 'right'. +// All edits cost the same, with replace having lower priority than +// add/remove. +// Simple implementation of the Wagner-Fischer algorithm. +// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm +enum EditType { kMatch, kAdd, kRemove, kReplace }; +GTEST_API_ std::vector CalculateOptimalEdits( + const std::vector& left, const std::vector& right); + +// Same as above, but the input is represented as strings. +GTEST_API_ std::vector CalculateOptimalEdits( + const std::vector& left, + const std::vector& right); + +// Create a diff of the input strings in Unified diff format. +GTEST_API_ std::string CreateUnifiedDiff(const std::vector& left, + const std::vector& right, + size_t context = 2); + +} // namespace edit_distance + +// Calculate the diff between 'left' and 'right' and return it in unified diff +// format. +// If not null, stores in 'total_line_count' the total number of lines found +// in left + right. +GTEST_API_ std::string DiffStrings(const std::string& left, + const std::string& right, + size_t* total_line_count); + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true if and only if the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison. (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly. Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +// The most-significant bit being the leftmost, an IEEE +// floating-point looks like +// +// sign_bit exponent_bits fraction_bits +// +// Here, sign_bit is a single bit that designates the sign of the +// number. +// +// For float, there are 8 exponent bits and 23 fraction bits. +// +// For double, there are 11 exponent bits and 52 fraction bits. +// +// More details can be found at +// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +template +class FloatingPoint { + public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize::UInt Bits; + + // Constants. + + // # of bits in a number. + static const size_t kBitCount = 8*sizeof(RawType); + + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits::digits - 1; + + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); + + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast(0) >> (kExponentBitCount + 1); + + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ + static const size_t kMaxUlps = 4; + + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + + // Static methods + + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } + + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() { + return ReinterpretBits(kExponentBitMask); + } + + // Returns the maximum representable finite floating-point number. + static RawType Max(); + + // Non-static methods + + // Returns the bits that represents this number. + const Bits &bits() const { return u_.bits_; } + + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } + + // Returns true if and only if this is NAN (not a number). + bool is_nan() const { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } + + // Returns true if and only if this number is at most kMaxUlps ULP's away + // from rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; + + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; + } + + private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits &sam) { + if (kSignBitMask & sam) { + // sam represents a negative number. + return ~sam + 1; + } else { + // sam represents a positive number. + return kSignBitMask | sam; + } + } + + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, + const Bits &sam2) { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } + + FloatingPointUnion u_; +}; + +// We cannot use std::numeric_limits::max() as it clashes with the max() +// macro defined by . +template <> +inline float FloatingPoint::Max() { return FLT_MAX; } +template <> +inline double FloatingPoint::Max() { return DBL_MAX; } + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint Float; +typedef FloatingPoint Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test suite, we need to assign +// unique IDs to fixture classes and compare them. The TypeId type is +// used to hold such IDs. The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template +class TypeIdHelper { + public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper::dummy_ for different Ts as an "optimization". + static bool dummy_; +}; + +template +bool TypeIdHelper::dummy_ = false; + +// GetTypeId() returns the ID of type T. Different values will be +// returned for different types. Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template +TypeId GetTypeId() { + // The compiler is required to allocate a different + // TypeIdHelper::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper::dummy_); +} + +// Returns the type ID of ::testing::Test. Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +GTEST_API_ TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: + virtual ~TestFactoryBase() {} + + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; + + protected: + TestFactoryBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template +class TestFactoryImpl : public TestFactoryBase { + public: + Test* CreateTest() override { return new TestClass; } +}; + +#if GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT + +#endif // GTEST_OS_WINDOWS + +// Types of SetUpTestSuite() and TearDownTestSuite() functions. +using SetUpTestSuiteFunc = void (*)(); +using TearDownTestSuiteFunc = void (*)(); + +struct CodeLocation { + CodeLocation(const std::string& a_file, int a_line) + : file(a_file), line(a_line) {} + + std::string file; + int line; +}; + +// Helper to identify which setup function for TestCase / TestSuite to call. +// Only one function is allowed, either TestCase or TestSute but not both. + +// Utility functions to help SuiteApiResolver +using SetUpTearDownSuiteFuncType = void (*)(); + +inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull( + SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) { + return a == def ? nullptr : a; +} + +template +// Note that SuiteApiResolver inherits from T because +// SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way +// SuiteApiResolver can access them. +struct SuiteApiResolver : T { + // testing::Test is only forward declared at this point. So we make it a + // dependend class for the compiler to be OK with it. + using Test = + typename std::conditional::type; + + static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename, + int line_num) { + SetUpTearDownSuiteFuncType test_case_fp = + GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase); + SetUpTearDownSuiteFuncType test_suite_fp = + GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite); + + GTEST_CHECK_(!test_case_fp || !test_suite_fp) + << "Test can not provide both SetUpTestSuite and SetUpTestCase, please " + "make sure there is only one present at " + << filename << ":" << line_num; + + return test_case_fp != nullptr ? test_case_fp : test_suite_fp; + } + + static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename, + int line_num) { + SetUpTearDownSuiteFuncType test_case_fp = + GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase); + SetUpTearDownSuiteFuncType test_suite_fp = + GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite); + + GTEST_CHECK_(!test_case_fp || !test_suite_fp) + << "Test can not provide both TearDownTestSuite and TearDownTestCase," + " please make sure there is only one present at" + << filename << ":" << line_num; + + return test_case_fp != nullptr ? test_case_fp : test_suite_fp; + } +}; + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_suite_name: name of the test suite +// name: name of the test +// type_param the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param text representation of the test's value parameter, +// or NULL if this is not a type-parameterized test. +// code_location: code location where the test is defined +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test suite +// tear_down_tc: pointer to the function that tears down the test suite +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( + const char* test_suite_name, const char* name, const char* type_param, + const char* value_param, CodeLocation code_location, + TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc, + TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory); + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +// State of the definition of a type-parameterized test suite. +class GTEST_API_ TypedTestSuitePState { + public: + TypedTestSuitePState() : registered_(false) {} + + // Adds the given test name to defined_test_names_ and return true + // if the test suite hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) { + if (registered_) { + fprintf(stderr, + "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_SUITE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + registered_tests_.insert( + ::std::make_pair(test_name, CodeLocation(file, line))); + return true; + } + + bool TestExists(const std::string& test_name) const { + return registered_tests_.count(test_name) > 0; + } + + const CodeLocation& GetCodeLocation(const std::string& test_name) const { + RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name); + GTEST_CHECK_(it != registered_tests_.end()); + return it->second; + } + + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); + + private: + typedef ::std::map RegisteredTestsMap; + + bool registered_; + RegisteredTestsMap registered_tests_; +}; + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +using TypedTestCasePState = TypedTestSuitePState; +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { + const char* comma = strchr(str, ','); + if (comma == nullptr) { + return nullptr; + } + while (IsSpace(*(++comma))) {} + return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline std::string GetPrefixUntilComma(const char* str) { + const char* comma = strchr(str, ','); + return comma == nullptr ? str : std::string(str, comma); +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. +void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest); + +// The default argument to the template below for the case when the user does +// not provide a name generator. +struct DefaultNameGenerator { + template + static std::string GetName(int i) { + return StreamableToString(i); + } +}; + +template +struct NameGeneratorSelector { + typedef Provided type; +}; + +template +void GenerateNamesRecursively(Types0, std::vector*, int) {} + +template +void GenerateNamesRecursively(Types, std::vector* result, int i) { + result->push_back(NameGenerator::template GetName(i)); + GenerateNamesRecursively(typename Types::Tail(), result, + i + 1); +} + +template +std::vector GenerateNames() { + std::vector result; + GenerateNamesRecursively(Types(), &result, 0); + return result; +} + +// TypeParameterizedTest::Register() +// registers a list of type-parameterized tests with Google Test. The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter. It's defined in gtest-type-util.h. +template +class TypeParameterizedTest { + public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const CodeLocation& code_location, + const char* case_name, const char* test_names, int index, + const std::vector& type_names = + GenerateNames()) { + typedef typename Types::Head Type; + typedef Fixture FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; + + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + + "/" + type_names[static_cast(index)]) + .c_str(), + StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), + GetTypeName().c_str(), + nullptr, // No value parameter. + code_location, GetTypeId(), + SuiteApiResolver::GetSetUpCaseOrSuite( + code_location.file.c_str(), code_location.line), + SuiteApiResolver::GetTearDownCaseOrSuite( + code_location.file.c_str(), code_location.line), + new TestFactoryImpl); + + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest::Register(prefix, + code_location, + case_name, + test_names, + index + 1, + type_names); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTest { + public: + static bool Register(const char* /*prefix*/, const CodeLocation&, + const char* /*case_name*/, const char* /*test_names*/, + int /*index*/, + const std::vector& = + std::vector() /*type_names*/) { + return true; + } +}; + +// TypeParameterizedTestSuite::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test. The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template +class TypeParameterizedTestSuite { + public: + static bool Register(const char* prefix, CodeLocation code_location, + const TypedTestSuitePState* state, const char* case_name, + const char* test_names, + const std::vector& type_names = + GenerateNames()) { + std::string test_name = StripTrailingSpaces( + GetPrefixUntilComma(test_names)); + if (!state->TestExists(test_name)) { + fprintf(stderr, "Failed to get code location for test %s.%s at %s.", + case_name, test_name.c_str(), + FormatFileLocation(code_location.file.c_str(), + code_location.line).c_str()); + fflush(stderr); + posix::Abort(); + } + const CodeLocation& test_location = state->GetCodeLocation(test_name); + + typedef typename Tests::Head Head; + + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest::Register( + prefix, test_location, case_name, test_names, 0, type_names); + + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestSuite::Register(prefix, code_location, + state, case_name, + SkipComma(test_names), + type_names); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTestSuite { + public: + static bool Register(const char* /*prefix*/, const CodeLocation&, + const TypedTestSuitePState* /*state*/, + const char* /*case_name*/, const char* /*test_names*/, + const std::vector& = + std::vector() /*type_names*/) { + return true; + } +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( + UnitTest* unit_test, int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// Helper for suppressing false warning from Clang on a const char* +// variable declared in a conditional expression always being NULL in +// the else branch. +struct GTEST_API_ ConstCharPtr { + ConstCharPtr(const char* str) : value(str) {} + operator bool() const { return true; } + const char* value; +}; + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + +// Turns const U&, U&, const U, and U all into U. +#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ + typename std::remove_const::type>::type + +// IsAProtocolMessage::value is a compile-time bool constant that's +// true if and only if T is type proto2::Message or a subclass of it. +template +struct IsAProtocolMessage + : public bool_constant< + std::is_convertible::value> {}; + +// When the compiler sees expression IsContainerTest(0), if C is an +// STL-style container class, the first overload of IsContainerTest +// will be viable (since both C::iterator* and C::const_iterator* are +// valid types and NULL can be implicitly converted to them). It will +// be picked over the second overload as 'int' is a perfect match for +// the type of argument 0. If C::iterator or C::const_iterator is not +// a valid type, the first overload is not viable, and the second +// overload will be picked. Therefore, we can determine whether C is +// a container class by checking the type of IsContainerTest(0). +// The value of the expression is insignificant. +// +// In C++11 mode we check the existence of a const_iterator and that an +// iterator is properly implemented for the container. +// +// For pre-C++11 that we look for both C::iterator and C::const_iterator. +// The reason is that C++ injects the name of a class as a member of the +// class itself (e.g. you can refer to class iterator as either +// 'iterator' or 'iterator::iterator'). If we look for C::iterator +// only, for example, we would mistakenly think that a class named +// iterator is an STL container. +// +// Also note that the simpler approach of overloading +// IsContainerTest(typename C::const_iterator*) and +// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. +typedef int IsContainer; +template ().begin()), + class = decltype(::std::declval().end()), + class = decltype(++::std::declval()), + class = decltype(*::std::declval()), + class = typename C::const_iterator> +IsContainer IsContainerTest(int /* dummy */) { + return 0; +} + +typedef char IsNotContainer; +template +IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } + +// Trait to detect whether a type T is a hash table. +// The heuristic used is that the type contains an inner type `hasher` and does +// not contain an inner type `reverse_iterator`. +// If the container is iterable in reverse, then order might actually matter. +template +struct IsHashTable { + private: + template + static char test(typename U::hasher*, typename U::reverse_iterator*); + template + static int test(typename U::hasher*, ...); + template + static char test(...); + + public: + static const bool value = sizeof(test(nullptr, nullptr)) == sizeof(int); +}; + +template +const bool IsHashTable::value; + +template (0)) == sizeof(IsContainer)> +struct IsRecursiveContainerImpl; + +template +struct IsRecursiveContainerImpl : public std::false_type {}; + +// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to +// obey the same inconsistencies as the IsContainerTest, namely check if +// something is a container is relying on only const_iterator in C++11 and +// is relying on both const_iterator and iterator otherwise +template +struct IsRecursiveContainerImpl { + using value_type = decltype(*std::declval()); + using type = + std::is_same::type>::type, + C>; +}; + +// IsRecursiveContainer is a unary compile-time predicate that +// evaluates whether C is a recursive container type. A recursive container +// type is a container type whose value_type is equal to the container type +// itself. An example for a recursive container type is +// boost::filesystem::path, whose iterator has a value_type that is equal to +// boost::filesystem::path. +template +struct IsRecursiveContainer : public IsRecursiveContainerImpl::type {}; + +// Utilities for native arrays. + +// ArrayEq() compares two k-dimensional native arrays using the +// elements' operator==, where k can be any integer >= 0. When k is +// 0, ArrayEq() degenerates into comparing a single pair of values. + +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs); + +// This generic version is used when k is 0. +template +inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } + +// This overload is used when k >= 1. +template +inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { + return internal::ArrayEq(lhs, N, rhs); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous ArrayEq() function, arrays with different sizes would +// lead to different copies of the template code. +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs) { + for (size_t i = 0; i != size; i++) { + if (!internal::ArrayEq(lhs[i], rhs[i])) + return false; + } + return true; +} + +// Finds the first element in the iterator range [begin, end) that +// equals elem. Element may be a native array type itself. +template +Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { + for (Iter it = begin; it != end; ++it) { + if (internal::ArrayEq(*it, elem)) + return it; + } + return end; +} + +// CopyArray() copies a k-dimensional native array using the elements' +// operator=, where k can be any integer >= 0. When k is 0, +// CopyArray() degenerates into copying a single value. + +template +void CopyArray(const T* from, size_t size, U* to); + +// This generic version is used when k is 0. +template +inline void CopyArray(const T& from, U* to) { *to = from; } + +// This overload is used when k >= 1. +template +inline void CopyArray(const T(&from)[N], U(*to)[N]) { + internal::CopyArray(from, N, *to); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous CopyArray() function, arrays with different sizes +// would lead to different copies of the template code. +template +void CopyArray(const T* from, size_t size, U* to) { + for (size_t i = 0; i != size; i++) { + internal::CopyArray(from[i], to + i); + } +} + +// The relation between an NativeArray object (see below) and the +// native array it represents. +// We use 2 different structs to allow non-copyable types to be used, as long +// as RelationToSourceReference() is passed. +struct RelationToSourceReference {}; +struct RelationToSourceCopy {}; + +// Adapts a native array to a read-only STL-style container. Instead +// of the complete STL container concept, this adaptor only implements +// members useful for Google Mock's container matchers. New members +// should be added as needed. To simplify the implementation, we only +// support Element being a raw type (i.e. having no top-level const or +// reference modifier). It's the client's responsibility to satisfy +// this requirement. Element can be an array type itself (hence +// multi-dimensional arrays are supported). +template +class NativeArray { + public: + // STL-style container typedefs. + typedef Element value_type; + typedef Element* iterator; + typedef const Element* const_iterator; + + // Constructs from a native array. References the source. + NativeArray(const Element* array, size_t count, RelationToSourceReference) { + InitRef(array, count); + } + + // Constructs from a native array. Copies the source. + NativeArray(const Element* array, size_t count, RelationToSourceCopy) { + InitCopy(array, count); + } + + // Copy constructor. + NativeArray(const NativeArray& rhs) { + (this->*rhs.clone_)(rhs.array_, rhs.size_); + } + + ~NativeArray() { + if (clone_ != &NativeArray::InitRef) + delete[] array_; + } + + // STL-style container methods. + size_t size() const { return size_; } + const_iterator begin() const { return array_; } + const_iterator end() const { return array_ + size_; } + bool operator==(const NativeArray& rhs) const { + return size() == rhs.size() && + ArrayEq(begin(), size(), rhs.begin()); + } + + private: + static_assert(!std::is_const::value, "Type must not be const"); + static_assert(!std::is_reference::value, + "Type must not be a reference"); + + // Initializes this object with a copy of the input. + void InitCopy(const Element* array, size_t a_size) { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; + size_ = a_size; + clone_ = &NativeArray::InitCopy; + } + + // Initializes this object with a reference of the input. + void InitRef(const Element* array, size_t a_size) { + array_ = array; + size_ = a_size; + clone_ = &NativeArray::InitRef; + } + + const Element* array_; + size_t size_; + void (NativeArray::*clone_)(const Element*, size_t); + + GTEST_DISALLOW_ASSIGN_(NativeArray); +}; + +// Backport of std::index_sequence. +template +struct IndexSequence { + using type = IndexSequence; +}; + +// Double the IndexSequence, and one if plus_one is true. +template +struct DoubleSequence; +template +struct DoubleSequence, sizeofT> { + using type = IndexSequence; +}; +template +struct DoubleSequence, sizeofT> { + using type = IndexSequence; +}; + +// Backport of std::make_index_sequence. +// It uses O(ln(N)) instantiation depth. +template +struct MakeIndexSequence + : DoubleSequence::type, + N / 2>::type {}; + +template <> +struct MakeIndexSequence<0> : IndexSequence<> {}; + +// FIXME: This implementation of ElemFromList is O(1) in instantiation depth, +// but it is O(N^2) in total instantiations. Not sure if this is the best +// tradeoff, as it will make it somewhat slow to compile. +template +struct ElemFromListImpl {}; + +template +struct ElemFromListImpl { + using type = T; +}; + +// Get the Nth element from T... +// It uses O(1) instantiation depth. +template +struct ElemFromList; + +template +struct ElemFromList, T...> + : ElemFromListImpl... {}; + +template +class FlatTuple; + +template +struct FlatTupleElemBase; + +template +struct FlatTupleElemBase, I> { + using value_type = + typename ElemFromList::type, + T...>::type; + FlatTupleElemBase() = default; + explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {} + value_type value; +}; + +template +struct FlatTupleBase; + +template +struct FlatTupleBase, IndexSequence> + : FlatTupleElemBase, Idx>... { + using Indices = IndexSequence; + FlatTupleBase() = default; + explicit FlatTupleBase(T... t) + : FlatTupleElemBase, Idx>(std::move(t))... {} +}; + +// Analog to std::tuple but with different tradeoffs. +// This class minimizes the template instantiation depth, thus allowing more +// elements that std::tuple would. std::tuple has been seen to require an +// instantiation depth of more than 10x the number of elements in some +// implementations. +// FlatTuple and ElemFromList are not recursive and have a fixed depth +// regardless of T... +// MakeIndexSequence, on the other hand, it is recursive but with an +// instantiation depth of O(ln(N)). +template +class FlatTuple + : private FlatTupleBase, + typename MakeIndexSequence::type> { + using Indices = typename FlatTuple::FlatTupleBase::Indices; + + public: + FlatTuple() = default; + explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {} + + template + const typename ElemFromList::type& Get() const { + return static_cast*>(this)->value; + } + + template + typename ElemFromList::type& Get() { + return static_cast*>(this)->value; + } +}; + +// Utility functions to be called with static_assert to induce deprecation +// warnings. +GTEST_INTERNAL_DEPRECATED( + "INSTANTIATE_TEST_CASE_P is deprecated, please use " + "INSTANTIATE_TEST_SUITE_P") +constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; } + +GTEST_INTERNAL_DEPRECATED( + "TYPED_TEST_CASE_P is deprecated, please use " + "TYPED_TEST_SUITE_P") +constexpr bool TypedTestCase_P_IsDeprecated() { return true; } + +GTEST_INTERNAL_DEPRECATED( + "TYPED_TEST_CASE is deprecated, please use " + "TYPED_TEST_SUITE") +constexpr bool TypedTestCaseIsDeprecated() { return true; } + +GTEST_INTERNAL_DEPRECATED( + "REGISTER_TYPED_TEST_CASE_P is deprecated, please use " + "REGISTER_TYPED_TEST_SUITE_P") +constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; } + +GTEST_INTERNAL_DEPRECATED( + "INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use " + "INSTANTIATE_TYPED_TEST_SUITE_P") +constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } + +} // namespace internal +} // namespace testing + +#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ + ::testing::internal::AssertHelper(result_type, file, line, message) \ + = ::testing::Message() + +#define GTEST_MESSAGE_(message, result_type) \ + GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) + +#define GTEST_FATAL_FAILURE_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + +#define GTEST_NONFATAL_FAILURE_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + +#define GTEST_SUCCESS_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +#define GTEST_SKIP_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip) + +// Suppress MSVC warning 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::ConstCharPtr gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg.value) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail("Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws.") + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ + fail("Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't.") + + +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ + fail("Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does.") + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ + test_suite_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \ + static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \ + "test_suite_name must not be empty"); \ + static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \ + "test_name must not be empty"); \ + class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ + : public parent_class { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ + \ + private: \ + virtual void TestBody(); \ + static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name)); \ + }; \ + \ + ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name)::test_info_ = \ + ::testing::internal::MakeAndRegisterTestInfo( \ + #test_suite_name, #test_name, nullptr, nullptr, \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \ + ::testing::internal::SuiteApiResolver< \ + parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \ + ::testing::internal::SuiteApiResolver< \ + parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \ + new ::testing::internal::TestFactoryImpl); \ + void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ diff --git a/3rdparty/gtest/include/gtest/internal/gtest-param-util.h b/3rdparty/gtest/include/gtest/internal/gtest-param-util.h new file mode 100644 index 0000000..9753399 --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/gtest-param-util.h @@ -0,0 +1,883 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Type and function utilities for implementing parameterized tests. + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-port.h" +#include "gtest/gtest-printers.h" + +namespace testing { +// Input to a parameterized test name generator, describing a test parameter. +// Consists of the parameter value and the integer parameter index. +template +struct TestParamInfo { + TestParamInfo(const ParamType& a_param, size_t an_index) : + param(a_param), + index(an_index) {} + ParamType param; + size_t index; +}; + +// A builtin parameterized test name generator which returns the result of +// testing::PrintToString. +struct PrintToStringParamName { + template + std::string operator()(const TestParamInfo& info) const { + return PrintToString(info.param); + } +}; + +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// Utility Functions + +// Outputs a message explaining invalid registration of different +// fixture class for the same test suite. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name, + CodeLocation code_location); + +template class ParamGeneratorInterface; +template class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface. +template +class ParamIteratorInterface { + public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface. It wraps ParamIteratorInterface +// and implements the const forward iterator concept. +template +class ParamIterator { + public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; + + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } + + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) { + ParamIteratorInterface* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const { + return !(*this == other); + } + + private: + friend class ParamGenerator; + explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} + std::unique_ptr > impl_; +}; + +// ParamGeneratorInterface is the binary interface to access generators +// defined in other translation units. +template +class ParamGeneratorInterface { + public: + typedef T ParamType; + + virtual ~ParamGeneratorInterface() {} + + // Generator interface definition + virtual ParamIteratorInterface* Begin() const = 0; + virtual ParamIteratorInterface* End() const = 0; +}; + +// Wraps ParamGeneratorInterface and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template +class ParamGenerator { + public: + typedef ParamIterator iterator; + + explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + + ParamGenerator& operator=(const ParamGenerator& other) { + impl_ = other.impl_; + return *this; + } + + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } + + private: + std::shared_ptr > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template +class RangeGenerator : public ParamGeneratorInterface { + public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), + step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + ~RangeGenerator() override {} + + ParamIteratorInterface* Begin() const override { + return new Iterator(this, begin_, 0, step_); + } + ParamIteratorInterface* End() const override { + return new Iterator(this, end_, end_index_, step_); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + ~Iterator() override {} + + const ParamGeneratorInterface* BaseGenerator() const override { + return base_; + } + void Advance() override { + value_ = static_cast(value_ + step_); + index_++; + } + ParamIteratorInterface* Clone() const override { + return new Iterator(*this); + } + const T* Current() const override { return &value_; } + bool Equals(const ParamIteratorInterface& other) const override { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType(&other)->index_; + return index_ == other_index; + } + + private: + Iterator(const Iterator& other) + : ParamIteratorInterface(), + base_(other.base_), value_(other.value_), index_(other.index_), + step_(other.step_) {} + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator + + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) { + int end_index = 0; + for (T i = begin; i < end; i = static_cast(i + step)) + end_index++; + return end_index; + } + + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; +}; // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { + public: + template + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) {} + ~ValuesInIteratorRangeGenerator() override {} + + ParamIteratorInterface* Begin() const override { + return new Iterator(this, container_.begin()); + } + ParamIteratorInterface* End() const override { + return new Iterator(this, container_.end()); + } + + private: + typedef typename ::std::vector ContainerType; + + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + ~Iterator() override {} + + const ParamGeneratorInterface* BaseGenerator() const override { + return base_; + } + void Advance() override { + ++iterator_; + value_.reset(); + } + ParamIteratorInterface* Clone() const override { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + const T* Current() const override { + if (value_.get() == nullptr) value_.reset(new T(*iterator_)); + return value_.get(); + } + bool Equals(const ParamIteratorInterface& other) const override { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType(&other)->iterator_; + } + + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface(), + base_(other.base_), + iterator_(other.iterator_) {} + + const ParamGeneratorInterface* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of std::unique_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable std::unique_ptr value_; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); + + const ContainerType container_; +}; // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Default parameterized test name generator, returns a string containing the +// integer test parameter index. +template +std::string DefaultParamName(const TestParamInfo& info) { + Message name_stream; + name_stream << info.index; + return name_stream.GetString(); +} + +template +void TestNotEmpty() { + static_assert(sizeof(T) == 0, "Empty arguments are not allowed."); +} +template +void TestNotEmpty(const T&) {} + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template +class ParameterizedTestFactory : public TestFactoryBase { + public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : + parameter_(parameter) {} + Test* CreateTest() override { + TestClass::SetParam(¶meter_); + return new TestClass(); + } + + private: + const ParamType parameter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template +class TestMetaFactoryBase { + public: + virtual ~TestMetaFactoryBase() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestSuiteInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template +class TestMetaFactory + : public TestMetaFactoryBase { + public: + using ParamType = typename TestSuite::ParamType; + + TestMetaFactory() {} + + TestFactoryBase* CreateTestFactory(ParamType parameter) override { + return new ParameterizedTestFactory(parameter); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestSuiteInfoBase is a generic interface +// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds +// a collection of pointers to the ParameterizedTestSuiteInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestSuiteInfoBase { + public: + virtual ~ParameterizedTestSuiteInfoBase() {} + + // Base part of test suite name for display purposes. + virtual const std::string& GetTestSuiteName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestSuiteTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test suite right before running them in RUN_ALL_TESTS macro. + // This method should not be called more than once on any single + // instance of a ParameterizedTestSuiteInfoBase derived class. + virtual void RegisterTests() = 0; + + protected: + ParameterizedTestSuiteInfoBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test suite and generators +// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that +// test suite. It registers tests with all values generated by all +// generators when asked. +template +class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { + public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestSuiteInstantiation(). + using ParamType = typename TestSuite::ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator(GeneratorCreationFunc)(); + using ParamNameGeneratorFunc = std::string(const TestParamInfo&); + + explicit ParameterizedTestSuiteInfo(const char* name, + CodeLocation code_location) + : test_suite_name_(name), code_location_(code_location) {} + + // Test case base name for display purposes. + const std::string& GetTestSuiteName() const override { + return test_suite_name_; + } + // Test case id to verify identity. + TypeId GetTestSuiteTypeId() const override { return GetTypeId(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_suite_name is the base name of the test suite (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test suite base name and DoBar is test base name. + void AddTestPattern(const char* test_suite_name, const char* test_base_name, + TestMetaFactoryBase* meta_factory) { + tests_.push_back(std::shared_ptr( + new TestInfo(test_suite_name, test_base_name, meta_factory))); + } + // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestSuiteInstantiation(const std::string& instantiation_name, + GeneratorCreationFunc* func, + ParamNameGeneratorFunc* name_func, + const char* file, int line) { + instantiations_.push_back( + InstantiationInfo(instantiation_name, func, name_func, file, line)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test suite + // test suites right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more than once on any single + // instance of a ParameterizedTestSuiteInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more than once. + void RegisterTests() override { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) { + std::shared_ptr test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); gen_it != instantiations_.end(); + ++gen_it) { + const std::string& instantiation_name = gen_it->name; + ParamGenerator generator((*gen_it->generator)()); + ParamNameGeneratorFunc* name_func = gen_it->name_func; + const char* file = gen_it->file; + int line = gen_it->line; + + std::string test_suite_name; + if ( !instantiation_name.empty() ) + test_suite_name = instantiation_name + "/"; + test_suite_name += test_info->test_suite_base_name; + + size_t i = 0; + std::set test_param_names; + for (typename ParamGenerator::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) { + Message test_name_stream; + + std::string param_name = name_func( + TestParamInfo(*param_it, i)); + + GTEST_CHECK_(IsValidParamName(param_name)) + << "Parameterized test name '" << param_name + << "' is invalid, in " << file + << " line " << line << std::endl; + + GTEST_CHECK_(test_param_names.count(param_name) == 0) + << "Duplicate parameterized test name '" << param_name + << "', in " << file << " line " << line << std::endl; + + test_param_names.insert(param_name); + + if (!test_info->test_base_name.empty()) { + test_name_stream << test_info->test_base_name << "/"; + } + test_name_stream << param_name; + MakeAndRegisterTestInfo( + test_suite_name.c_str(), test_name_stream.GetString().c_str(), + nullptr, // No type parameter. + PrintToString(*param_it).c_str(), code_location_, + GetTestSuiteTypeId(), + SuiteApiResolver::GetSetUpCaseOrSuite(file, line), + SuiteApiResolver::GetTearDownCaseOrSuite(file, line), + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests + + private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo { + TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name, + TestMetaFactoryBase* a_test_meta_factory) + : test_suite_base_name(a_test_suite_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} + + const std::string test_suite_base_name; + const std::string test_base_name; + const std::unique_ptr > test_meta_factory; + }; + using TestInfoContainer = ::std::vector >; + // Records data received from INSTANTIATE_TEST_SUITE_P macros: + // + struct InstantiationInfo { + InstantiationInfo(const std::string &name_in, + GeneratorCreationFunc* generator_in, + ParamNameGeneratorFunc* name_func_in, + const char* file_in, + int line_in) + : name(name_in), + generator(generator_in), + name_func(name_func_in), + file(file_in), + line(line_in) {} + + std::string name; + GeneratorCreationFunc* generator; + ParamNameGeneratorFunc* name_func; + const char* file; + int line; + }; + typedef ::std::vector InstantiationContainer; + + static bool IsValidParamName(const std::string& name) { + // Check for empty string + if (name.empty()) + return false; + + // Check for invalid characters + for (std::string::size_type index = 0; index < name.size(); ++index) { + if (!isalnum(name[index]) && name[index] != '_') + return false; + } + + return true; + } + + const std::string test_suite_name_; + CodeLocation code_location_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo); +}; // class ParameterizedTestSuiteInfo + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +template +using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo; +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestSuiteRegistry contains a map of +// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P +// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding +// ParameterizedTestSuiteInfo descriptors. +class ParameterizedTestSuiteRegistry { + public: + ParameterizedTestSuiteRegistry() {} + ~ParameterizedTestSuiteRegistry() { + for (auto& test_suite_info : test_suite_infos_) { + delete test_suite_info; + } + } + + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test suite. + template + ParameterizedTestSuiteInfo* GetTestSuitePatternHolder( + const char* test_suite_name, CodeLocation code_location) { + ParameterizedTestSuiteInfo* typed_test_info = nullptr; + for (auto& test_suite_info : test_suite_infos_) { + if (test_suite_info->GetTestSuiteName() == test_suite_name) { + if (test_suite_info->GetTestSuiteTypeId() != GetTypeId()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test suite setup and tear-down in this case. + ReportInvalidTestSuiteType(test_suite_name, code_location); + posix::Abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestSuiteInfo >(test_suite_info); + } + break; + } + } + if (typed_test_info == nullptr) { + typed_test_info = new ParameterizedTestSuiteInfo( + test_suite_name, code_location); + test_suite_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() { + for (auto& test_suite_info : test_suite_infos_) { + test_suite_info->RegisterTests(); + } + } +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + template + ParameterizedTestCaseInfo* GetTestCasePatternHolder( + const char* test_case_name, CodeLocation code_location) { + return GetTestSuitePatternHolder(test_case_name, code_location); + } + +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + private: + using TestSuiteInfoContainer = ::std::vector; + + TestSuiteInfoContainer test_suite_infos_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry); +}; + +} // namespace internal + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template +internal::ParamGenerator ValuesIn( + const Container& container); + +namespace internal { +// Used in the Values() function to provide polymorphic capabilities. + +template +class ValueArray { + public: + ValueArray(Ts... v) : v_{std::move(v)...} {} + + template + operator ParamGenerator() const { // NOLINT + return ValuesIn(MakeVector(MakeIndexSequence())); + } + + private: + template + std::vector MakeVector(IndexSequence) const { + return std::vector{static_cast(v_.template Get())...}; + } + + FlatTuple v_; +}; + +template +class CartesianProductGenerator + : public ParamGeneratorInterface<::std::tuple> { + public: + typedef ::std::tuple ParamType; + + CartesianProductGenerator(const std::tuple...>& g) + : generators_(g) {} + ~CartesianProductGenerator() override {} + + ParamIteratorInterface* Begin() const override { + return new Iterator(this, generators_, false); + } + ParamIteratorInterface* End() const override { + return new Iterator(this, generators_, true); + } + + private: + template + class IteratorImpl; + template + class IteratorImpl> + : public ParamIteratorInterface { + public: + IteratorImpl(const ParamGeneratorInterface* base, + const std::tuple...>& generators, bool is_end) + : base_(base), + begin_(std::get(generators).begin()...), + end_(std::get(generators).end()...), + current_(is_end ? end_ : begin_) { + ComputeCurrentValue(); + } + ~IteratorImpl() override {} + + const ParamGeneratorInterface* BaseGenerator() const override { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + void Advance() override { + assert(!AtEnd()); + // Advance the last iterator. + ++std::get(current_); + // if that reaches end, propagate that up. + AdvanceIfEnd(); + ComputeCurrentValue(); + } + ParamIteratorInterface* Clone() const override { + return new IteratorImpl(*this); + } + + const ParamType* Current() const override { return current_value_.get(); } + + bool Equals(const ParamIteratorInterface& other) const override { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const IteratorImpl* typed_other = + CheckedDowncastToActualType(&other); + + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + if (AtEnd() && typed_other->AtEnd()) return true; + + bool same = true; + bool dummy[] = { + (same = same && std::get(current_) == + std::get(typed_other->current_))...}; + (void)dummy; + return same; + } + + private: + template + void AdvanceIfEnd() { + if (std::get(current_) != std::get(end_)) return; + + bool last = ThisI == 0; + if (last) { + // We are done. Nothing else to propagate. + return; + } + + constexpr size_t NextI = ThisI - (ThisI != 0); + std::get(current_) = std::get(begin_); + ++std::get(current_); + AdvanceIfEnd(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = std::make_shared(*std::get(current_)...); + } + bool AtEnd() const { + bool at_end = false; + bool dummy[] = { + (at_end = at_end || std::get(current_) == std::get(end_))...}; + (void)dummy; + return at_end; + } + + const ParamGeneratorInterface* const base_; + std::tuple::iterator...> begin_; + std::tuple::iterator...> end_; + std::tuple::iterator...> current_; + std::shared_ptr current_value_; + }; + + using Iterator = IteratorImpl::type>; + + std::tuple...> generators_; +}; + +template +class CartesianProductHolder { + public: + CartesianProductHolder(const Gen&... g) : generators_(g...) {} + template + operator ParamGenerator<::std::tuple>() const { + return ParamGenerator<::std::tuple>( + new CartesianProductGenerator(generators_)); + } + + private: + std::tuple generators_; +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ diff --git a/3rdparty/gtest/include/gtest/internal/gtest-port-arch.h b/3rdparty/gtest/include/gtest/internal/gtest-port-arch.h new file mode 100644 index 0000000..cece93d --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/gtest-port-arch.h @@ -0,0 +1,107 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This header file defines the GTEST_OS_* macro. +// It is separate from gtest-port.h so that custom/gtest-port.h can include it. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +# define GTEST_OS_CYGWIN 1 +# elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) +# define GTEST_OS_WINDOWS_MINGW 1 +# define GTEST_OS_WINDOWS 1 +#elif defined _WIN32 +# define GTEST_OS_WINDOWS 1 +# ifdef _WIN32_WCE +# define GTEST_OS_WINDOWS_MOBILE 1 +# elif defined(WINAPI_FAMILY) +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define GTEST_OS_WINDOWS_DESKTOP 1 +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +# define GTEST_OS_WINDOWS_PHONE 1 +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +# define GTEST_OS_WINDOWS_RT 1 +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) +# define GTEST_OS_WINDOWS_PHONE 1 +# define GTEST_OS_WINDOWS_TV_TITLE 1 +# else + // WINAPI_FAMILY defined but no known partition matched. + // Default to desktop. +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif +# else +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif // _WIN32_WCE +#elif defined __OS2__ +# define GTEST_OS_OS2 1 +#elif defined __APPLE__ +# define GTEST_OS_MAC 1 +# if TARGET_OS_IPHONE +# define GTEST_OS_IOS 1 +# endif +#elif defined __DragonFly__ +# define GTEST_OS_DRAGONFLY 1 +#elif defined __FreeBSD__ +# define GTEST_OS_FREEBSD 1 +#elif defined __Fuchsia__ +# define GTEST_OS_FUCHSIA 1 +#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__) +# define GTEST_OS_GNU_KFREEBSD 1 +#elif defined __linux__ +# define GTEST_OS_LINUX 1 +# if defined __ANDROID__ +# define GTEST_OS_LINUX_ANDROID 1 +# endif +#elif defined __MVS__ +# define GTEST_OS_ZOS 1 +#elif defined(__sun) && defined(__SVR4) +# define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +# define GTEST_OS_AIX 1 +#elif defined(__hpux) +# define GTEST_OS_HPUX 1 +#elif defined __native_client__ +# define GTEST_OS_NACL 1 +#elif defined __NetBSD__ +# define GTEST_OS_NETBSD 1 +#elif defined __OpenBSD__ +# define GTEST_OS_OPENBSD 1 +#elif defined __QNX__ +# define GTEST_OS_QNX 1 +#elif defined(__HAIKU__) +#define GTEST_OS_HAIKU 1 +#endif // __CYGWIN__ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ diff --git a/3rdparty/gtest/include/gtest/internal/gtest-port.h b/3rdparty/gtest/include/gtest/internal/gtest-port.h new file mode 100644 index 0000000..063fcb1 --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/gtest-port.h @@ -0,0 +1,2231 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Low-level types and utilities for porting Google Test to various +// platforms. All macros ending with _ and symbols defined in an +// internal namespace are subject to change without notice. Code +// outside Google Test MUST NOT USE THEM DIRECTLY. Macros that don't +// end with _ are part of Google Test's public API and can be used by +// code outside Google Test. +// +// This file is fundamental to Google Test. All other Google Test source +// files are expected to #include this. Therefore, it cannot #include +// any other Google Test header. + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// Environment-describing macros +// ----------------------------- +// +// Google Test can be used in many different environments. Macros in +// this section tell Google Test what kind of environment it is being +// used in, such that Google Test can provide environment-specific +// features and implementations. +// +// Google Test tries to automatically detect the properties of its +// environment, so users usually don't need to worry about these +// macros. However, the automatic detection is not perfect. +// Sometimes it's necessary for a user to define some of the following +// macros in the build script to override Google Test's decisions. +// +// If the user doesn't define a macro in the list, Google Test will +// provide a default definition. After this header is #included, all +// macros in this list will be defined to either 1 or 0. +// +// Notes to maintainers: +// - Each macro here is a user-tweakable knob; do not grow the list +// lightly. +// - Use #if to key off these macros. Don't use #ifdef or "#if +// defined(...)", which will not work as these macros are ALWAYS +// defined. +// +// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) +// is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. +// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular +// expressions are/aren't available. +// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that +// is/isn't available. +// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't +// enabled. +// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that +// std::wstring does/doesn't work (Google Test can +// be used where std::wstring is unavailable). +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_HAS_STREAM_REDIRECTION +// - Define it to 1/0 to indicate whether the +// platform supports I/O stream redirection using +// dup() and dup2(). +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. +// GTEST_DEFAULT_DEATH_TEST_STYLE +// - The default value of --gtest_death_test_style. +// The legacy default has been "fast" in the open +// source version since 2008. The recommended value +// is "threadsafe", and can be set in +// custom/gtest-port.h. + +// Platform-indicating macros +// -------------------------- +// +// Macros indicating the platform on which Google Test is being used +// (a macro is defined to 1 if compiled on the given platform; +// otherwise UNDEFINED -- it's never defined to 0.). Google Test +// defines these macros automatically. Code outside Google Test MUST +// NOT define them. +// +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_DRAGONFLY - DragonFlyBSD +// GTEST_OS_FREEBSD - FreeBSD +// GTEST_OS_FUCHSIA - Fuchsia +// GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD +// GTEST_OS_HAIKU - Haiku +// GTEST_OS_HPUX - HP-UX +// GTEST_OS_LINUX - Linux +// GTEST_OS_LINUX_ANDROID - Google Android +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_IOS - iOS +// GTEST_OS_NACL - Google Native Client (NaCl) +// GTEST_OS_NETBSD - NetBSD +// GTEST_OS_OPENBSD - OpenBSD +// GTEST_OS_OS2 - OS/2 +// GTEST_OS_QNX - QNX +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_WINDOWS_PHONE - Windows Phone +// GTEST_OS_WINDOWS_RT - Windows Store App/WinRT +// GTEST_OS_ZOS - z/OS +// +// Among the platforms, Cygwin, Linux, Mac OS X, and Windows have the +// most stable support. Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable. If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// It is possible that none of the GTEST_OS_* macros are defined. + +// Feature-indicating macros +// ------------------------- +// +// Macros indicating which Google Test features are available (a macro +// is defined to 1 if the corresponding feature is supported; +// otherwise UNDEFINED -- it's never defined to 0.). Google Test +// defines these macros automatically. Code outside Google Test MUST +// NOT define them. +// +// These macros are public so that portable tests can be written. +// Such tests typically surround code using a feature with an #if +// which controls that code. For example: +// +// #if GTEST_HAS_DEATH_TEST +// EXPECT_DEATH(DoSomethingDeadly()); +// #endif +// +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_IS_THREADSAFE - Google Test is thread-safe. +// GOOGLETEST_CM0007 DO NOT DELETE +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with +// GTEST_HAS_POSIX_RE (see above) which users can +// define themselves. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above RE\b(s) are mutually exclusive. + +// Misc public macros +// ------------------ +// +// GTEST_FLAG(flag_name) - references the variable corresponding to +// the given Google Test flag. + +// Internal utilities +// ------------------ +// +// The following macros and utilities are for Google Test's INTERNAL +// use only. Code outside Google Test MUST NOT USE THEM DIRECTLY. +// +// Macros for basic C++ coding: +// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is +// suppressed (constant conditional). +// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 +// is suppressed. +// +// Synchronization: +// Mutex, MutexLock, ThreadLocal, GetThreadCount() +// - synchronization primitives. +// +// Regular expressions: +// RE - a simple regular expression class using the POSIX +// Extended Regular Expression syntax on UNIX-like platforms +// GOOGLETEST_CM0008 DO NOT DELETE +// or a reduced regular exception syntax on other +// platforms, including Windows. +// Logging: +// GTEST_LOG_() - logs messages at the specified severity level. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. +// +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. +// CaptureStderr() - starts capturing stderr. +// GetCapturedStderr() - stops capturing stderr and returns the captured +// string. +// +// Integer types: +// TypeWithSize - maps an integer to a int type. +// Int32, UInt32, Int64, UInt64, TimeInMillis +// - integers of known sizes. +// BiggestInt - the biggest signed integer type. +// +// Command-line utilities: +// GTEST_DECLARE_*() - declares a flag. +// GTEST_DEFINE_*() - defines a flag. +// GetInjectableArgvs() - returns the command line as a vector of strings. +// +// Environment variable utilities: +// GetEnv() - gets the value of an environment variable. +// BoolFromGTestEnv() - parses a bool environment variable. +// Int32FromGTestEnv() - parses an Int32 environment variable. +// StringFromGTestEnv() - parses a string environment variable. +// +// Deprecation warnings: +// GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as +// deprecated; calling a marked function +// should generate a compiler warning + +#include // for isspace, etc +#include // for ptrdiff_t +#include +#include +#include +#include +#include + +#ifndef _WIN32_WCE +# include +# include +#endif // !_WIN32_WCE + +#if defined __APPLE__ +# include +# include +#endif + +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include +#include +#include // NOLINT + +#include "gtest/internal/gtest-port-arch.h" +#include "gtest/internal/custom/gtest-port.h" + +#if !defined(GTEST_DEV_EMAIL_) +# define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +# define GTEST_FLAG_PREFIX_ "gtest_" +# define GTEST_FLAG_PREFIX_DASH_ "gtest-" +# define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +# define GTEST_NAME_ "Google Test" +# define GTEST_PROJECT_URL_ "https://github.com/google/googletest/" +#endif // !defined(GTEST_DEV_EMAIL_) + +#if !defined(GTEST_INIT_GOOGLE_TEST_NAME_) +# define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest" +#endif // !defined(GTEST_INIT_GOOGLE_TEST_NAME_) + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +# define GTEST_GCC_VER_ \ + (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +// Macros for disabling Microsoft Visual C++ warnings. +// +// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385) +// /* code that triggers warnings C4800 and C4385 */ +// GTEST_DISABLE_MSC_WARNINGS_POP_() +#if defined(_MSC_VER) +# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \ + __pragma(warning(push)) \ + __pragma(warning(disable: warnings)) +# define GTEST_DISABLE_MSC_WARNINGS_POP_() \ + __pragma(warning(pop)) +#else +// Not all compilers are MSVC +# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) +# define GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif + +// Clang on Windows does not understand MSVC's pragma warning. +// We need clang-specific way to disable function deprecation warning. +#ifdef __clang__ +# define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ + _Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"") +#define GTEST_DISABLE_MSC_DEPRECATED_POP_() \ + _Pragma("clang diagnostic pop") +#else +# define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) +# define GTEST_DISABLE_MSC_DEPRECATED_POP_() \ + GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif + +// Brings in definitions for functions used in the testing::internal::posix +// namespace (read, write, close, chdir, isatty, stat). We do not currently +// use them on Windows Mobile. +#if GTEST_OS_WINDOWS +# if !GTEST_OS_WINDOWS_MOBILE +# include +# include +# endif +// In order to avoid having to include , use forward declaration +#if GTEST_OS_WINDOWS_MINGW && !defined(__MINGW64_VERSION_MAJOR) +// MinGW defined _CRITICAL_SECTION and _RTL_CRITICAL_SECTION as two +// separate (equivalent) structs, instead of using typedef +typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION; +#else +// Assume CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION. +// This assumption is verified by +// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION. +typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; +#endif +#else +// This assumes that non-Windows OSes provide unistd.h. For OSes where this +// is not the case, we need to include headers that provide the functions +// mentioned above. +# include +# include +#endif // GTEST_OS_WINDOWS + +#if GTEST_OS_LINUX_ANDROID +// Used to define __ANDROID_API__ matching the target NDK API level. +# include // NOLINT +#endif + +// Defines this to true if and only if Google Test can use POSIX regular +// expressions. +#ifndef GTEST_HAS_POSIX_RE +# if GTEST_OS_LINUX_ANDROID +// On Android, is only available starting with Gingerbread. +# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) +# else +# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) +# endif +#endif + +#if GTEST_USES_PCRE +// The appropriate headers have already been included. + +#elif GTEST_HAS_POSIX_RE + +// On some platforms, needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included , which is guaranteed to define size_t through +// . +# include // NOLINT + +# define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +// is not available on Windows. Use our own simple regex +// implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#else + +// may not be available on this platform. Use our own +// simple regex implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_USES_PCRE + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +# if defined(_MSC_VER) && defined(_CPPUNWIND) +// MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__BORLANDC__) +// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. +// Assumes that exceptions are enabled by default. +# ifndef _HAS_EXCEPTIONS +# define _HAS_EXCEPTIONS 1 +# endif // _HAS_EXCEPTIONS +# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +# elif defined(__clang__) +// clang defines __EXCEPTIONS if and only if exceptions are enabled before clang +// 220714, but if and only if cleanups are enabled after that. In Obj-C++ files, +// there can be cleanups for ObjC exceptions which also need cleanups, even if +// C++ exceptions are disabled. clang has __has_feature(cxx_exceptions) which +// checks for C++ exceptions starting at clang r206352, but which checked for +// cleanups prior to that. To reliably check for C++ exception availability with +// clang, check for +// __EXCEPTIONS && __has_feature(cxx_exceptions). +# define GTEST_HAS_EXCEPTIONS (__EXCEPTIONS && __has_feature(cxx_exceptions)) +# elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 if and only if exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__HP_aCC) +// Exception handling is in effect by default in HP aCC compiler. It has to +// be turned of by +noeh compiler option if desired. +# define GTEST_HAS_EXCEPTIONS 1 +# else +// For other compilers, we assume exceptions are disabled to be +// conservative. +# define GTEST_HAS_EXCEPTIONS 0 +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS + +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +# define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +# error "::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// Cygwin 1.7 and below doesn't support ::std::wstring. +// Solaris' libc++ doesn't support it either. Android has +// no support for it at least as recent as Froyo (2.2). +#define GTEST_HAS_STD_WSTRING \ + (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + GTEST_OS_HAIKU)) + +#endif // GTEST_HAS_STD_WSTRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +# ifdef _MSC_VER + +#ifdef _CPPRTTI // MSVC defines this macro if and only if RTTI is enabled. +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +// Starting with version 4.3.2, gcc defines __GXX_RTTI if and only if RTTI is +// enabled. +# elif defined(__GNUC__) + +# ifdef __GXX_RTTI +// When building against STLport with the Android NDK and with +// -frtti -fno-exceptions, the build fails at link time with undefined +// references to __cxa_bad_typeid. Note sure if STL or toolchain bug, +// so disable RTTI when detected. +# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ + !defined(__EXCEPTIONS) +# define GTEST_HAS_RTTI 0 +# else +# define GTEST_HAS_RTTI 1 +# endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS +# else +# define GTEST_HAS_RTTI 0 +# endif // __GXX_RTTI + +// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends +// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the +// first version with C++ support. +# elif defined(__clang__) + +# define GTEST_HAS_RTTI __has_feature(cxx_rtti) + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +# ifdef __RTTI_ALL__ +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +# else + +// For all other compilers, we assume RTTI is enabled. +# define GTEST_HAS_RTTI 1 + +# endif // _MSC_VER + +#endif // GTEST_HAS_RTTI + +// It's this header's responsibility to #include when RTTI +// is enabled. +#if GTEST_HAS_RTTI +# include +#endif + +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we make reasonable assumptions about +// which platforms have pthreads support. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +#define GTEST_HAS_PTHREAD \ + (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \ + GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ + GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \ + GTEST_OS_HAIKU) +#endif // GTEST_HAS_PTHREAD + +#if GTEST_HAS_PTHREAD +// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is +// true. +# include // NOLINT + +// For timespec and nanosleep, used below. +# include // NOLINT +#endif + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +# if GTEST_OS_LINUX && !defined(__ia64__) +# if GTEST_OS_LINUX_ANDROID +// On Android, clone() became available at different API levels for each 32-bit +// architecture. +# if defined(__LP64__) || \ + (defined(__arm__) && __ANDROID_API__ >= 9) || \ + (defined(__mips__) && __ANDROID_API__ >= 12) || \ + (defined(__i386__) && __ANDROID_API__ >= 17) +# define GTEST_HAS_CLONE 1 +# else +# define GTEST_HAS_CLONE 0 +# endif +# else +# define GTEST_HAS_CLONE 1 +# endif +# else +# define GTEST_HAS_CLONE 0 +# endif // GTEST_OS_LINUX && !defined(__ia64__) + +#endif // GTEST_HAS_CLONE + +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#ifndef GTEST_HAS_STREAM_REDIRECTION +// By default, we assume that stream redirection is supported on all +// platforms except known mobile ones. +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT +# define GTEST_HAS_STREAM_REDIRECTION 0 +# else +# define GTEST_HAS_STREAM_REDIRECTION 1 +# endif // !GTEST_OS_WINDOWS_MOBILE +#endif // GTEST_HAS_STREAM_REDIRECTION + +// Determines whether to support death tests. +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_MAC && !GTEST_OS_IOS) || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \ + GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \ + GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ + GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU) +# define GTEST_HAS_DEATH_TEST 1 +#endif + +// Determines whether to support type-driven tests. + +// Typed tests need and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, IBM Visual Age, and HP aCC support. +#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) || defined(__HP_aCC) +# define GTEST_HAS_TYPED_TEST 1 +# define GTEST_HAS_TYPED_TEST_P 1 +#endif + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_AIX || GTEST_OS_OS2) + +// Determines whether test results can be streamed to a socket. +#if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \ + GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD +# define GTEST_CAN_STREAM_RESULTS_ 1 +#endif + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding. This leads to problems with code like: +// +// if (gate) +// ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT +#endif + +// Use this annotation at the end of a struct/class definition to +// prevent the compiler from optimizing away instances that are never +// used. This is useful when all interesting logic happens inside the +// c'tor and / or d'tor. Example: +// +// struct Foo { +// Foo() { ... } +// } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +#if defined(__GNUC__) && !defined(COMPILER_ICC) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#elif defined(__clang__) +# if __has_attribute(unused) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +# endif +#endif +#ifndef GTEST_ATTRIBUTE_UNUSED_ +# define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// Use this annotation before a function that takes a printf format string. +#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC) +# if defined(__MINGW_PRINTF_FORMAT) +// MinGW has two different printf implementations. Ensure the format macro +// matches the selected implementation. See +// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. +# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ + __attribute__((__format__(__MINGW_PRINTF_FORMAT, string_index, \ + first_to_check))) +# else +# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ + __attribute__((__format__(__printf__, string_index, first_to_check))) +# endif +#else +# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) +#endif + + +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type) \ + void operator=(type const &) = delete + +// A macro to disallow copy constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \ + type(type const &) = delete; \ + GTEST_DISALLOW_ASSIGN_(type) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && !defined(COMPILER_ICC) +# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +# define GTEST_MUST_USE_RESULT_ +#endif // __GNUC__ && !COMPILER_ICC + +// MS C++ compiler emits warning when a conditional expression is compile time +// constant. In some contexts this warning is false positive and needs to be +// suppressed. Use the following two macros in such cases: +// +// GTEST_INTENTIONAL_CONST_COND_PUSH_() +// while (true) { +// GTEST_INTENTIONAL_CONST_COND_POP_() +// } +# define GTEST_INTENTIONAL_CONST_COND_PUSH_() \ + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127) +# define GTEST_INTENTIONAL_CONST_COND_POP_() \ + GTEST_DISABLE_MSC_WARNINGS_POP_() + +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +# if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +# define GTEST_HAS_SEH 1 +# else +// Assume no SEH. +# define GTEST_HAS_SEH 0 +# endif + +#endif // GTEST_HAS_SEH + +#ifndef GTEST_IS_THREADSAFE + +#define GTEST_IS_THREADSAFE \ + (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ || \ + (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) || \ + GTEST_HAS_PTHREAD) + +#endif // GTEST_IS_THREADSAFE + +// GTEST_API_ qualifies all symbols that must be exported. The definitions below +// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in +// gtest/internal/custom/gtest-port.h +#ifndef GTEST_API_ + +#ifdef _MSC_VER +# if GTEST_LINKED_AS_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllimport) +# elif GTEST_CREATE_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllexport) +# endif +#elif __GNUC__ >= 4 || defined(__clang__) +# define GTEST_API_ __attribute__((visibility ("default"))) +#endif // _MSC_VER + +#endif // GTEST_API_ + +#ifndef GTEST_API_ +# define GTEST_API_ +#endif // GTEST_API_ + +#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE +# define GTEST_DEFAULT_DEATH_TEST_STYLE "fast" +#endif // GTEST_DEFAULT_DEATH_TEST_STYLE + +#ifdef __GNUC__ +// Ask the compiler to never inline a given function. +# define GTEST_NO_INLINE_ __attribute__((noinline)) +#else +# define GTEST_NO_INLINE_ +#endif + +// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. +#if !defined(GTEST_HAS_CXXABI_H_) +# if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) +# define GTEST_HAS_CXXABI_H_ 1 +# else +# define GTEST_HAS_CXXABI_H_ 0 +# endif +#endif + +// A function level attribute to disable checking for use of uninitialized +// memory when built with MemorySanitizer. +#if defined(__clang__) +# if __has_feature(memory_sanitizer) +# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ \ + __attribute__((no_sanitize_memory)) +# else +# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +# endif // __has_feature(memory_sanitizer) +#else +# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +#endif // __clang__ + +// A function level attribute to disable AddressSanitizer instrumentation. +#if defined(__clang__) +# if __has_feature(address_sanitizer) +# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \ + __attribute__((no_sanitize_address)) +# else +# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +# endif // __has_feature(address_sanitizer) +#else +# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +#endif // __clang__ + +// A function level attribute to disable HWAddressSanitizer instrumentation. +#if defined(__clang__) +# if __has_feature(hwaddress_sanitizer) +# define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \ + __attribute__((no_sanitize("hwaddress"))) +# else +# define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ +# endif // __has_feature(hwaddress_sanitizer) +#else +# define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ +#endif // __clang__ + +// A function level attribute to disable ThreadSanitizer instrumentation. +#if defined(__clang__) +# if __has_feature(thread_sanitizer) +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ \ + __attribute__((no_sanitize_thread)) +# else +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +# endif // __has_feature(thread_sanitizer) +#else +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +#endif // __clang__ + +namespace testing { + +class Message; + +// Legacy imports for backwards compatibility. +// New code should use std:: names directly. +using std::get; +using std::make_tuple; +using std::tuple; +using std::tuple_element; +using std::tuple_size; + +namespace internal { + +// A secret type that Google Test users don't know about. It has no +// definition on purpose. Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// The GTEST_COMPILE_ASSERT_ is a legacy macro used to verify that a compile +// time expression is true (in new code, use static_assert instead). For +// example, you could use it to verify the size of a static array: +// +// GTEST_COMPILE_ASSERT_(GTEST_ARRAY_SIZE_(names) == NUM_NAMES, +// names_incorrect_size); +// +// The second argument to the macro must be a valid C++ identifier. If the +// expression is false, compiler will issue an error containing this identifier. +#define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg) + +// Evaluates to the number of elements in 'array'. +#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0])) + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); + +// Defines RE. + +#if GTEST_USES_PCRE +// if used, PCRE is injected by custom/gtest-port.h +#elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE + +// A simple C++ wrapper for . It uses the POSIX Extended +// Regular Expression syntax. +class GTEST_API_ RE { + public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + + RE(const char* regex) { Init(regex); } // NOLINT + ~RE(); + + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } + + // FullMatch(str, re) returns true if and only if regular expression re + // matches the entire str. + // PartialMatch(str, re) returns true if and only if regular expression re + // matches a substring of str (including str itself). + static bool FullMatch(const ::std::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); + + private: + void Init(const char* regex); + const char* pattern_; + bool is_valid_; + +# if GTEST_USES_POSIX_RE + + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). + +# else // GTEST_USES_SIMPLE_RE + + const char* full_pattern_; // For FullMatch(); + +# endif + + GTEST_DISALLOW_ASSIGN_(RE); +}; + +#endif // GTEST_USES_PCRE + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, + int line); + +// Defines logging utilities: +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL +}; + +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); + + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#if !defined(GTEST_LOG_) + +# define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(nullptr); } + +#endif // !defined(GTEST_LOG_) + +#if !defined(GTEST_CHECK_) +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +# define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " +#endif // !defined(GTEST_CHECK_) + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// Transforms "T" into "const T&" according to standard reference collapsing +// rules (this is only needed as a backport for C++98 compilers that do not +// support reference collapsing). Specifically, it transforms: +// +// char ==> const char& +// const char ==> const char& +// char& ==> char& +// const char& ==> const char& +// +// Note that the non-const reference will not have "const" added. This is +// standard, and necessary so that "T" can always bind to "const T&". +template +struct ConstRef { typedef const T& type; }; +template +struct ConstRef { typedef T& type; }; + +// The argument T must depend on some template parameters. +#define GTEST_REFERENCE_TO_CONST_(T) \ + typename ::testing::internal::ConstRef::type + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Use ImplicitCast_ as a safe version of static_cast for upcasting in +// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a +// const Foo*). When you use ImplicitCast_, the compiler checks that +// the cast is safe. Such explicit ImplicitCast_s are necessary in +// surprisingly many situations where C++ demands an exact type match +// instead of an argument type convertable to a target type. +// +// The syntax for using ImplicitCast_ is the same as for static_cast: +// +// ImplicitCast_(expr) +// +// ImplicitCast_ would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., implicit_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template +inline To ImplicitCast_(To x) { return x; } + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., down_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template // use like this: DownCast_(foo); +inline To DownCast_(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + GTEST_INTENTIONAL_CONST_COND_PUSH_() + if (false) { + GTEST_INTENTIONAL_CONST_COND_POP_() + const To to = nullptr; + ::testing::internal::ImplicitCast_(to); + } + +#if GTEST_HAS_RTTI + // RTTI: debug mode only! + GTEST_CHECK_(f == nullptr || dynamic_cast(f) != nullptr); +#endif + return static_cast(f); +} + +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); +#endif + +#if GTEST_HAS_DOWNCAST_ + return ::down_cast(base); +#elif GTEST_HAS_RTTI + return dynamic_cast(base); // NOLINT +#else + return static_cast(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. +// CaptureStderr - starts capturing stderr. +// GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ std::string GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ std::string GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION +// Returns the size (in bytes) of a file. +GTEST_API_ size_t GetFileSize(FILE* file); + +// Reads the entire content of a file as a string. +GTEST_API_ std::string ReadEntireFile(FILE* file); + +// All command line arguments. +GTEST_API_ std::vector GetArgvs(); + +#if GTEST_HAS_DEATH_TEST + +std::vector GetInjectableArgvs(); +// Deprecated: pass the args vector by value instead. +void SetInjectableArgvs(const std::vector* new_argvs); +void SetInjectableArgvs(const std::vector& new_argvs); +void ClearInjectableArgvs(); + +#endif // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. +#if GTEST_IS_THREADSAFE +# if GTEST_HAS_PTHREAD +// Sleeps for (roughly) n milliseconds. This function is only for testing +// Google Test's own constructs. Don't use it in user tests, either +// directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, nullptr); +} +# endif // GTEST_HAS_PTHREAD + +# if GTEST_HAS_NOTIFICATION_ +// Notification has already been imported into the namespace. +// Nothing to do here. + +# elif GTEST_HAS_PTHREAD +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr)); + } + ~Notification() { + pthread_mutex_destroy(&mutex_); + } + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { + pthread_mutex_lock(&mutex_); + notified_ = true; + pthread_mutex_unlock(&mutex_); + } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + for (;;) { + pthread_mutex_lock(&mutex_); + const bool notified = notified_; + pthread_mutex_unlock(&mutex_); + if (notified) + break; + SleepMilliseconds(10); + } + } + + private: + pthread_mutex_t mutex_; + bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +GTEST_API_ void SleepMilliseconds(int n); + +// Provides leak-safe Windows kernel handle ownership. +// Used in death tests and in threading support. +class GTEST_API_ AutoHandle { + public: + // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to + // avoid including in this header file. Including is + // undesirable because it defines a lot of symbols and macros that tend to + // conflict with client code. This assumption is verified by + // WindowsTypesTest.HANDLEIsVoidStar. + typedef void* Handle; + AutoHandle(); + explicit AutoHandle(Handle handle); + + ~AutoHandle(); + + Handle Get() const; + void Reset(); + void Reset(Handle handle); + + private: + // Returns true if and only if the handle is a valid handle object that can be + // closed. + bool IsCloseable() const; + + Handle handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class GTEST_API_ Notification { + public: + Notification(); + void Notify(); + void WaitForNotification(); + + private: + AutoHandle event_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; +# endif // GTEST_HAS_NOTIFICATION_ + +// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD +// defined, but we don't want to use MinGW's pthreads implementation, which +// has conformance problems with some versions of the POSIX standard. +# if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast(thread)->Run(); + return nullptr; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void UserThreadFunc(T); + + ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, nullptr, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() override { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, nullptr)); + finished_ = true; + } + } + + void Run() override { + if (thread_can_start_ != nullptr) thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + UserThreadFunc* const func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true if and only if we know that the thread function has + // finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; +# endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD || + // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ + +# if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ +// Mutex and ThreadLocal have already been imported into the namespace. +// Nothing to do here. + +# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +// Mutex implements mutex on Windows platforms. It is used in conjunction +// with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the +// // end of the current scope. +// +// A static Mutex *must* be defined or declared using one of the following +// macros: +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// (A non-static Mutex is defined/declared in the usual way). +class GTEST_API_ Mutex { + public: + enum MutexType { kStatic = 0, kDynamic = 1 }; + // We rely on kStaticMutex being 0 as it is to what the linker initializes + // type_ in static mutexes. critical_section_ will be initialized lazily + // in ThreadSafeLazyInit(). + enum StaticConstructorSelector { kStaticMutex = 0 }; + + // This constructor intentionally does nothing. It relies on type_ being + // statically initialized to 0 (effectively setting it to kStatic) and on + // ThreadSafeLazyInit() to lazily initialize the rest of the members. + explicit Mutex(StaticConstructorSelector /*dummy*/) {} + + Mutex(); + ~Mutex(); + + void Lock(); + + void Unlock(); + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld(); + + private: + // Initializes owner_thread_id_ and critical_section_ in static mutexes. + void ThreadSafeLazyInit(); + + // Per https://blogs.msdn.microsoft.com/oldnewthing/20040223-00/?p=40503, + // we assume that 0 is an invalid value for thread IDs. + unsigned int owner_thread_id_; + + // For static mutexes, we rely on these members being initialized to zeros + // by the linker. + MutexType type_; + long critical_section_init_phase_; // NOLINT + GTEST_CRITICAL_SECTION* critical_section_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex) + +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + Mutex* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Base class for ValueHolder. Allows a caller to hold and delete a value +// without knowing its type. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Provides a way for a thread to send notifications to a ThreadLocal +// regardless of its parameter type. +class ThreadLocalBase { + public: + // Creates a new ValueHolder object holding a default value passed to + // this ThreadLocal's constructor and returns it. It is the caller's + // responsibility not to call this when the ThreadLocal instance already + // has a value on the current thread. + virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0; + + protected: + ThreadLocalBase() {} + virtual ~ThreadLocalBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocalBase); +}; + +// Maps a thread to a set of ThreadLocals that have values instantiated on that +// thread and notifies them when the thread exits. A ThreadLocal instance is +// expected to persist until all threads it has values on have terminated. +class GTEST_API_ ThreadLocalRegistry { + public: + // Registers thread_local_instance as having value on the current thread. + // Returns a value that can be used to identify the thread from other threads. + static ThreadLocalValueHolderBase* GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance); + + // Invoked when a ThreadLocal instance is destroyed. + static void OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance); +}; + +class GTEST_API_ ThreadWithParamBase { + public: + void Join(); + + protected: + class Runnable { + public: + virtual ~Runnable() {} + virtual void Run() = 0; + }; + + ThreadWithParamBase(Runnable *runnable, Notification* thread_can_start); + virtual ~ThreadWithParamBase(); + + private: + AutoHandle thread_; +}; + +// Helper class for testing Google Test's multi-threading constructs. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void UserThreadFunc(T); + + ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) + : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) { + } + virtual ~ThreadWithParam() {} + + private: + class RunnableImpl : public Runnable { + public: + RunnableImpl(UserThreadFunc* func, T param) + : func_(func), + param_(param) { + } + virtual ~RunnableImpl() {} + virtual void Run() { + func_(param_); + } + + private: + UserThreadFunc* const func_; + const T param_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(RunnableImpl); + }; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// Implements thread-local storage on Windows systems. +// +// // Thread 1 +// ThreadLocal tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// The users of a TheadLocal instance have to make sure that all but one +// threads (including the main one) using that instance have exited before +// destroying it. Otherwise, the per-thread objects managed for them by the +// ThreadLocal instance are not guaranteed to be destroyed on all platforms. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template +class ThreadLocal : public ThreadLocalBase { + public: + ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {} + explicit ThreadLocal(const T& value) + : default_factory_(new InstanceValueHolderFactory(value)) {} + + ~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of T. Can be deleted via its base class without the caller + // knowing the type of T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + ValueHolder() : value_() {} + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + + T* GetOrCreateValue() const { + return static_cast( + ThreadLocalRegistry::GetValueOnCurrentThread(this))->pointer(); + } + + virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const { + return default_factory_->MakeNewHolder(); + } + + class ValueHolderFactory { + public: + ValueHolderFactory() {} + virtual ~ValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); + }; + + class DefaultValueHolderFactory : public ValueHolderFactory { + public: + DefaultValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); + }; + + class InstanceValueHolderFactory : public ValueHolderFactory { + public: + explicit InstanceValueHolderFactory(const T& value) : value_(value) {} + virtual ValueHolder* MakeNewHolder() const { + return new ValueHolder(value_); + } + + private: + const T value_; // The value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); + }; + + std::unique_ptr default_factory_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# elif GTEST_HAS_PTHREAD + +// MutexBase and Mutex implement mutex on pthreads-based platforms. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + has_owner_ = true; + } + + // Releases this mutex. + void Unlock() { + // Since the lock is being released the owner_ field should no longer be + // considered valid. We don't protect writing to has_owner_ here, as it's + // the caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + has_owner_ = false; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + // has_owner_ indicates whether the owner_ field below contains a valid thread + // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All + // accesses to the owner_ field should be protected by a check of this field. + // An alternative might be to memset() owner_ to all zeros, but there's no + // guarantee that a zero'd pthread_t is necessarily invalid or even different + // from pthread_self(). + bool has_owner_; + pthread_t owner_; // The thread holding the mutex. +}; + +// Forward-declares a static mutex. +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +// The initialization list here does not explicitly initialize each field, +// instead relying on default initialization for the unspecified fields. In +// particular, the owner_ field (a pthread_t) is not explicitly initialized. +// This allows initialization to work whether pthread_t is a scalar or struct. +// The flag -Wmissing-field-initializers must not be specified for this to work. +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0} + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr)); + has_owner_ = false; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +template +class GTEST_API_ ThreadLocal { + public: + ThreadLocal() + : key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {} + explicit ThreadLocal(const T& value) + : key_(CreateKey()), + default_factory_(new InstanceValueHolderFactory(value)) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + ValueHolder() : value_() {} + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast(pthread_getspecific(key_)); + if (holder != nullptr) { + return CheckedDowncastToActualType(holder)->pointer(); + } + + ValueHolder* const new_holder = default_factory_->MakeNewHolder(); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + class ValueHolderFactory { + public: + ValueHolderFactory() {} + virtual ~ValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); + }; + + class DefaultValueHolderFactory : public ValueHolderFactory { + public: + DefaultValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); + }; + + class InstanceValueHolderFactory : public ValueHolderFactory { + public: + explicit InstanceValueHolderFactory(const T& value) : value_(value) {} + virtual ValueHolder* MakeNewHolder() const { + return new ValueHolder(value_); + } + + private: + const T value_; // The value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); + }; + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + std::unique_ptr default_factory_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ + +#else // GTEST_IS_THREADSAFE + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable). Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: + Mutex() {} + void Lock() {} + void Unlock() {} + void AssertHeld() const {} +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex*) {} // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template +class GTEST_API_ ThreadLocal { + public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + private: + T value_; +}; + +#endif // GTEST_IS_THREADSAFE + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); + +template +using bool_constant = std::integral_constant; + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_SEP_ "\\" +# define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. +typedef __int64 BiggestInt; +#else +# define GTEST_PATH_SEP_ "/" +# define GTEST_HAS_ALT_PATH_SEP_ 0 +typedef long long BiggestInt; // NOLINT +#endif // GTEST_OS_WINDOWS + +// Utilities for char. + +// isspace(int ch) and friends accept an unsigned char or EOF. char +// may be signed, depending on the compiler (or compiler flags). +// Therefore we need to cast a char to unsigned char before calling +// isspace(), etc. + +inline bool IsAlpha(char ch) { + return isalpha(static_cast(ch)) != 0; +} +inline bool IsAlNum(char ch) { + return isalnum(static_cast(ch)) != 0; +} +inline bool IsDigit(char ch) { + return isdigit(static_cast(ch)) != 0; +} +inline bool IsLower(char ch) { + return islower(static_cast(ch)) != 0; +} +inline bool IsSpace(char ch) { + return isspace(static_cast(ch)) != 0; +} +inline bool IsUpper(char ch) { + return isupper(static_cast(ch)) != 0; +} +inline bool IsXDigit(char ch) { + return isxdigit(static_cast(ch)) != 0; +} +inline bool IsXDigit(wchar_t ch) { + const unsigned char low_byte = static_cast(ch); + return ch == low_byte && isxdigit(low_byte) != 0; +} + +inline char ToLower(char ch) { + return static_cast(tolower(static_cast(ch))); +} +inline char ToUpper(char ch) { + return static_cast(toupper(static_cast(ch))); +} + +inline std::string StripTrailingSpaces(std::string str) { + std::string::iterator it = str.end(); + while (it != str.begin() && IsSpace(*--it)) + it = str.erase(it); + return str; +} + +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +# ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +# else // !__BORLANDC__ +# if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +# else +inline int IsATTY(int fd) { return _isatty(fd); } +# endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +# endif // __BORLANDC__ + +# if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +# else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +GTEST_DISABLE_MSC_DEPRECATED_PUSH_() + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT + // We are on Windows CE, which has no environment variables. + static_cast(name); // To prevent 'unused argument' warning. + return nullptr; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != nullptr && env[0] != '\0') ? env : nullptr; +#else + return getenv(name); +#endif +} + +GTEST_DISABLE_MSC_DEPRECATED_POP_() + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +[[noreturn]] void Abort(); +#else +[[noreturn]] inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + +// MSVC "deprecates" snprintf and issues warnings wherever it is used. In +// order to avoid these warnings, we need to use _snprintf or _snprintf_s on +// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate +// function in order to achieve that. We use macro definition here because +// snprintf is a variadic function. +#if _MSC_VER && !GTEST_OS_WINDOWS_MOBILE +// MSVC 2005 and above support variadic macros. +# define GTEST_SNPRINTF_(buffer, size, format, ...) \ + _snprintf_s(buffer, size, size, format, __VA_ARGS__) +#elif defined(_MSC_VER) +// Windows CE does not define _snprintf_s +# define GTEST_SNPRINTF_ _snprintf +#else +# define GTEST_SNPRINTF_ snprintf +#endif + +// The maximum number a BiggestInt can represent. This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = + ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type. It maps a size in bytes to a primitive type with that +// size. e.g. +// +// TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs. Other types can be easily added in the future if need +// arises. +template +class TypeWithSize { + public: + // This prevents the user from using TypeWithSize with incorrect + // values of N. + typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: +#if GTEST_OS_WINDOWS + typedef __int64 Int; + typedef unsigned __int64 UInt; +#else + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT +#endif // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. + +// Utilities for command line flags and environment variables. + +// Macro for referencing flags. +#if !defined(GTEST_FLAG) +# define GTEST_FLAG(name) FLAGS_gtest_##name +#endif // !defined(GTEST_FLAG) + +#if !defined(GTEST_USE_OWN_FLAGFILE_FLAG_) +# define GTEST_USE_OWN_FLAGFILE_FLAG_ 1 +#endif // !defined(GTEST_USE_OWN_FLAGFILE_FLAG_) + +#if !defined(GTEST_DECLARE_bool_) +# define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver + +// Macros for declaring flags. +# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +# define GTEST_DECLARE_int32_(name) \ + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) +# define GTEST_DECLARE_string_(name) \ + GTEST_API_ extern ::std::string GTEST_FLAG(name) + +// Macros for defining flags. +# define GTEST_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val) +# define GTEST_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +# define GTEST_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) + +#endif // !defined(GTEST_DECLARE_bool_) + +// Thread annotations +#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) +# define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +# define GTEST_LOCK_EXCLUDED_(locks) +#endif // !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) + +// Parses 'str' for a 32-bit signed integer. If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +std::string OutputFlagAlsoCheckEnvVar(); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +} // namespace internal +} // namespace testing + +#if !defined(GTEST_INTERNAL_DEPRECATED) + +// Internal Macro to mark an API deprecated, for googletest usage only +// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or +// GTEST_INTERNAL_DEPRECATED(message) myFunction(); Every usage of +// a deprecated entity will trigger a warning when compiled with +// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler). +// For msvc /W3 option will need to be used +// Note that for 'other' compilers this macro evaluates to nothing to prevent +// compilations errors. +#if defined(_MSC_VER) +#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message)) +#elif defined(__GNUC__) +#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message))) +#else +#define GTEST_INTERNAL_DEPRECATED(message) +#endif + +#endif // !defined(GTEST_INTERNAL_DEPRECATED) + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ diff --git a/3rdparty/gtest/include/gtest/internal/gtest-string.h b/3rdparty/gtest/include/gtest/internal/gtest-string.h new file mode 100644 index 0000000..82aaa63 --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/gtest-string.h @@ -0,0 +1,171 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test. They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by gtest-internal.h. +// It should not be #included by other files. + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +# include +#endif + +#include +#include + +#include "gtest/internal/gtest-port.h" + +namespace testing { +namespace internal { + +// String - an abstract class holding static string utilities. +class GTEST_API_ String { + public: + // Static utility methods + + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); + +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. + + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); + + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + + // Compares two C strings. Returns true if and only if they have the same + // content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); + + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static std::string ShowWideCString(const wchar_t* wide_c_str); + + // Compares two wide C strings. Returns true if and only if they have the + // same content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + + // Compares two C strings, ignoring case. Returns true if and only if + // they have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); + + // Compares two wide C strings, ignoring case. Returns true if and only if + // they have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); + + // Returns true if and only if the given string ends with the given suffix, + // ignoring case. Any string is considered to end with an empty suffix. + static bool EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix); + + // Formats an int value as "%02d". + static std::string FormatIntWidth2(int value); // "%02d" for width == 2 + + // Formats an int value as "%X". + static std::string FormatHexInt(int value); + + // Formats an int value as "%X". + static std::string FormatHexUInt32(UInt32 value); + + // Formats a byte as "%02X". + static std::string FormatByte(unsigned char value); + + private: + String(); // Not meant to be instantiated. +}; // class String + +// Gets the content of the stringstream's buffer as an std::string. Each '\0' +// character in the buffer is replaced with "\\0". +GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ diff --git a/3rdparty/gtest/include/gtest/internal/gtest-type-util.h b/3rdparty/gtest/include/gtest/internal/gtest-type-util.h new file mode 100644 index 0000000..3d7542d --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/gtest-type-util.h @@ -0,0 +1,3335 @@ +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test suite. +// Please contact googletestframework@googlegroups.com if you need +// more. + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +#include "gtest/internal/gtest-port.h" + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# if GTEST_HAS_CXXABI_H_ +# include +# elif defined(__HP_aCC) +# include +# endif // GTEST_HASH_CXXABI_H_ + +namespace testing { +namespace internal { + +// Canonicalizes a given name with respect to the Standard C++ Library. +// This handles removing the inline namespace within `std` that is +// used by various standard libraries (e.g., `std::__1`). Names outside +// of namespace std are returned unmodified. +inline std::string CanonicalizeForStdLibVersioning(std::string s) { + static const char prefix[] = "std::__"; + if (s.compare(0, strlen(prefix), prefix) == 0) { + std::string::size_type end = s.find("::", strlen(prefix)); + if (end != s.npos) { + // Erase everything between the initial `std` and the second `::`. + s.erase(strlen("std"), end - strlen("std")); + } + } + return s; +} + +// GetTypeName() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template +std::string GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# if GTEST_HAS_CXXABI_H_ + using abi::__cxa_demangle; +# endif // GTEST_HAS_CXXABI_H_ + char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); + const std::string name_str(status == 0 ? readable_name : name); + free(readable_name); + return CanonicalizeForStdLibVersioning(name_str); +# else + return name; +# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC + +# else + + return ""; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; +template +struct Types2 { + typedef T1 Head; + typedef Types1 Tail; +}; + +template +struct Types3 { + typedef T1 Head; + typedef Types2 Tail; +}; + +template +struct Types4 { + typedef T1 Head; + typedef Types3 Tail; +}; + +template +struct Types5 { + typedef T1 Head; + typedef Types4 Tail; +}; + +template +struct Types6 { + typedef T1 Head; + typedef Types5 Tail; +}; + +template +struct Types7 { + typedef T1 Head; + typedef Types6 Tail; +}; + +template +struct Types8 { + typedef T1 Head; + typedef Types7 Tail; +}; + +template +struct Types9 { + typedef T1 Head; + typedef Types8 Tail; +}; + +template +struct Types10 { + typedef T1 Head; + typedef Types9 Tail; +}; + +template +struct Types11 { + typedef T1 Head; + typedef Types10 Tail; +}; + +template +struct Types12 { + typedef T1 Head; + typedef Types11 Tail; +}; + +template +struct Types13 { + typedef T1 Head; + typedef Types12 Tail; +}; + +template +struct Types14 { + typedef T1 Head; + typedef Types13 Tail; +}; + +template +struct Types15 { + typedef T1 Head; + typedef Types14 Tail; +}; + +template +struct Types16 { + typedef T1 Head; + typedef Types15 Tail; +}; + +template +struct Types17 { + typedef T1 Head; + typedef Types16 Tail; +}; + +template +struct Types18 { + typedef T1 Head; + typedef Types17 Tail; +}; + +template +struct Types19 { + typedef T1 Head; + typedef Types18 Tail; +}; + +template +struct Types20 { + typedef T1 Head; + typedef Types19 Tail; +}; + +template +struct Types21 { + typedef T1 Head; + typedef Types20 Tail; +}; + +template +struct Types22 { + typedef T1 Head; + typedef Types21 Tail; +}; + +template +struct Types23 { + typedef T1 Head; + typedef Types22 Tail; +}; + +template +struct Types24 { + typedef T1 Head; + typedef Types23 Tail; +}; + +template +struct Types25 { + typedef T1 Head; + typedef Types24 Tail; +}; + +template +struct Types26 { + typedef T1 Head; + typedef Types25 Tail; +}; + +template +struct Types27 { + typedef T1 Head; + typedef Types26 Tail; +}; + +template +struct Types28 { + typedef T1 Head; + typedef Types27 Tail; +}; + +template +struct Types29 { + typedef T1 Head; + typedef Types28 Tail; +}; + +template +struct Types30 { + typedef T1 Head; + typedef Types29 Tail; +}; + +template +struct Types31 { + typedef T1 Head; + typedef Types30 Tail; +}; + +template +struct Types32 { + typedef T1 Head; + typedef Types31 Tail; +}; + +template +struct Types33 { + typedef T1 Head; + typedef Types32 Tail; +}; + +template +struct Types34 { + typedef T1 Head; + typedef Types33 Tail; +}; + +template +struct Types35 { + typedef T1 Head; + typedef Types34 Tail; +}; + +template +struct Types36 { + typedef T1 Head; + typedef Types35 Tail; +}; + +template +struct Types37 { + typedef T1 Head; + typedef Types36 Tail; +}; + +template +struct Types38 { + typedef T1 Head; + typedef Types37 Tail; +}; + +template +struct Types39 { + typedef T1 Head; + typedef Types38 Tail; +}; + +template +struct Types40 { + typedef T1 Head; + typedef Types39 Tail; +}; + +template +struct Types41 { + typedef T1 Head; + typedef Types40 Tail; +}; + +template +struct Types42 { + typedef T1 Head; + typedef Types41 Tail; +}; + +template +struct Types43 { + typedef T1 Head; + typedef Types42 Tail; +}; + +template +struct Types44 { + typedef T1 Head; + typedef Types43 Tail; +}; + +template +struct Types45 { + typedef T1 Head; + typedef Types44 Tail; +}; + +template +struct Types46 { + typedef T1 Head; + typedef Types45 Tail; +}; + +template +struct Types47 { + typedef T1 Head; + typedef Types46 Tail; +}; + +template +struct Types48 { + typedef T1 Head; + typedef Types47 Tail; +}; + +template +struct Types49 { + typedef T1 Head; + typedef Types48 Tail; +}; + +template +struct Types50 { + typedef T1 Head; + typedef Types49 Tail; +}; + + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. +template +struct Types { + typedef internal::Types50 type; +}; + +template <> +struct Types { + typedef internal::Types0 type; +}; +template +struct Types { + typedef internal::Types1 type; +}; +template +struct Types { + typedef internal::Types2 type; +}; +template +struct Types { + typedef internal::Types3 type; +}; +template +struct Types { + typedef internal::Types4 type; +}; +template +struct Types { + typedef internal::Types5 type; +}; +template +struct Types { + typedef internal::Types6 type; +}; +template +struct Types { + typedef internal::Types7 type; +}; +template +struct Types { + typedef internal::Types8 type; +}; +template +struct Types { + typedef internal::Types9 type; +}; +template +struct Types { + typedef internal::Types10 type; +}; +template +struct Types { + typedef internal::Types11 type; +}; +template +struct Types { + typedef internal::Types12 type; +}; +template +struct Types { + typedef internal::Types13 type; +}; +template +struct Types { + typedef internal::Types14 type; +}; +template +struct Types { + typedef internal::Types15 type; +}; +template +struct Types { + typedef internal::Types16 type; +}; +template +struct Types { + typedef internal::Types17 type; +}; +template +struct Types { + typedef internal::Types18 type; +}; +template +struct Types { + typedef internal::Types19 type; +}; +template +struct Types { + typedef internal::Types20 type; +}; +template +struct Types { + typedef internal::Types21 type; +}; +template +struct Types { + typedef internal::Types22 type; +}; +template +struct Types { + typedef internal::Types23 type; +}; +template +struct Types { + typedef internal::Types24 type; +}; +template +struct Types { + typedef internal::Types25 type; +}; +template +struct Types { + typedef internal::Types26 type; +}; +template +struct Types { + typedef internal::Types27 type; +}; +template +struct Types { + typedef internal::Types28 type; +}; +template +struct Types { + typedef internal::Types29 type; +}; +template +struct Types { + typedef internal::Types30 type; +}; +template +struct Types { + typedef internal::Types31 type; +}; +template +struct Types { + typedef internal::Types32 type; +}; +template +struct Types { + typedef internal::Types33 type; +}; +template +struct Types { + typedef internal::Types34 type; +}; +template +struct Types { + typedef internal::Types35 type; +}; +template +struct Types { + typedef internal::Types36 type; +}; +template +struct Types { + typedef internal::Types37 type; +}; +template +struct Types { + typedef internal::Types38 type; +}; +template +struct Types { + typedef internal::Types39 type; +}; +template +struct Types { + typedef internal::Types40 type; +}; +template +struct Types { + typedef internal::Types41 type; +}; +template +struct Types { + typedef internal::Types42 type; +}; +template +struct Types { + typedef internal::Types43 type; +}; +template +struct Types { + typedef internal::Types44 type; +}; +template +struct Types { + typedef internal::Types45 type; +}; +template +struct Types { + typedef internal::Types46 type; +}; +template +struct Types { + typedef internal::Types47 type; +}; +template +struct Types { + typedef internal::Types48 type; +}; +template +struct Types { + typedef internal::Types49 type; +}; + +namespace internal { + +# define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; +template +struct Templates2 { + typedef TemplateSel Head; + typedef Templates1 Tail; +}; + +template +struct Templates3 { + typedef TemplateSel Head; + typedef Templates2 Tail; +}; + +template +struct Templates4 { + typedef TemplateSel Head; + typedef Templates3 Tail; +}; + +template +struct Templates5 { + typedef TemplateSel Head; + typedef Templates4 Tail; +}; + +template +struct Templates6 { + typedef TemplateSel Head; + typedef Templates5 Tail; +}; + +template +struct Templates7 { + typedef TemplateSel Head; + typedef Templates6 Tail; +}; + +template +struct Templates8 { + typedef TemplateSel Head; + typedef Templates7 Tail; +}; + +template +struct Templates9 { + typedef TemplateSel Head; + typedef Templates8 Tail; +}; + +template +struct Templates10 { + typedef TemplateSel Head; + typedef Templates9 Tail; +}; + +template +struct Templates11 { + typedef TemplateSel Head; + typedef Templates10 Tail; +}; + +template +struct Templates12 { + typedef TemplateSel Head; + typedef Templates11 Tail; +}; + +template +struct Templates13 { + typedef TemplateSel Head; + typedef Templates12 Tail; +}; + +template +struct Templates14 { + typedef TemplateSel Head; + typedef Templates13 Tail; +}; + +template +struct Templates15 { + typedef TemplateSel Head; + typedef Templates14 Tail; +}; + +template +struct Templates16 { + typedef TemplateSel Head; + typedef Templates15 Tail; +}; + +template +struct Templates17 { + typedef TemplateSel Head; + typedef Templates16 Tail; +}; + +template +struct Templates18 { + typedef TemplateSel Head; + typedef Templates17 Tail; +}; + +template +struct Templates19 { + typedef TemplateSel Head; + typedef Templates18 Tail; +}; + +template +struct Templates20 { + typedef TemplateSel Head; + typedef Templates19 Tail; +}; + +template +struct Templates21 { + typedef TemplateSel Head; + typedef Templates20 Tail; +}; + +template +struct Templates22 { + typedef TemplateSel Head; + typedef Templates21 Tail; +}; + +template +struct Templates23 { + typedef TemplateSel Head; + typedef Templates22 Tail; +}; + +template +struct Templates24 { + typedef TemplateSel Head; + typedef Templates23 Tail; +}; + +template +struct Templates25 { + typedef TemplateSel Head; + typedef Templates24 Tail; +}; + +template +struct Templates26 { + typedef TemplateSel Head; + typedef Templates25 Tail; +}; + +template +struct Templates27 { + typedef TemplateSel Head; + typedef Templates26 Tail; +}; + +template +struct Templates28 { + typedef TemplateSel Head; + typedef Templates27 Tail; +}; + +template +struct Templates29 { + typedef TemplateSel Head; + typedef Templates28 Tail; +}; + +template +struct Templates30 { + typedef TemplateSel Head; + typedef Templates29 Tail; +}; + +template +struct Templates31 { + typedef TemplateSel Head; + typedef Templates30 Tail; +}; + +template +struct Templates32 { + typedef TemplateSel Head; + typedef Templates31 Tail; +}; + +template +struct Templates33 { + typedef TemplateSel Head; + typedef Templates32 Tail; +}; + +template +struct Templates34 { + typedef TemplateSel Head; + typedef Templates33 Tail; +}; + +template +struct Templates35 { + typedef TemplateSel Head; + typedef Templates34 Tail; +}; + +template +struct Templates36 { + typedef TemplateSel Head; + typedef Templates35 Tail; +}; + +template +struct Templates37 { + typedef TemplateSel Head; + typedef Templates36 Tail; +}; + +template +struct Templates38 { + typedef TemplateSel Head; + typedef Templates37 Tail; +}; + +template +struct Templates39 { + typedef TemplateSel Head; + typedef Templates38 Tail; +}; + +template +struct Templates40 { + typedef TemplateSel Head; + typedef Templates39 Tail; +}; + +template +struct Templates41 { + typedef TemplateSel Head; + typedef Templates40 Tail; +}; + +template +struct Templates42 { + typedef TemplateSel Head; + typedef Templates41 Tail; +}; + +template +struct Templates43 { + typedef TemplateSel Head; + typedef Templates42 Tail; +}; + +template +struct Templates44 { + typedef TemplateSel Head; + typedef Templates43 Tail; +}; + +template +struct Templates45 { + typedef TemplateSel Head; + typedef Templates44 Tail; +}; + +template +struct Templates46 { + typedef TemplateSel Head; + typedef Templates45 Tail; +}; + +template +struct Templates47 { + typedef TemplateSel Head; + typedef Templates46 Tail; +}; + +template +struct Templates48 { + typedef TemplateSel Head; + typedef Templates47 Tail; +}; + +template +struct Templates49 { + typedef TemplateSel Head; + typedef Templates48 Tail; +}; + +template +struct Templates50 { + typedef TemplateSel Head; + typedef Templates49 Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. +template +struct Templates { + typedef Templates50 type; +}; + +template <> +struct Templates { + typedef Templates0 type; +}; +template +struct Templates { + typedef Templates1 type; +}; +template +struct Templates { + typedef Templates2 type; +}; +template +struct Templates { + typedef Templates3 type; +}; +template +struct Templates { + typedef Templates4 type; +}; +template +struct Templates { + typedef Templates5 type; +}; +template +struct Templates { + typedef Templates6 type; +}; +template +struct Templates { + typedef Templates7 type; +}; +template +struct Templates { + typedef Templates8 type; +}; +template +struct Templates { + typedef Templates9 type; +}; +template +struct Templates { + typedef Templates10 type; +}; +template +struct Templates { + typedef Templates11 type; +}; +template +struct Templates { + typedef Templates12 type; +}; +template +struct Templates { + typedef Templates13 type; +}; +template +struct Templates { + typedef Templates14 type; +}; +template +struct Templates { + typedef Templates15 type; +}; +template +struct Templates { + typedef Templates16 type; +}; +template +struct Templates { + typedef Templates17 type; +}; +template +struct Templates { + typedef Templates18 type; +}; +template +struct Templates { + typedef Templates19 type; +}; +template +struct Templates { + typedef Templates20 type; +}; +template +struct Templates { + typedef Templates21 type; +}; +template +struct Templates { + typedef Templates22 type; +}; +template +struct Templates { + typedef Templates23 type; +}; +template +struct Templates { + typedef Templates24 type; +}; +template +struct Templates { + typedef Templates25 type; +}; +template +struct Templates { + typedef Templates26 type; +}; +template +struct Templates { + typedef Templates27 type; +}; +template +struct Templates { + typedef Templates28 type; +}; +template +struct Templates { + typedef Templates29 type; +}; +template +struct Templates { + typedef Templates30 type; +}; +template +struct Templates { + typedef Templates31 type; +}; +template +struct Templates { + typedef Templates32 type; +}; +template +struct Templates { + typedef Templates33 type; +}; +template +struct Templates { + typedef Templates34 type; +}; +template +struct Templates { + typedef Templates35 type; +}; +template +struct Templates { + typedef Templates36 type; +}; +template +struct Templates { + typedef Templates37 type; +}; +template +struct Templates { + typedef Templates38 type; +}; +template +struct Templates { + typedef Templates39 type; +}; +template +struct Templates { + typedef Templates40 type; +}; +template +struct Templates { + typedef Templates41 type; +}; +template +struct Templates { + typedef Templates42 type; +}; +template +struct Templates { + typedef Templates43 type; +}; +template +struct Templates { + typedef Templates44 type; +}; +template +struct Templates { + typedef Templates45 type; +}; +template +struct Templates { + typedef Templates46 type; +}; +template +struct Templates { + typedef Templates47 type; +}; +template +struct Templates { + typedef Templates48 type; +}; +template +struct Templates { + typedef Templates49 type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_SUITE() and +// INSTANTIATE_TYPED_TEST_SUITE_P(). + +template +struct TypeList { + typedef Types1 type; +}; + +template +struct TypeList > { + typedef typename Types::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/3rdparty/gtest/include/gtest/internal/gtest-type-util.h.pump b/3rdparty/gtest/include/gtest/internal/gtest-type-util.h.pump new file mode 100644 index 0000000..5e31b7b --- /dev/null +++ b/3rdparty/gtest/include/gtest/internal/gtest-type-util.h.pump @@ -0,0 +1,302 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of type lists we want to support. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most $n types in a list, and at most $n +// type-parameterized tests in one type-parameterized test suite. +// Please contact googletestframework@googlegroups.com if you need +// more. + +// GOOGLETEST_CM0001 DO NOT DELETE + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +#include "gtest/internal/gtest-port.h" + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# if GTEST_HAS_CXXABI_H_ +# include +# elif defined(__HP_aCC) +# include +# endif // GTEST_HASH_CXXABI_H_ + +namespace testing { +namespace internal { + +// Canonicalizes a given name with respect to the Standard C++ Library. +// This handles removing the inline namespace within `std` that is +// used by various standard libraries (e.g., `std::__1`). Names outside +// of namespace std are returned unmodified. +inline std::string CanonicalizeForStdLibVersioning(std::string s) { + static const char prefix[] = "std::__"; + if (s.compare(0, strlen(prefix), prefix) == 0) { + std::string::size_type end = s.find("::", strlen(prefix)); + if (end != s.npos) { + // Erase everything between the initial `std` and the second `::`. + s.erase(strlen("std"), end - strlen("std")); + } + } + return s; +} + +// GetTypeName() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template +std::string GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# if GTEST_HAS_CXXABI_H_ + using abi::__cxa_demangle; +# endif // GTEST_HAS_CXXABI_H_ + char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); + const std::string name_str(status == 0 ? readable_name : name); + free(readable_name); + return CanonicalizeForStdLibVersioning(name_str); +# else + return name; +# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC + +# else + + return ""; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; + +$range i 2..n + +$for i [[ +$range j 1..i +$range k 2..i +template <$for j, [[typename T$j]]> +struct Types$i { + typedef T1 Head; + typedef Types$(i-1)<$for k, [[T$k]]> Tail; +}; + + +]] + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. + +$range i 1..n +template <$for i, [[typename T$i = internal::None]]> +struct Types { + typedef internal::Types$n<$for i, [[T$i]]> type; +}; + +template <> +struct Types<$for i, [[internal::None]]> { + typedef internal::Types0 type; +}; + +$range i 1..n-1 +$for i [[ +$range j 1..i +$range k i+1..n +template <$for j, [[typename T$j]]> +struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { + typedef internal::Types$i<$for j, [[T$j]]> type; +}; + +]] + +namespace internal { + +# define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; + +$range i 2..n + +$for i [[ +$range j 1..i +$range k 2..i +template <$for j, [[GTEST_TEMPLATE_ T$j]]> +struct Templates$i { + typedef TemplateSel Head; + typedef Templates$(i-1)<$for k, [[T$k]]> Tail; +}; + + +]] + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. + +$range i 1..n +template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> +struct Templates { + typedef Templates$n<$for i, [[T$i]]> type; +}; + +template <> +struct Templates<$for i, [[NoneT]]> { + typedef Templates0 type; +}; + +$range i 1..n-1 +$for i [[ +$range j 1..i +$range k i+1..n +template <$for j, [[GTEST_TEMPLATE_ T$j]]> +struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { + typedef Templates$i<$for j, [[T$j]]> type; +}; + +]] + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_SUITE() and +// INSTANTIATE_TYPED_TEST_SUITE_P(). + +template +struct TypeList { + typedef Types1 type; +}; + + +$range i 1..n +template <$for i, [[typename T$i]]> +struct TypeList > { + typedef typename Types<$for i, [[T$i]]>::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/3rdparty/gtest/samples/prime_tables.h b/3rdparty/gtest/samples/prime_tables.h new file mode 100644 index 0000000..72539bf --- /dev/null +++ b/3rdparty/gtest/samples/prime_tables.h @@ -0,0 +1,126 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +// This provides interface PrimeTable that determines whether a number is a +// prime and determines a next prime number. This interface is used +// in Google Test samples demonstrating use of parameterized tests. + +#ifndef GTEST_SAMPLES_PRIME_TABLES_H_ +#define GTEST_SAMPLES_PRIME_TABLES_H_ + +#include + +// The prime table interface. +class PrimeTable { + public: + virtual ~PrimeTable() {} + + // Returns true if and only if n is a prime number. + virtual bool IsPrime(int n) const = 0; + + // Returns the smallest prime number greater than p; or returns -1 + // if the next prime is beyond the capacity of the table. + virtual int GetNextPrime(int p) const = 0; +}; + +// Implementation #1 calculates the primes on-the-fly. +class OnTheFlyPrimeTable : public PrimeTable { + public: + bool IsPrime(int n) const override { + if (n <= 1) return false; + + for (int i = 2; i*i <= n; i++) { + // n is divisible by an integer other than 1 and itself. + if ((n % i) == 0) return false; + } + + return true; + } + + int GetNextPrime(int p) const override { + for (int n = p + 1; n > 0; n++) { + if (IsPrime(n)) return n; + } + + return -1; + } +}; + +// Implementation #2 pre-calculates the primes and stores the result +// in an array. +class PreCalculatedPrimeTable : public PrimeTable { + public: + // 'max' specifies the maximum number the prime table holds. + explicit PreCalculatedPrimeTable(int max) + : is_prime_size_(max + 1), is_prime_(new bool[max + 1]) { + CalculatePrimesUpTo(max); + } + ~PreCalculatedPrimeTable() override { delete[] is_prime_; } + + bool IsPrime(int n) const override { + return 0 <= n && n < is_prime_size_ && is_prime_[n]; + } + + int GetNextPrime(int p) const override { + for (int n = p + 1; n < is_prime_size_; n++) { + if (is_prime_[n]) return n; + } + + return -1; + } + + private: + void CalculatePrimesUpTo(int max) { + ::std::fill(is_prime_, is_prime_ + is_prime_size_, true); + is_prime_[0] = is_prime_[1] = false; + + // Checks every candidate for prime number (we know that 2 is the only even + // prime). + for (int i = 2; i*i <= max; i += i%2+1) { + if (!is_prime_[i]) continue; + + // Marks all multiples of i (except i itself) as non-prime. + // We are starting here from i-th multiplier, because all smaller + // complex numbers were already marked. + for (int j = i*i; j <= max; j += i) { + is_prime_[j] = false; + } + } + } + + const int is_prime_size_; + bool* const is_prime_; + + // Disables compiler warning "assignment operator could not be generated." + void operator=(const PreCalculatedPrimeTable& rhs); +}; + +#endif // GTEST_SAMPLES_PRIME_TABLES_H_ diff --git a/3rdparty/gtest/samples/sample1.cc b/3rdparty/gtest/samples/sample1.cc new file mode 100644 index 0000000..1d42759 --- /dev/null +++ b/3rdparty/gtest/samples/sample1.cc @@ -0,0 +1,66 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. + +#include "sample1.h" + +// Returns n! (the factorial of n). For negative n, n! is defined to be 1. +int Factorial(int n) { + int result = 1; + for (int i = 1; i <= n; i++) { + result *= i; + } + + return result; +} + +// Returns true if and only if n is a prime number. +bool IsPrime(int n) { + // Trivial case 1: small numbers + if (n <= 1) return false; + + // Trivial case 2: even numbers + if (n % 2 == 0) return n == 2; + + // Now, we have that n is odd and n >= 3. + + // Try to divide n by every odd number i, starting from 3 + for (int i = 3; ; i += 2) { + // We only have to try i up to the square root of n + if (i > n/i) break; + + // Now, we have i <= n/i < n. + // If n is divisible by i, n is not prime. + if (n % i == 0) return false; + } + + // n has no integer factor in the range (1, n), and thus is prime. + return true; +} diff --git a/3rdparty/gtest/samples/sample1.h b/3rdparty/gtest/samples/sample1.h new file mode 100644 index 0000000..12e49de --- /dev/null +++ b/3rdparty/gtest/samples/sample1.h @@ -0,0 +1,41 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. + +#ifndef GTEST_SAMPLES_SAMPLE1_H_ +#define GTEST_SAMPLES_SAMPLE1_H_ + +// Returns n! (the factorial of n). For negative n, n! is defined to be 1. +int Factorial(int n); + +// Returns true if and only if n is a prime number. +bool IsPrime(int n); + +#endif // GTEST_SAMPLES_SAMPLE1_H_ diff --git a/3rdparty/gtest/samples/sample10_unittest.cc b/3rdparty/gtest/samples/sample10_unittest.cc new file mode 100644 index 0000000..36cdac2 --- /dev/null +++ b/3rdparty/gtest/samples/sample10_unittest.cc @@ -0,0 +1,139 @@ +// Copyright 2009 Google Inc. All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// This sample shows how to use Google Test listener API to implement +// a primitive leak checker. + +#include +#include + +#include "gtest/gtest.h" +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +namespace { +// We will track memory used by this class. +class Water { + public: + // Normal Water declarations go here. + + // operator new and operator delete help us control water allocation. + void* operator new(size_t allocation_size) { + allocated_++; + return malloc(allocation_size); + } + + void operator delete(void* block, size_t /* allocation_size */) { + allocated_--; + free(block); + } + + static int allocated() { return allocated_; } + + private: + static int allocated_; +}; + +int Water::allocated_ = 0; + +// This event listener monitors how many Water objects are created and +// destroyed by each test, and reports a failure if a test leaks some Water +// objects. It does this by comparing the number of live Water objects at +// the beginning of a test and at the end of a test. +class LeakChecker : public EmptyTestEventListener { + private: + // Called before a test starts. + void OnTestStart(const TestInfo& /* test_info */) override { + initially_allocated_ = Water::allocated(); + } + + // Called after a test ends. + void OnTestEnd(const TestInfo& /* test_info */) override { + int difference = Water::allocated() - initially_allocated_; + + // You can generate a failure in any event handler except + // OnTestPartResult. Just use an appropriate Google Test assertion to do + // it. + EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!"; + } + + int initially_allocated_; +}; + +TEST(ListenersTest, DoesNotLeak) { + Water* water = new Water; + delete water; +} + +// This should fail when the --check_for_leaks command line flag is +// specified. +TEST(ListenersTest, LeaksWater) { + Water* water = new Water; + EXPECT_TRUE(water != nullptr); +} +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + bool check_for_leaks = false; + if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 ) + check_for_leaks = true; + else + printf("%s\n", "Run this program with --check_for_leaks to enable " + "custom leak checking in the tests."); + + // If we are given the --check_for_leaks command line flag, installs the + // leak checker. + if (check_for_leaks) { + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + + // Adds the leak checker to the end of the test event listener list, + // after the default text output printer and the default XML report + // generator. + // + // The order is important - it ensures that failures generated in the + // leak checker's OnTestEnd() method are processed by the text and XML + // printers *before* their OnTestEnd() methods are called, such that + // they are attributed to the right test. Remember that a listener + // receives an OnXyzStart event *after* listeners preceding it in the + // list received that event, and receives an OnXyzEnd event *before* + // listeners preceding it. + // + // We don't need to worry about deleting the new listener later, as + // Google Test will do it. + listeners.Append(new LeakChecker); + } + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/samples/sample1_unittest.cc b/3rdparty/gtest/samples/sample1_unittest.cc new file mode 100644 index 0000000..cb08b61 --- /dev/null +++ b/3rdparty/gtest/samples/sample1_unittest.cc @@ -0,0 +1,151 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. + +// This sample shows how to write a simple unit test for a function, +// using Google C++ testing framework. +// +// Writing a unit test using Google C++ testing framework is easy as 1-2-3: + + +// Step 1. Include necessary header files such that the stuff your +// test logic needs is declared. +// +// Don't forget gtest.h, which declares the testing framework. + +#include +#include "sample1.h" +#include "gtest/gtest.h" +namespace { + +// Step 2. Use the TEST macro to define your tests. +// +// TEST has two parameters: the test case name and the test name. +// After using the macro, you should define your test logic between a +// pair of braces. You can use a bunch of macros to indicate the +// success or failure of a test. EXPECT_TRUE and EXPECT_EQ are +// examples of such macros. For a complete list, see gtest.h. +// +// +// +// In Google Test, tests are grouped into test cases. This is how we +// keep test code organized. You should put logically related tests +// into the same test case. +// +// The test case name and the test name should both be valid C++ +// identifiers. And you should not use underscore (_) in the names. +// +// Google Test guarantees that each test you define is run exactly +// once, but it makes no guarantee on the order the tests are +// executed. Therefore, you should write your tests in such a way +// that their results don't depend on their order. +// +// + + +// Tests Factorial(). + +// Tests factorial of negative numbers. +TEST(FactorialTest, Negative) { + // This test is named "Negative", and belongs to the "FactorialTest" + // test case. + EXPECT_EQ(1, Factorial(-5)); + EXPECT_EQ(1, Factorial(-1)); + EXPECT_GT(Factorial(-10), 0); + + // + // + // EXPECT_EQ(expected, actual) is the same as + // + // EXPECT_TRUE((expected) == (actual)) + // + // except that it will print both the expected value and the actual + // value when the assertion fails. This is very helpful for + // debugging. Therefore in this case EXPECT_EQ is preferred. + // + // On the other hand, EXPECT_TRUE accepts any Boolean expression, + // and is thus more general. + // + // +} + +// Tests factorial of 0. +TEST(FactorialTest, Zero) { + EXPECT_EQ(1, Factorial(0)); +} + +// Tests factorial of positive numbers. +TEST(FactorialTest, Positive) { + EXPECT_EQ(1, Factorial(1)); + EXPECT_EQ(2, Factorial(2)); + EXPECT_EQ(6, Factorial(3)); + EXPECT_EQ(40320, Factorial(8)); +} + + +// Tests IsPrime() + +// Tests negative input. +TEST(IsPrimeTest, Negative) { + // This test belongs to the IsPrimeTest test case. + + EXPECT_FALSE(IsPrime(-1)); + EXPECT_FALSE(IsPrime(-2)); + EXPECT_FALSE(IsPrime(INT_MIN)); +} + +// Tests some trivial cases. +TEST(IsPrimeTest, Trivial) { + EXPECT_FALSE(IsPrime(0)); + EXPECT_FALSE(IsPrime(1)); + EXPECT_TRUE(IsPrime(2)); + EXPECT_TRUE(IsPrime(3)); +} + +// Tests positive input. +TEST(IsPrimeTest, Positive) { + EXPECT_FALSE(IsPrime(4)); + EXPECT_TRUE(IsPrime(5)); + EXPECT_FALSE(IsPrime(6)); + EXPECT_TRUE(IsPrime(23)); +} +} // namespace + +// Step 3. Call RUN_ALL_TESTS() in main(). +// +// We do this by linking in src/gtest_main.cc file, which consists of +// a main() function which calls RUN_ALL_TESTS() for us. +// +// This runs all the tests you've defined, prints the result, and +// returns 0 if successful, or 1 otherwise. +// +// Did you notice that we didn't register the tests? The +// RUN_ALL_TESTS() macro magically knows about all the tests we +// defined. Isn't this convenient? diff --git a/3rdparty/gtest/samples/sample2.cc b/3rdparty/gtest/samples/sample2.cc new file mode 100644 index 0000000..d8e8723 --- /dev/null +++ b/3rdparty/gtest/samples/sample2.cc @@ -0,0 +1,54 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. + +#include "sample2.h" + +#include + +// Clones a 0-terminated C string, allocating memory using new. +const char* MyString::CloneCString(const char* a_c_string) { + if (a_c_string == nullptr) return nullptr; + + const size_t len = strlen(a_c_string); + char* const clone = new char[ len + 1 ]; + memcpy(clone, a_c_string, len + 1); + + return clone; +} + +// Sets the 0-terminated C string this MyString object +// represents. +void MyString::Set(const char* a_c_string) { + // Makes sure this works when c_string == c_string_ + const char* const temp = MyString::CloneCString(a_c_string); + delete[] c_string_; + c_string_ = temp; +} diff --git a/3rdparty/gtest/samples/sample2.h b/3rdparty/gtest/samples/sample2.h new file mode 100644 index 0000000..e9a5a70 --- /dev/null +++ b/3rdparty/gtest/samples/sample2.h @@ -0,0 +1,81 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. + +#ifndef GTEST_SAMPLES_SAMPLE2_H_ +#define GTEST_SAMPLES_SAMPLE2_H_ + +#include + + +// A simple string class. +class MyString { + private: + const char* c_string_; + const MyString& operator=(const MyString& rhs); + + public: + // Clones a 0-terminated C string, allocating memory using new. + static const char* CloneCString(const char* a_c_string); + + //////////////////////////////////////////////////////////// + // + // C'tors + + // The default c'tor constructs a NULL string. + MyString() : c_string_(nullptr) {} + + // Constructs a MyString by cloning a 0-terminated C string. + explicit MyString(const char* a_c_string) : c_string_(nullptr) { + Set(a_c_string); + } + + // Copy c'tor + MyString(const MyString& string) : c_string_(nullptr) { + Set(string.c_string_); + } + + //////////////////////////////////////////////////////////// + // + // D'tor. MyString is intended to be a final class, so the d'tor + // doesn't need to be virtual. + ~MyString() { delete[] c_string_; } + + // Gets the 0-terminated C string this MyString object represents. + const char* c_string() const { return c_string_; } + + size_t Length() const { return c_string_ == nullptr ? 0 : strlen(c_string_); } + + // Sets the 0-terminated C string this MyString object represents. + void Set(const char* c_string); +}; + + +#endif // GTEST_SAMPLES_SAMPLE2_H_ diff --git a/3rdparty/gtest/samples/sample2_unittest.cc b/3rdparty/gtest/samples/sample2_unittest.cc new file mode 100644 index 0000000..41e31c1 --- /dev/null +++ b/3rdparty/gtest/samples/sample2_unittest.cc @@ -0,0 +1,107 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. + +// This sample shows how to write a more complex unit test for a class +// that has multiple member functions. +// +// Usually, it's a good idea to have one test for each method in your +// class. You don't have to do that exactly, but it helps to keep +// your tests organized. You may also throw in additional tests as +// needed. + +#include "sample2.h" +#include "gtest/gtest.h" +namespace { +// In this example, we test the MyString class (a simple string). + +// Tests the default c'tor. +TEST(MyString, DefaultConstructor) { + const MyString s; + + // Asserts that s.c_string() returns NULL. + // + // + // + // If we write NULL instead of + // + // static_cast(NULL) + // + // in this assertion, it will generate a warning on gcc 3.4. The + // reason is that EXPECT_EQ needs to know the types of its + // arguments in order to print them when it fails. Since NULL is + // #defined as 0, the compiler will use the formatter function for + // int to print it. However, gcc thinks that NULL should be used as + // a pointer, not an int, and therefore complains. + // + // The root of the problem is C++'s lack of distinction between the + // integer number 0 and the null pointer constant. Unfortunately, + // we have to live with this fact. + // + // + EXPECT_STREQ(nullptr, s.c_string()); + + EXPECT_EQ(0u, s.Length()); +} + +const char kHelloString[] = "Hello, world!"; + +// Tests the c'tor that accepts a C string. +TEST(MyString, ConstructorFromCString) { + const MyString s(kHelloString); + EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); + EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1, + s.Length()); +} + +// Tests the copy c'tor. +TEST(MyString, CopyConstructor) { + const MyString s1(kHelloString); + const MyString s2 = s1; + EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString)); +} + +// Tests the Set method. +TEST(MyString, Set) { + MyString s; + + s.Set(kHelloString); + EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); + + // Set should work when the input pointer is the same as the one + // already in the MyString object. + s.Set(s.c_string()); + EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); + + // Can we set the MyString to NULL? + s.Set(nullptr); + EXPECT_STREQ(nullptr, s.c_string()); +} +} // namespace diff --git a/3rdparty/gtest/samples/sample3-inl.h b/3rdparty/gtest/samples/sample3-inl.h new file mode 100644 index 0000000..80ba6b9 --- /dev/null +++ b/3rdparty/gtest/samples/sample3-inl.h @@ -0,0 +1,172 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. + +#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_ +#define GTEST_SAMPLES_SAMPLE3_INL_H_ + +#include + + +// Queue is a simple queue implemented as a singled-linked list. +// +// The element type must support copy constructor. +template // E is the element type +class Queue; + +// QueueNode is a node in a Queue, which consists of an element of +// type E and a pointer to the next node. +template // E is the element type +class QueueNode { + friend class Queue; + + public: + // Gets the element in this node. + const E& element() const { return element_; } + + // Gets the next node in the queue. + QueueNode* next() { return next_; } + const QueueNode* next() const { return next_; } + + private: + // Creates a node with a given element value. The next pointer is + // set to NULL. + explicit QueueNode(const E& an_element) + : element_(an_element), next_(nullptr) {} + + // We disable the default assignment operator and copy c'tor. + const QueueNode& operator = (const QueueNode&); + QueueNode(const QueueNode&); + + E element_; + QueueNode* next_; +}; + +template // E is the element type. +class Queue { + public: + // Creates an empty queue. + Queue() : head_(nullptr), last_(nullptr), size_(0) {} + + // D'tor. Clears the queue. + ~Queue() { Clear(); } + + // Clears the queue. + void Clear() { + if (size_ > 0) { + // 1. Deletes every node. + QueueNode* node = head_; + QueueNode* next = node->next(); + for (; ;) { + delete node; + node = next; + if (node == nullptr) break; + next = node->next(); + } + + // 2. Resets the member variables. + head_ = last_ = nullptr; + size_ = 0; + } + } + + // Gets the number of elements. + size_t Size() const { return size_; } + + // Gets the first element of the queue, or NULL if the queue is empty. + QueueNode* Head() { return head_; } + const QueueNode* Head() const { return head_; } + + // Gets the last element of the queue, or NULL if the queue is empty. + QueueNode* Last() { return last_; } + const QueueNode* Last() const { return last_; } + + // Adds an element to the end of the queue. A copy of the element is + // created using the copy constructor, and then stored in the queue. + // Changes made to the element in the queue doesn't affect the source + // object, and vice versa. + void Enqueue(const E& element) { + QueueNode* new_node = new QueueNode(element); + + if (size_ == 0) { + head_ = last_ = new_node; + size_ = 1; + } else { + last_->next_ = new_node; + last_ = new_node; + size_++; + } + } + + // Removes the head of the queue and returns it. Returns NULL if + // the queue is empty. + E* Dequeue() { + if (size_ == 0) { + return nullptr; + } + + const QueueNode* const old_head = head_; + head_ = head_->next_; + size_--; + if (size_ == 0) { + last_ = nullptr; + } + + E* element = new E(old_head->element()); + delete old_head; + + return element; + } + + // Applies a function/functor on each element of the queue, and + // returns the result in a new queue. The original queue is not + // affected. + template + Queue* Map(F function) const { + Queue* new_queue = new Queue(); + for (const QueueNode* node = head_; node != nullptr; + node = node->next_) { + new_queue->Enqueue(function(node->element())); + } + + return new_queue; + } + + private: + QueueNode* head_; // The first node of the queue. + QueueNode* last_; // The last node of the queue. + size_t size_; // The number of elements in the queue. + + // We disallow copying a queue. + Queue(const Queue&); + const Queue& operator = (const Queue&); +}; + +#endif // GTEST_SAMPLES_SAMPLE3_INL_H_ diff --git a/3rdparty/gtest/samples/sample3_unittest.cc b/3rdparty/gtest/samples/sample3_unittest.cc new file mode 100644 index 0000000..b19416d --- /dev/null +++ b/3rdparty/gtest/samples/sample3_unittest.cc @@ -0,0 +1,149 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. + +// In this example, we use a more advanced feature of Google Test called +// test fixture. +// +// A test fixture is a place to hold objects and functions shared by +// all tests in a test case. Using a test fixture avoids duplicating +// the test code necessary to initialize and cleanup those common +// objects for each test. It is also useful for defining sub-routines +// that your tests need to invoke a lot. +// +// +// +// The tests share the test fixture in the sense of code sharing, not +// data sharing. Each test is given its own fresh copy of the +// fixture. You cannot expect the data modified by one test to be +// passed on to another test, which is a bad idea. +// +// The reason for this design is that tests should be independent and +// repeatable. In particular, a test should not fail as the result of +// another test's failure. If one test depends on info produced by +// another test, then the two tests should really be one big test. +// +// The macros for indicating the success/failure of a test +// (EXPECT_TRUE, FAIL, etc) need to know what the current test is +// (when Google Test prints the test result, it tells you which test +// each failure belongs to). Technically, these macros invoke a +// member function of the Test class. Therefore, you cannot use them +// in a global function. That's why you should put test sub-routines +// in a test fixture. +// +// + +#include "sample3-inl.h" +#include "gtest/gtest.h" +namespace { +// To use a test fixture, derive a class from testing::Test. +class QueueTestSmpl3 : public testing::Test { + protected: // You should make the members protected s.t. they can be + // accessed from sub-classes. + + // virtual void SetUp() will be called before each test is run. You + // should define it if you need to initialize the variables. + // Otherwise, this can be skipped. + void SetUp() override { + q1_.Enqueue(1); + q2_.Enqueue(2); + q2_.Enqueue(3); + } + + // virtual void TearDown() will be called after each test is run. + // You should define it if there is cleanup work to do. Otherwise, + // you don't have to provide it. + // + // virtual void TearDown() { + // } + + // A helper function that some test uses. + static int Double(int n) { + return 2*n; + } + + // A helper function for testing Queue::Map(). + void MapTester(const Queue * q) { + // Creates a new queue, where each element is twice as big as the + // corresponding one in q. + const Queue * const new_q = q->Map(Double); + + // Verifies that the new queue has the same size as q. + ASSERT_EQ(q->Size(), new_q->Size()); + + // Verifies the relationship between the elements of the two queues. + for (const QueueNode*n1 = q->Head(), *n2 = new_q->Head(); + n1 != nullptr; n1 = n1->next(), n2 = n2->next()) { + EXPECT_EQ(2 * n1->element(), n2->element()); + } + + delete new_q; + } + + // Declares the variables your tests want to use. + Queue q0_; + Queue q1_; + Queue q2_; +}; + +// When you have a test fixture, you define a test using TEST_F +// instead of TEST. + +// Tests the default c'tor. +TEST_F(QueueTestSmpl3, DefaultConstructor) { + // You can access data in the test fixture here. + EXPECT_EQ(0u, q0_.Size()); +} + +// Tests Dequeue(). +TEST_F(QueueTestSmpl3, Dequeue) { + int * n = q0_.Dequeue(); + EXPECT_TRUE(n == nullptr); + + n = q1_.Dequeue(); + ASSERT_TRUE(n != nullptr); + EXPECT_EQ(1, *n); + EXPECT_EQ(0u, q1_.Size()); + delete n; + + n = q2_.Dequeue(); + ASSERT_TRUE(n != nullptr); + EXPECT_EQ(2, *n); + EXPECT_EQ(1u, q2_.Size()); + delete n; +} + +// Tests the Queue::Map() function. +TEST_F(QueueTestSmpl3, Map) { + MapTester(&q0_); + MapTester(&q1_); + MapTester(&q2_); +} +} // namespace diff --git a/3rdparty/gtest/samples/sample4.cc b/3rdparty/gtest/samples/sample4.cc new file mode 100644 index 0000000..b0ee609 --- /dev/null +++ b/3rdparty/gtest/samples/sample4.cc @@ -0,0 +1,54 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. + +#include + +#include "sample4.h" + +// Returns the current counter value, and increments it. +int Counter::Increment() { + return counter_++; +} + +// Returns the current counter value, and decrements it. +// counter can not be less than 0, return 0 in this case +int Counter::Decrement() { + if (counter_ == 0) { + return counter_; + } else { + return counter_--; + } +} + +// Prints the current counter value to STDOUT. +void Counter::Print() const { + printf("%d", counter_); +} diff --git a/3rdparty/gtest/samples/sample4.h b/3rdparty/gtest/samples/sample4.h new file mode 100644 index 0000000..e256f40 --- /dev/null +++ b/3rdparty/gtest/samples/sample4.h @@ -0,0 +1,53 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A sample program demonstrating using Google C++ testing framework. +#ifndef GTEST_SAMPLES_SAMPLE4_H_ +#define GTEST_SAMPLES_SAMPLE4_H_ + +// A simple monotonic counter. +class Counter { + private: + int counter_; + + public: + // Creates a counter that starts at 0. + Counter() : counter_(0) {} + + // Returns the current counter value, and increments it. + int Increment(); + + // Returns the current counter value, and decrements it. + int Decrement(); + + // Prints the current counter value to STDOUT. + void Print() const; +}; + +#endif // GTEST_SAMPLES_SAMPLE4_H_ diff --git a/3rdparty/gtest/samples/sample4_unittest.cc b/3rdparty/gtest/samples/sample4_unittest.cc new file mode 100644 index 0000000..d5144c0 --- /dev/null +++ b/3rdparty/gtest/samples/sample4_unittest.cc @@ -0,0 +1,53 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "sample4.h" +#include "gtest/gtest.h" + +namespace { +// Tests the Increment() method. + +TEST(Counter, Increment) { + Counter c; + + // Test that counter 0 returns 0 + EXPECT_EQ(0, c.Decrement()); + + // EXPECT_EQ() evaluates its arguments exactly once, so they + // can have side effects. + + EXPECT_EQ(0, c.Increment()); + EXPECT_EQ(1, c.Increment()); + EXPECT_EQ(2, c.Increment()); + + EXPECT_EQ(3, c.Decrement()); +} + +} // namespace diff --git a/3rdparty/gtest/samples/sample5_unittest.cc b/3rdparty/gtest/samples/sample5_unittest.cc new file mode 100644 index 0000000..0a21dd2 --- /dev/null +++ b/3rdparty/gtest/samples/sample5_unittest.cc @@ -0,0 +1,196 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// This sample teaches how to reuse a test fixture in multiple test +// cases by deriving sub-fixtures from it. +// +// When you define a test fixture, you specify the name of the test +// case that will use this fixture. Therefore, a test fixture can +// be used by only one test case. +// +// Sometimes, more than one test cases may want to use the same or +// slightly different test fixtures. For example, you may want to +// make sure that all tests for a GUI library don't leak important +// system resources like fonts and brushes. In Google Test, you do +// this by putting the shared logic in a super (as in "super class") +// test fixture, and then have each test case use a fixture derived +// from this super fixture. + +#include +#include +#include "gtest/gtest.h" +#include "sample1.h" +#include "sample3-inl.h" +namespace { +// In this sample, we want to ensure that every test finishes within +// ~5 seconds. If a test takes longer to run, we consider it a +// failure. +// +// We put the code for timing a test in a test fixture called +// "QuickTest". QuickTest is intended to be the super fixture that +// other fixtures derive from, therefore there is no test case with +// the name "QuickTest". This is OK. +// +// Later, we will derive multiple test fixtures from QuickTest. +class QuickTest : public testing::Test { + protected: + // Remember that SetUp() is run immediately before a test starts. + // This is a good place to record the start time. + void SetUp() override { start_time_ = time(nullptr); } + + // TearDown() is invoked immediately after a test finishes. Here we + // check if the test was too slow. + void TearDown() override { + // Gets the time when the test finishes + const time_t end_time = time(nullptr); + + // Asserts that the test took no more than ~5 seconds. Did you + // know that you can use assertions in SetUp() and TearDown() as + // well? + EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long."; + } + + // The UTC time (in seconds) when the test starts + time_t start_time_; +}; + + +// We derive a fixture named IntegerFunctionTest from the QuickTest +// fixture. All tests using this fixture will be automatically +// required to be quick. +class IntegerFunctionTest : public QuickTest { + // We don't need any more logic than already in the QuickTest fixture. + // Therefore the body is empty. +}; + + +// Now we can write tests in the IntegerFunctionTest test case. + +// Tests Factorial() +TEST_F(IntegerFunctionTest, Factorial) { + // Tests factorial of negative numbers. + EXPECT_EQ(1, Factorial(-5)); + EXPECT_EQ(1, Factorial(-1)); + EXPECT_GT(Factorial(-10), 0); + + // Tests factorial of 0. + EXPECT_EQ(1, Factorial(0)); + + // Tests factorial of positive numbers. + EXPECT_EQ(1, Factorial(1)); + EXPECT_EQ(2, Factorial(2)); + EXPECT_EQ(6, Factorial(3)); + EXPECT_EQ(40320, Factorial(8)); +} + + +// Tests IsPrime() +TEST_F(IntegerFunctionTest, IsPrime) { + // Tests negative input. + EXPECT_FALSE(IsPrime(-1)); + EXPECT_FALSE(IsPrime(-2)); + EXPECT_FALSE(IsPrime(INT_MIN)); + + // Tests some trivial cases. + EXPECT_FALSE(IsPrime(0)); + EXPECT_FALSE(IsPrime(1)); + EXPECT_TRUE(IsPrime(2)); + EXPECT_TRUE(IsPrime(3)); + + // Tests positive input. + EXPECT_FALSE(IsPrime(4)); + EXPECT_TRUE(IsPrime(5)); + EXPECT_FALSE(IsPrime(6)); + EXPECT_TRUE(IsPrime(23)); +} + + +// The next test case (named "QueueTest") also needs to be quick, so +// we derive another fixture from QuickTest. +// +// The QueueTest test fixture has some logic and shared objects in +// addition to what's in QuickTest already. We define the additional +// stuff inside the body of the test fixture, as usual. +class QueueTest : public QuickTest { + protected: + void SetUp() override { + // First, we need to set up the super fixture (QuickTest). + QuickTest::SetUp(); + + // Second, some additional setup for this fixture. + q1_.Enqueue(1); + q2_.Enqueue(2); + q2_.Enqueue(3); + } + + // By default, TearDown() inherits the behavior of + // QuickTest::TearDown(). As we have no additional cleaning work + // for QueueTest, we omit it here. + // + // virtual void TearDown() { + // QuickTest::TearDown(); + // } + + Queue q0_; + Queue q1_; + Queue q2_; +}; + + +// Now, let's write tests using the QueueTest fixture. + +// Tests the default constructor. +TEST_F(QueueTest, DefaultConstructor) { + EXPECT_EQ(0u, q0_.Size()); +} + +// Tests Dequeue(). +TEST_F(QueueTest, Dequeue) { + int* n = q0_.Dequeue(); + EXPECT_TRUE(n == nullptr); + + n = q1_.Dequeue(); + EXPECT_TRUE(n != nullptr); + EXPECT_EQ(1, *n); + EXPECT_EQ(0u, q1_.Size()); + delete n; + + n = q2_.Dequeue(); + EXPECT_TRUE(n != nullptr); + EXPECT_EQ(2, *n); + EXPECT_EQ(1u, q2_.Size()); + delete n; +} +} // namespace +// If necessary, you can derive further test fixtures from a derived +// fixture itself. For example, you can derive another fixture from +// QueueTest. Google Test imposes no limit on how deep the hierarchy +// can be. In practice, however, you probably don't want it to be too +// deep as to be confusing. diff --git a/3rdparty/gtest/samples/sample6_unittest.cc b/3rdparty/gtest/samples/sample6_unittest.cc new file mode 100644 index 0000000..0266e27 --- /dev/null +++ b/3rdparty/gtest/samples/sample6_unittest.cc @@ -0,0 +1,224 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// This sample shows how to test common properties of multiple +// implementations of the same interface (aka interface tests). + +// The interface and its implementations are in this header. +#include "prime_tables.h" + +#include "gtest/gtest.h" +namespace { +// First, we define some factory functions for creating instances of +// the implementations. You may be able to skip this step if all your +// implementations can be constructed the same way. + +template +PrimeTable* CreatePrimeTable(); + +template <> +PrimeTable* CreatePrimeTable() { + return new OnTheFlyPrimeTable; +} + +template <> +PrimeTable* CreatePrimeTable() { + return new PreCalculatedPrimeTable(10000); +} + +// Then we define a test fixture class template. +template +class PrimeTableTest : public testing::Test { + protected: + // The ctor calls the factory function to create a prime table + // implemented by T. + PrimeTableTest() : table_(CreatePrimeTable()) {} + + ~PrimeTableTest() override { delete table_; } + + // Note that we test an implementation via the base interface + // instead of the actual implementation class. This is important + // for keeping the tests close to the real world scenario, where the + // implementation is invoked via the base interface. It avoids + // got-yas where the implementation class has a method that shadows + // a method with the same name (but slightly different argument + // types) in the base interface, for example. + PrimeTable* const table_; +}; + +#if GTEST_HAS_TYPED_TEST + +using testing::Types; + +// Google Test offers two ways for reusing tests for different types. +// The first is called "typed tests". You should use it if you +// already know *all* the types you are gonna exercise when you write +// the tests. + +// To write a typed test case, first use +// +// TYPED_TEST_SUITE(TestCaseName, TypeList); +// +// to declare it and specify the type parameters. As with TEST_F, +// TestCaseName must match the test fixture name. + +// The list of types we want to test. +typedef Types Implementations; + +TYPED_TEST_SUITE(PrimeTableTest, Implementations); + +// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test, +// similar to TEST_F. +TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) { + // Inside the test body, you can refer to the type parameter by + // TypeParam, and refer to the fixture class by TestFixture. We + // don't need them in this example. + + // Since we are in the template world, C++ requires explicitly + // writing 'this->' when referring to members of the fixture class. + // This is something you have to learn to live with. + EXPECT_FALSE(this->table_->IsPrime(-5)); + EXPECT_FALSE(this->table_->IsPrime(0)); + EXPECT_FALSE(this->table_->IsPrime(1)); + EXPECT_FALSE(this->table_->IsPrime(4)); + EXPECT_FALSE(this->table_->IsPrime(6)); + EXPECT_FALSE(this->table_->IsPrime(100)); +} + +TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) { + EXPECT_TRUE(this->table_->IsPrime(2)); + EXPECT_TRUE(this->table_->IsPrime(3)); + EXPECT_TRUE(this->table_->IsPrime(5)); + EXPECT_TRUE(this->table_->IsPrime(7)); + EXPECT_TRUE(this->table_->IsPrime(11)); + EXPECT_TRUE(this->table_->IsPrime(131)); +} + +TYPED_TEST(PrimeTableTest, CanGetNextPrime) { + EXPECT_EQ(2, this->table_->GetNextPrime(0)); + EXPECT_EQ(3, this->table_->GetNextPrime(2)); + EXPECT_EQ(5, this->table_->GetNextPrime(3)); + EXPECT_EQ(7, this->table_->GetNextPrime(5)); + EXPECT_EQ(11, this->table_->GetNextPrime(7)); + EXPECT_EQ(131, this->table_->GetNextPrime(128)); +} + +// That's it! Google Test will repeat each TYPED_TEST for each type +// in the type list specified in TYPED_TEST_SUITE. Sit back and be +// happy that you don't have to define them multiple times. + +#endif // GTEST_HAS_TYPED_TEST + +#if GTEST_HAS_TYPED_TEST_P + +using testing::Types; + +// Sometimes, however, you don't yet know all the types that you want +// to test when you write the tests. For example, if you are the +// author of an interface and expect other people to implement it, you +// might want to write a set of tests to make sure each implementation +// conforms to some basic requirements, but you don't know what +// implementations will be written in the future. +// +// How can you write the tests without committing to the type +// parameters? That's what "type-parameterized tests" can do for you. +// It is a bit more involved than typed tests, but in return you get a +// test pattern that can be reused in many contexts, which is a big +// win. Here's how you do it: + +// First, define a test fixture class template. Here we just reuse +// the PrimeTableTest fixture defined earlier: + +template +class PrimeTableTest2 : public PrimeTableTest { +}; + +// Then, declare the test case. The argument is the name of the test +// fixture, and also the name of the test case (as usual). The _P +// suffix is for "parameterized" or "pattern". +TYPED_TEST_SUITE_P(PrimeTableTest2); + +// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test, +// similar to what you do with TEST_F. +TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) { + EXPECT_FALSE(this->table_->IsPrime(-5)); + EXPECT_FALSE(this->table_->IsPrime(0)); + EXPECT_FALSE(this->table_->IsPrime(1)); + EXPECT_FALSE(this->table_->IsPrime(4)); + EXPECT_FALSE(this->table_->IsPrime(6)); + EXPECT_FALSE(this->table_->IsPrime(100)); +} + +TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) { + EXPECT_TRUE(this->table_->IsPrime(2)); + EXPECT_TRUE(this->table_->IsPrime(3)); + EXPECT_TRUE(this->table_->IsPrime(5)); + EXPECT_TRUE(this->table_->IsPrime(7)); + EXPECT_TRUE(this->table_->IsPrime(11)); + EXPECT_TRUE(this->table_->IsPrime(131)); +} + +TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) { + EXPECT_EQ(2, this->table_->GetNextPrime(0)); + EXPECT_EQ(3, this->table_->GetNextPrime(2)); + EXPECT_EQ(5, this->table_->GetNextPrime(3)); + EXPECT_EQ(7, this->table_->GetNextPrime(5)); + EXPECT_EQ(11, this->table_->GetNextPrime(7)); + EXPECT_EQ(131, this->table_->GetNextPrime(128)); +} + +// Type-parameterized tests involve one extra step: you have to +// enumerate the tests you defined: +REGISTER_TYPED_TEST_SUITE_P( + PrimeTableTest2, // The first argument is the test case name. + // The rest of the arguments are the test names. + ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime); + +// At this point the test pattern is done. However, you don't have +// any real test yet as you haven't said which types you want to run +// the tests with. + +// To turn the abstract test pattern into real tests, you instantiate +// it with a list of types. Usually the test pattern will be defined +// in a .h file, and anyone can #include and instantiate it. You can +// even instantiate it more than once in the same program. To tell +// different instances apart, you give each of them a name, which will +// become part of the test case name and can be used in test filters. + +// The list of types we want to test. Note that it doesn't have to be +// defined at the time we write the TYPED_TEST_P()s. +typedef Types + PrimeTableImplementations; +INSTANTIATE_TYPED_TEST_SUITE_P(OnTheFlyAndPreCalculated, // Instance name + PrimeTableTest2, // Test case name + PrimeTableImplementations); // Type list + +#endif // GTEST_HAS_TYPED_TEST_P +} // namespace diff --git a/3rdparty/gtest/samples/sample7_unittest.cc b/3rdparty/gtest/samples/sample7_unittest.cc new file mode 100644 index 0000000..e0efc29 --- /dev/null +++ b/3rdparty/gtest/samples/sample7_unittest.cc @@ -0,0 +1,117 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// This sample shows how to test common properties of multiple +// implementations of an interface (aka interface tests) using +// value-parameterized tests. Each test in the test case has +// a parameter that is an interface pointer to an implementation +// tested. + +// The interface and its implementations are in this header. +#include "prime_tables.h" + +#include "gtest/gtest.h" +namespace { + +using ::testing::TestWithParam; +using ::testing::Values; + +// As a general rule, to prevent a test from affecting the tests that come +// after it, you should create and destroy the tested objects for each test +// instead of reusing them. In this sample we will define a simple factory +// function for PrimeTable objects. We will instantiate objects in test's +// SetUp() method and delete them in TearDown() method. +typedef PrimeTable* CreatePrimeTableFunc(); + +PrimeTable* CreateOnTheFlyPrimeTable() { + return new OnTheFlyPrimeTable(); +} + +template +PrimeTable* CreatePreCalculatedPrimeTable() { + return new PreCalculatedPrimeTable(max_precalculated); +} + +// Inside the test body, fixture constructor, SetUp(), and TearDown() you +// can refer to the test parameter by GetParam(). In this case, the test +// parameter is a factory function which we call in fixture's SetUp() to +// create and store an instance of PrimeTable. +class PrimeTableTestSmpl7 : public TestWithParam { + public: + ~PrimeTableTestSmpl7() override { delete table_; } + void SetUp() override { table_ = (*GetParam())(); } + void TearDown() override { + delete table_; + table_ = nullptr; + } + + protected: + PrimeTable* table_; +}; + +TEST_P(PrimeTableTestSmpl7, ReturnsFalseForNonPrimes) { + EXPECT_FALSE(table_->IsPrime(-5)); + EXPECT_FALSE(table_->IsPrime(0)); + EXPECT_FALSE(table_->IsPrime(1)); + EXPECT_FALSE(table_->IsPrime(4)); + EXPECT_FALSE(table_->IsPrime(6)); + EXPECT_FALSE(table_->IsPrime(100)); +} + +TEST_P(PrimeTableTestSmpl7, ReturnsTrueForPrimes) { + EXPECT_TRUE(table_->IsPrime(2)); + EXPECT_TRUE(table_->IsPrime(3)); + EXPECT_TRUE(table_->IsPrime(5)); + EXPECT_TRUE(table_->IsPrime(7)); + EXPECT_TRUE(table_->IsPrime(11)); + EXPECT_TRUE(table_->IsPrime(131)); +} + +TEST_P(PrimeTableTestSmpl7, CanGetNextPrime) { + EXPECT_EQ(2, table_->GetNextPrime(0)); + EXPECT_EQ(3, table_->GetNextPrime(2)); + EXPECT_EQ(5, table_->GetNextPrime(3)); + EXPECT_EQ(7, table_->GetNextPrime(5)); + EXPECT_EQ(11, table_->GetNextPrime(7)); + EXPECT_EQ(131, table_->GetNextPrime(128)); +} + +// In order to run value-parameterized tests, you need to instantiate them, +// or bind them to a list of values which will be used as test parameters. +// You can instantiate them in a different translation module, or even +// instantiate them several times. +// +// Here, we instantiate our tests with a list of two PrimeTable object +// factory functions: +INSTANTIATE_TEST_SUITE_P(OnTheFlyAndPreCalculated, PrimeTableTestSmpl7, + Values(&CreateOnTheFlyPrimeTable, + &CreatePreCalculatedPrimeTable<1000>)); + +} // namespace diff --git a/3rdparty/gtest/samples/sample8_unittest.cc b/3rdparty/gtest/samples/sample8_unittest.cc new file mode 100644 index 0000000..10488b0 --- /dev/null +++ b/3rdparty/gtest/samples/sample8_unittest.cc @@ -0,0 +1,154 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// This sample shows how to test code relying on some global flag variables. +// Combine() helps with generating all possible combinations of such flags, +// and each test is given one combination as a parameter. + +// Use class definitions to test from this header. +#include "prime_tables.h" + +#include "gtest/gtest.h" +namespace { + +// Suppose we want to introduce a new, improved implementation of PrimeTable +// which combines speed of PrecalcPrimeTable and versatility of +// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both +// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more +// appropriate under the circumstances. But in low memory conditions, it can be +// told to instantiate without PrecalcPrimeTable instance at all and use only +// OnTheFlyPrimeTable. +class HybridPrimeTable : public PrimeTable { + public: + HybridPrimeTable(bool force_on_the_fly, int max_precalculated) + : on_the_fly_impl_(new OnTheFlyPrimeTable), + precalc_impl_(force_on_the_fly + ? nullptr + : new PreCalculatedPrimeTable(max_precalculated)), + max_precalculated_(max_precalculated) {} + ~HybridPrimeTable() override { + delete on_the_fly_impl_; + delete precalc_impl_; + } + + bool IsPrime(int n) const override { + if (precalc_impl_ != nullptr && n < max_precalculated_) + return precalc_impl_->IsPrime(n); + else + return on_the_fly_impl_->IsPrime(n); + } + + int GetNextPrime(int p) const override { + int next_prime = -1; + if (precalc_impl_ != nullptr && p < max_precalculated_) + next_prime = precalc_impl_->GetNextPrime(p); + + return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p); + } + + private: + OnTheFlyPrimeTable* on_the_fly_impl_; + PreCalculatedPrimeTable* precalc_impl_; + int max_precalculated_; +}; + +using ::testing::TestWithParam; +using ::testing::Bool; +using ::testing::Values; +using ::testing::Combine; + +// To test all code paths for HybridPrimeTable we must test it with numbers +// both within and outside PreCalculatedPrimeTable's capacity and also with +// PreCalculatedPrimeTable disabled. We do this by defining fixture which will +// accept different combinations of parameters for instantiating a +// HybridPrimeTable instance. +class PrimeTableTest : public TestWithParam< ::std::tuple > { + protected: + void SetUp() override { + bool force_on_the_fly; + int max_precalculated; + std::tie(force_on_the_fly, max_precalculated) = GetParam(); + table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated); + } + void TearDown() override { + delete table_; + table_ = nullptr; + } + HybridPrimeTable* table_; +}; + +TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) { + // Inside the test body, you can refer to the test parameter by GetParam(). + // In this case, the test parameter is a PrimeTable interface pointer which + // we can use directly. + // Please note that you can also save it in the fixture's SetUp() method + // or constructor and use saved copy in the tests. + + EXPECT_FALSE(table_->IsPrime(-5)); + EXPECT_FALSE(table_->IsPrime(0)); + EXPECT_FALSE(table_->IsPrime(1)); + EXPECT_FALSE(table_->IsPrime(4)); + EXPECT_FALSE(table_->IsPrime(6)); + EXPECT_FALSE(table_->IsPrime(100)); +} + +TEST_P(PrimeTableTest, ReturnsTrueForPrimes) { + EXPECT_TRUE(table_->IsPrime(2)); + EXPECT_TRUE(table_->IsPrime(3)); + EXPECT_TRUE(table_->IsPrime(5)); + EXPECT_TRUE(table_->IsPrime(7)); + EXPECT_TRUE(table_->IsPrime(11)); + EXPECT_TRUE(table_->IsPrime(131)); +} + +TEST_P(PrimeTableTest, CanGetNextPrime) { + EXPECT_EQ(2, table_->GetNextPrime(0)); + EXPECT_EQ(3, table_->GetNextPrime(2)); + EXPECT_EQ(5, table_->GetNextPrime(3)); + EXPECT_EQ(7, table_->GetNextPrime(5)); + EXPECT_EQ(11, table_->GetNextPrime(7)); + EXPECT_EQ(131, table_->GetNextPrime(128)); +} + +// In order to run value-parameterized tests, you need to instantiate them, +// or bind them to a list of values which will be used as test parameters. +// You can instantiate them in a different translation module, or even +// instantiate them several times. +// +// Here, we instantiate our tests with a list of parameters. We must combine +// all variations of the boolean flag suppressing PrecalcPrimeTable and some +// meaningful values for tests. We choose a small value (1), and a value that +// will put some of the tested numbers beyond the capability of the +// PrecalcPrimeTable instance and some inside it (10). Combine will produce all +// possible combinations. +INSTANTIATE_TEST_SUITE_P(MeaningfulTestParameters, PrimeTableTest, + Combine(Bool(), Values(1, 10))); + +} // namespace diff --git a/3rdparty/gtest/samples/sample9_unittest.cc b/3rdparty/gtest/samples/sample9_unittest.cc new file mode 100644 index 0000000..e502d08 --- /dev/null +++ b/3rdparty/gtest/samples/sample9_unittest.cc @@ -0,0 +1,156 @@ +// Copyright 2009 Google Inc. All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// This sample shows how to use Google Test listener API to implement +// an alternative console output and how to use the UnitTest reflection API +// to enumerate test cases and tests and to inspect their results. + +#include + +#include "gtest/gtest.h" + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; +namespace { +// Provides alternative output mode which produces minimal amount of +// information about tests. +class TersePrinter : public EmptyTestEventListener { + private: + // Called before any test activity starts. + void OnTestProgramStart(const UnitTest& /* unit_test */) override {} + + // Called after all test activities have ended. + void OnTestProgramEnd(const UnitTest& unit_test) override { + fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED"); + fflush(stdout); + } + + // Called before a test starts. + void OnTestStart(const TestInfo& test_info) override { + fprintf(stdout, + "*** Test %s.%s starting.\n", + test_info.test_case_name(), + test_info.name()); + fflush(stdout); + } + + // Called after a failed assertion or a SUCCEED() invocation. + void OnTestPartResult(const TestPartResult& test_part_result) override { + fprintf(stdout, + "%s in %s:%d\n%s\n", + test_part_result.failed() ? "*** Failure" : "Success", + test_part_result.file_name(), + test_part_result.line_number(), + test_part_result.summary()); + fflush(stdout); + } + + // Called after a test ends. + void OnTestEnd(const TestInfo& test_info) override { + fprintf(stdout, + "*** Test %s.%s ending.\n", + test_info.test_case_name(), + test_info.name()); + fflush(stdout); + } +}; // class TersePrinter + +TEST(CustomOutputTest, PrintsMessage) { + printf("Printing something from the test body...\n"); +} + +TEST(CustomOutputTest, Succeeds) { + SUCCEED() << "SUCCEED() has been invoked from here"; +} + +TEST(CustomOutputTest, Fails) { + EXPECT_EQ(1, 2) + << "This test fails in order to demonstrate alternative failure messages"; +} +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + bool terse_output = false; + if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 ) + terse_output = true; + else + printf("%s\n", "Run this program with --terse_output to change the way " + "it prints its output."); + + UnitTest& unit_test = *UnitTest::GetInstance(); + + // If we are given the --terse_output command line flag, suppresses the + // standard output and attaches own result printer. + if (terse_output) { + TestEventListeners& listeners = unit_test.listeners(); + + // Removes the default console output listener from the list so it will + // not receive events from Google Test and won't print any output. Since + // this operation transfers ownership of the listener to the caller we + // have to delete it as well. + delete listeners.Release(listeners.default_result_printer()); + + // Adds the custom output listener to the list. It will now receive + // events from Google Test and print the alternative output. We don't + // have to worry about deleting it since Google Test assumes ownership + // over it after adding it to the list. + listeners.Append(new TersePrinter); + } + int ret_val = RUN_ALL_TESTS(); + + // This is an example of using the UnitTest reflection API to inspect test + // results. Here we discount failures from the tests we expected to fail. + int unexpectedly_failed_tests = 0; + for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { + const testing::TestSuite& test_suite = *unit_test.GetTestSuite(i); + for (int j = 0; j < test_suite.total_test_count(); ++j) { + const TestInfo& test_info = *test_suite.GetTestInfo(j); + // Counts failed tests that were not meant to fail (those without + // 'Fails' in the name). + if (test_info.result()->Failed() && + strcmp(test_info.name(), "Fails") != 0) { + unexpectedly_failed_tests++; + } + } + } + + // Test that were meant to fail should not affect the test program outcome. + if (unexpectedly_failed_tests == 0) + ret_val = 0; + + return ret_val; +} diff --git a/3rdparty/gtest/scripts/common.py b/3rdparty/gtest/scripts/common.py new file mode 100644 index 0000000..3c0347a --- /dev/null +++ b/3rdparty/gtest/scripts/common.py @@ -0,0 +1,83 @@ +# Copyright 2013 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Shared utilities for writing scripts for Google Test/Mock.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + + +import os +import re + + +# Matches the line from 'svn info .' output that describes what SVN +# path the current local directory corresponds to. For example, in +# a googletest SVN workspace's trunk/test directory, the output will be: +# +# URL: https://googletest.googlecode.com/svn/trunk/test +_SVN_INFO_URL_RE = re.compile(r'^URL: https://(\w+)\.googlecode\.com/svn(.*)') + + +def GetCommandOutput(command): + """Runs the shell command and returns its stdout as a list of lines.""" + + f = os.popen(command, 'r') + lines = [line.strip() for line in f.readlines()] + f.close() + return lines + + +def GetSvnInfo(): + """Returns the project name and the current SVN workspace's root path.""" + + for line in GetCommandOutput('svn info .'): + m = _SVN_INFO_URL_RE.match(line) + if m: + project = m.group(1) # googletest or googlemock + rel_path = m.group(2) + root = os.path.realpath(rel_path.count('/') * '../') + return project, root + + return None, None + + +def GetSvnTrunk(): + """Returns the current SVN workspace's trunk root path.""" + + _, root = GetSvnInfo() + return root + '/trunk' if root else None + + +def IsInGTestSvn(): + project, _ = GetSvnInfo() + return project == 'googletest' + + +def IsInGMockSvn(): + project, _ = GetSvnInfo() + return project == 'googlemock' diff --git a/3rdparty/gtest/scripts/fuse_gtest_files.py b/3rdparty/gtest/scripts/fuse_gtest_files.py new file mode 100644 index 0000000..d0dd464 --- /dev/null +++ b/3rdparty/gtest/scripts/fuse_gtest_files.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""fuse_gtest_files.py v0.2.0 +Fuses Google Test source code into a .h file and a .cc file. + +SYNOPSIS + fuse_gtest_files.py [GTEST_ROOT_DIR] OUTPUT_DIR + + Scans GTEST_ROOT_DIR for Google Test source code, and generates + two files: OUTPUT_DIR/gtest/gtest.h and OUTPUT_DIR/gtest/gtest-all.cc. + Then you can build your tests by adding OUTPUT_DIR to the include + search path and linking with OUTPUT_DIR/gtest/gtest-all.cc. These + two files contain everything you need to use Google Test. Hence + you can "install" Google Test by copying them to wherever you want. + + GTEST_ROOT_DIR can be omitted and defaults to the parent + directory of the directory holding this script. + +EXAMPLES + ./fuse_gtest_files.py fused_gtest + ./fuse_gtest_files.py path/to/unpacked/gtest fused_gtest + +This tool is experimental. In particular, it assumes that there is no +conditional inclusion of Google Test headers. Please report any +problems to googletestframework@googlegroups.com. You can read +https://github.com/google/googletest/blob/master/googletest/docs/advanced.md for +more information. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +try: + from sets import Set as set # For Python 2.3 compatibility +except ImportError: + pass +import sys + +# We assume that this file is in the scripts/ directory in the Google +# Test root directory. +DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..') + +# Regex for matching '#include "gtest/..."'. +INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gtest/.+)"') + +# Regex for matching '#include "src/..."'. +INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"') + +# Where to find the source seed files. +GTEST_H_SEED = 'include/gtest/gtest.h' +GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h' +GTEST_ALL_CC_SEED = 'src/gtest-all.cc' + +# Where to put the generated files. +GTEST_H_OUTPUT = 'gtest/gtest.h' +GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc' + + +def VerifyFileExists(directory, relative_path): + """Verifies that the given file exists; aborts on failure. + + relative_path is the file path relative to the given directory. + """ + + if not os.path.isfile(os.path.join(directory, relative_path)): + print('ERROR: Cannot find %s in directory %s.' % (relative_path, + directory)) + print('Please either specify a valid project root directory ' + 'or omit it on the command line.') + sys.exit(1) + + +def ValidateGTestRootDir(gtest_root): + """Makes sure gtest_root points to a valid gtest root directory. + + The function aborts the program on failure. + """ + + VerifyFileExists(gtest_root, GTEST_H_SEED) + VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED) + + +def VerifyOutputFile(output_dir, relative_path): + """Verifies that the given output file path is valid. + + relative_path is relative to the output_dir directory. + """ + + # Makes sure the output file either doesn't exist or can be overwritten. + output_file = os.path.join(output_dir, relative_path) + if os.path.exists(output_file): + # TODO(wan@google.com): The following user-interaction doesn't + # work with automated processes. We should provide a way for the + # Makefile to force overwriting the files. + print('%s already exists in directory %s - overwrite it? (y/N) ' % + (relative_path, output_dir)) + answer = sys.stdin.readline().strip() + if answer not in ['y', 'Y']: + print('ABORTED.') + sys.exit(1) + + # Makes sure the directory holding the output file exists; creates + # it and all its ancestors if necessary. + parent_directory = os.path.dirname(output_file) + if not os.path.isdir(parent_directory): + os.makedirs(parent_directory) + + +def ValidateOutputDir(output_dir): + """Makes sure output_dir points to a valid output directory. + + The function aborts the program on failure. + """ + + VerifyOutputFile(output_dir, GTEST_H_OUTPUT) + VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT) + + +def FuseGTestH(gtest_root, output_dir): + """Scans folder gtest_root to generate gtest/gtest.h in output_dir.""" + + output_file = open(os.path.join(output_dir, GTEST_H_OUTPUT), 'w') + processed_files = set() # Holds all gtest headers we've processed. + + def ProcessFile(gtest_header_path): + """Processes the given gtest header file.""" + + # We don't process the same header twice. + if gtest_header_path in processed_files: + return + + processed_files.add(gtest_header_path) + + # Reads each line in the given gtest header. + for line in open(os.path.join(gtest_root, gtest_header_path), 'r'): + m = INCLUDE_GTEST_FILE_REGEX.match(line) + if m: + # It's '#include "gtest/..."' - let's process it recursively. + ProcessFile('include/' + m.group(1)) + else: + # Otherwise we copy the line unchanged to the output file. + output_file.write(line) + + ProcessFile(GTEST_H_SEED) + output_file.close() + + +def FuseGTestAllCcToFile(gtest_root, output_file): + """Scans folder gtest_root to generate gtest/gtest-all.cc in output_file.""" + + processed_files = set() + + def ProcessFile(gtest_source_file): + """Processes the given gtest source file.""" + + # We don't process the same #included file twice. + if gtest_source_file in processed_files: + return + + processed_files.add(gtest_source_file) + + # Reads each line in the given gtest source file. + for line in open(os.path.join(gtest_root, gtest_source_file), 'r'): + m = INCLUDE_GTEST_FILE_REGEX.match(line) + if m: + if 'include/' + m.group(1) == GTEST_SPI_H_SEED: + # It's '#include "gtest/gtest-spi.h"'. This file is not + # #included by "gtest/gtest.h", so we need to process it. + ProcessFile(GTEST_SPI_H_SEED) + else: + # It's '#include "gtest/foo.h"' where foo is not gtest-spi. + # We treat it as '#include "gtest/gtest.h"', as all other + # gtest headers are being fused into gtest.h and cannot be + # #included directly. + + # There is no need to #include "gtest/gtest.h" more than once. + if not GTEST_H_SEED in processed_files: + processed_files.add(GTEST_H_SEED) + output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,)) + else: + m = INCLUDE_SRC_FILE_REGEX.match(line) + if m: + # It's '#include "src/foo"' - let's process it recursively. + ProcessFile(m.group(1)) + else: + output_file.write(line) + + ProcessFile(GTEST_ALL_CC_SEED) + + +def FuseGTestAllCc(gtest_root, output_dir): + """Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir.""" + + output_file = open(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w') + FuseGTestAllCcToFile(gtest_root, output_file) + output_file.close() + + +def FuseGTest(gtest_root, output_dir): + """Fuses gtest.h and gtest-all.cc.""" + + ValidateGTestRootDir(gtest_root) + ValidateOutputDir(output_dir) + + FuseGTestH(gtest_root, output_dir) + FuseGTestAllCc(gtest_root, output_dir) + + +def main(): + argc = len(sys.argv) + if argc == 2: + # fuse_gtest_files.py OUTPUT_DIR + FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1]) + elif argc == 3: + # fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR + FuseGTest(sys.argv[1], sys.argv[2]) + else: + print(__doc__) + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/3rdparty/gtest/scripts/gen_gtest_pred_impl.py b/3rdparty/gtest/scripts/gen_gtest_pred_impl.py new file mode 100644 index 0000000..b43efdf --- /dev/null +++ b/3rdparty/gtest/scripts/gen_gtest_pred_impl.py @@ -0,0 +1,730 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""gen_gtest_pred_impl.py v0.1 + +Generates the implementation of Google Test predicate assertions and +accompanying tests. + +Usage: + + gen_gtest_pred_impl.py MAX_ARITY + +where MAX_ARITY is a positive integer. + +The command generates the implementation of up-to MAX_ARITY-ary +predicate assertions, and writes it to file gtest_pred_impl.h in the +directory where the script is. It also generates the accompanying +unit test in file gtest_pred_impl_unittest.cc. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import sys +import time + +# Where this script is. +SCRIPT_DIR = os.path.dirname(sys.argv[0]) + +# Where to store the generated header. +HEADER = os.path.join(SCRIPT_DIR, '../include/gtest/gtest_pred_impl.h') + +# Where to store the generated unit test. +UNIT_TEST = os.path.join(SCRIPT_DIR, '../test/gtest_pred_impl_unittest.cc') + + +def HeaderPreamble(n): + """Returns the preamble for the header file. + + Args: + n: the maximum arity of the predicate macros to be generated. + """ + + # A map that defines the values used in the preamble template. + DEFS = { + 'today' : time.strftime('%m/%d/%Y'), + 'year' : time.strftime('%Y'), + 'command' : '%s %s' % (os.path.basename(sys.argv[0]), n), + 'n' : n + } + + return ( +"""// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is AUTOMATICALLY GENERATED on %(today)s by command +// '%(command)s'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +#include "gtest/gtest.h" + +namespace testing { + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most %(n)s. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \\ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\ + if (const ::testing::AssertionResult gtest_ar = (expression)) \\ + ; \\ + else \\ + on_failure(gtest_ar.failure_message()) +""" % DEFS) + + +def Arity(n): + """Returns the English name of the given arity.""" + + if n < 0: + return None + elif n <= 3: + return ['nullary', 'unary', 'binary', 'ternary'][n] + else: + return '%s-ary' % n + + +def Title(word): + """Returns the given word in title case. The difference between + this and string's title() method is that Title('4-ary') is '4-ary' + while '4-ary'.title() is '4-Ary'.""" + + return word[0].upper() + word[1:] + + +def OneTo(n): + """Returns the list [1, 2, 3, ..., n].""" + + return range(1, n + 1) + + +def Iter(n, format, sep=''): + """Given a positive integer n, a format string that contains 0 or + more '%s' format specs, and optionally a separator string, returns + the join of n strings, each formatted with the format string on an + iterator ranged from 1 to n. + + Example: + + Iter(3, 'v%s', sep=', ') returns 'v1, v2, v3'. + """ + + # How many '%s' specs are in format? + spec_count = len(format.split('%s')) - 1 + return sep.join([format % (spec_count * (i,)) for i in OneTo(n)]) + + +def ImplementationForArity(n): + """Returns the implementation of n-ary predicate assertions.""" + + # A map the defines the values used in the implementation template. + DEFS = { + 'n' : str(n), + 'vs' : Iter(n, 'v%s', sep=', '), + 'vts' : Iter(n, '#v%s', sep=', '), + 'arity' : Arity(n), + 'Arity' : Title(Arity(n)) + } + + impl = """ + +// Helper function for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use +// this in your code. +template +AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS + + impl += Iter(n, """, + const char* e%s""") + + impl += """, + Pred pred""" + + impl += Iter(n, """, + const T%s& v%s""") + + impl += """) { + if (pred(%(vs)s)) return AssertionSuccess(); + +""" % DEFS + + impl += ' return AssertionFailure() << pred_text << "("' + + impl += Iter(n, """ + << e%s""", sep=' << ", "') + + impl += ' << ") evaluates to false, where"' + + impl += Iter(n, """ + << "\\n" << e%s << " evaluates to " << v%s""") + + impl += """; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s. +// Don't use this in your code. +#define GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, on_failure)\\ + GTEST_ASSERT_(pred_format(%(vts)s, %(vs)s), \\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use +// this in your code. +#define GTEST_PRED%(n)s_(pred, %(vs)s, on_failure)\\ + GTEST_ASSERT_(::testing::AssertPred%(n)sHelper(#pred""" % DEFS + + impl += Iter(n, """, \\ + #v%s""") + + impl += """, \\ + pred""" + + impl += Iter(n, """, \\ + v%s""") + + impl += """), on_failure) + +// %(Arity)s predicate assertion macros. +#define EXPECT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ + GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED%(n)s(pred, %(vs)s) \\ + GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ + GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED%(n)s(pred, %(vs)s) \\ + GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_FATAL_FAILURE_) + +""" % DEFS + + return impl + + +def HeaderPostamble(): + """Returns the postamble for the header file.""" + + return """ + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +""" + + +def GenerateFile(path, content): + """Given a file path and a content string + overwrites it with the given content. + """ + print 'Updating file %s . . .' % path + f = file(path, 'w+') + print >>f, content, + f.close() + + print 'File %s has been updated.' % path + + +def GenerateHeader(n): + """Given the maximum arity n, updates the header file that implements + the predicate assertions. + """ + GenerateFile(HEADER, + HeaderPreamble(n) + + ''.join([ImplementationForArity(i) for i in OneTo(n)]) + + HeaderPostamble()) + + +def UnitTestPreamble(): + """Returns the preamble for the unit test file.""" + + # A map that defines the values used in the preamble template. + DEFS = { + 'today' : time.strftime('%m/%d/%Y'), + 'year' : time.strftime('%Y'), + 'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]), + } + + return ( +"""// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is AUTOMATICALLY GENERATED on %(today)s by command +// '%(command)s'. DO NOT EDIT BY HAND! + +// Regression test for gtest_pred_impl.h +// +// This file is generated by a script and quite long. If you intend to +// learn how Google Test works by reading its unit tests, read +// gtest_unittest.cc instead. +// +// This is intended as a regression test for the Google Test predicate +// assertions. We compile it as part of the gtest_unittest target +// only to keep the implementation tidy and compact, as it is quite +// involved to set up the stage for testing Google Test using Google +// Test itself. +// +// Currently, gtest_unittest takes ~11 seconds to run in the testing +// daemon. In the future, if it grows too large and needs much more +// time to finish, we should consider separating this file into a +// stand-alone regression test. + +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// A user-defined data type. +struct Bool { + explicit Bool(int val) : value(val != 0) {} + + bool operator>(int n) const { return value > Bool(n).value; } + + Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } + + bool operator==(const Bool& rhs) const { return value == rhs.value; } + + bool value; +}; + +// Enables Bool to be used in assertions. +std::ostream& operator<<(std::ostream& os, const Bool& x) { + return os << (x.value ? "true" : "false"); +} + +""" % DEFS) + + +def TestsForArity(n): + """Returns the tests for n-ary predicate assertions.""" + + # A map that defines the values used in the template for the tests. + DEFS = { + 'n' : n, + 'es' : Iter(n, 'e%s', sep=', '), + 'vs' : Iter(n, 'v%s', sep=', '), + 'vts' : Iter(n, '#v%s', sep=', '), + 'tvs' : Iter(n, 'T%s v%s', sep=', '), + 'int_vs' : Iter(n, 'int v%s', sep=', '), + 'Bool_vs' : Iter(n, 'Bool v%s', sep=', '), + 'types' : Iter(n, 'typename T%s', sep=', '), + 'v_sum' : Iter(n, 'v%s', sep=' + '), + 'arity' : Arity(n), + 'Arity' : Title(Arity(n)), + } + + tests = ( +"""// Sample functions/functors for testing %(arity)s predicate assertions. + +// A %(arity)s predicate function. +template <%(types)s> +bool PredFunction%(n)s(%(tvs)s) { + return %(v_sum)s > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction%(n)sInt(%(int_vs)s) { + return %(v_sum)s > 0; +} +bool PredFunction%(n)sBool(%(Bool_vs)s) { + return %(v_sum)s > 0; +} +""" % DEFS) + + tests += """ +// A %(arity)s predicate functor. +struct PredFunctor%(n)s { + template <%(types)s> + bool operator()(""" % DEFS + + tests += Iter(n, 'const T%s& v%s', sep=""", + """) + + tests += """) { + return %(v_sum)s > 0; + } +}; +""" % DEFS + + tests += """ +// A %(arity)s predicate-formatter function. +template <%(types)s> +testing::AssertionResult PredFormatFunction%(n)s(""" % DEFS + + tests += Iter(n, 'const char* e%s', sep=""", + """) + + tests += Iter(n, """, + const T%s& v%s""") + + tests += """) { + if (PredFunction%(n)s(%(vs)s)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << """ % DEFS + + tests += Iter(n, 'e%s', sep=' << " + " << ') + + tests += """ + << " is expected to be positive, but evaluates to " + << %(v_sum)s << "."; +} +""" % DEFS + + tests += """ +// A %(arity)s predicate-formatter functor. +struct PredFormatFunctor%(n)s { + template <%(types)s> + testing::AssertionResult operator()(""" % DEFS + + tests += Iter(n, 'const char* e%s', sep=""", + """) + + tests += Iter(n, """, + const T%s& v%s""") + + tests += """) const { + return PredFormatFunction%(n)s(%(es)s, %(vs)s); + } +}; +""" % DEFS + + tests += """ +// Tests for {EXPECT|ASSERT}_PRED_FORMAT%(n)s. + +class Predicate%(n)sTest : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false;""" % DEFS + + tests += """ + """ + Iter(n, 'n%s_ = ') + """0; + } +""" + + tests += """ + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once.""" + + tests += ''.join([""" + EXPECT_EQ(1, n%s_) << + "The predicate assertion didn't evaluate argument %s " + "exactly once.";""" % (i, i + 1) for i in OneTo(n)]) + + tests += """ + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; +""" % DEFS + + tests += Iter(n, """ + static int n%s_;""") + + tests += """ +}; + +bool Predicate%(n)sTest::expected_to_finish_; +bool Predicate%(n)sTest::finished_; +""" % DEFS + + tests += Iter(n, """int Predicate%%(n)sTest::n%s_; +""") % DEFS + + tests += """ +typedef Predicate%(n)sTest EXPECT_PRED_FORMAT%(n)sTest; +typedef Predicate%(n)sTest ASSERT_PRED_FORMAT%(n)sTest; +typedef Predicate%(n)sTest EXPECT_PRED%(n)sTest; +typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest; +""" % DEFS + + def GenTest(use_format, use_assert, expect_failure, + use_functor, use_user_type): + """Returns the test for a predicate assertion macro. + + Args: + use_format: true iff the assertion is a *_PRED_FORMAT*. + use_assert: true iff the assertion is a ASSERT_*. + expect_failure: true iff the assertion is expected to fail. + use_functor: true iff the first argument of the assertion is + a functor (as opposed to a function) + use_user_type: true iff the predicate functor/function takes + argument(s) of a user-defined type. + + Example: + + GenTest(1, 0, 0, 1, 0) returns a test that tests the behavior + of a successful EXPECT_PRED_FORMATn() that takes a functor + whose arguments have built-in types.""" + + if use_assert: + assrt = 'ASSERT' # 'assert' is reserved, so we cannot use + # that identifier here. + else: + assrt = 'EXPECT' + + assertion = assrt + '_PRED' + + if use_format: + pred_format = 'PredFormat' + assertion += '_FORMAT' + else: + pred_format = 'Pred' + + assertion += '%(n)s' % DEFS + + if use_functor: + pred_format_type = 'functor' + pred_format += 'Functor%(n)s()' + else: + pred_format_type = 'function' + pred_format += 'Function%(n)s' + if not use_format: + if use_user_type: + pred_format += 'Bool' + else: + pred_format += 'Int' + + test_name = pred_format_type.title() + + if use_user_type: + arg_type = 'user-defined type (Bool)' + test_name += 'OnUserType' + if expect_failure: + arg = 'Bool(n%s_++)' + else: + arg = 'Bool(++n%s_)' + else: + arg_type = 'built-in type (int)' + test_name += 'OnBuiltInType' + if expect_failure: + arg = 'n%s_++' + else: + arg = '++n%s_' + + if expect_failure: + successful_or_failed = 'failed' + expected_or_not = 'expected.' + test_name += 'Failure' + else: + successful_or_failed = 'successful' + expected_or_not = 'UNEXPECTED!' + test_name += 'Success' + + # A map that defines the values used in the test template. + defs = DEFS.copy() + defs.update({ + 'assert' : assrt, + 'assertion' : assertion, + 'test_name' : test_name, + 'pf_type' : pred_format_type, + 'pf' : pred_format, + 'arg_type' : arg_type, + 'arg' : arg, + 'successful' : successful_or_failed, + 'expected' : expected_or_not, + }) + + test = """ +// Tests a %(successful)s %(assertion)s where the +// predicate-formatter is a %(pf_type)s on a %(arg_type)s. +TEST_F(%(assertion)sTest, %(test_name)s) {""" % defs + + indent = (len(assertion) + 3)*' ' + extra_indent = '' + + if expect_failure: + extra_indent = ' ' + if use_assert: + test += """ + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT""" + else: + test += """ + EXPECT_NONFATAL_FAILURE({ // NOLINT""" + + test += '\n' + extra_indent + """ %(assertion)s(%(pf)s""" % defs + + test = test % defs + test += Iter(n, ',\n' + indent + extra_indent + '%(arg)s' % defs) + test += ');\n' + extra_indent + ' finished_ = true;\n' + + if expect_failure: + test += ' }, "");\n' + + test += '}\n' + return test + + # Generates tests for all 2**6 = 64 combinations. + tests += ''.join([GenTest(use_format, use_assert, expect_failure, + use_functor, use_user_type) + for use_format in [0, 1] + for use_assert in [0, 1] + for expect_failure in [0, 1] + for use_functor in [0, 1] + for use_user_type in [0, 1] + ]) + + return tests + + +def UnitTestPostamble(): + """Returns the postamble for the tests.""" + + return '' + + +def GenerateUnitTest(n): + """Returns the tests for up-to n-ary predicate assertions.""" + + GenerateFile(UNIT_TEST, + UnitTestPreamble() + + ''.join([TestsForArity(i) for i in OneTo(n)]) + + UnitTestPostamble()) + + +def _Main(): + """The entry point of the script. Generates the header file and its + unit test.""" + + if len(sys.argv) != 2: + print __doc__ + print 'Author: ' + __author__ + sys.exit(1) + + n = int(sys.argv[1]) + GenerateHeader(n) + GenerateUnitTest(n) + + +if __name__ == '__main__': + _Main() diff --git a/3rdparty/gtest/scripts/gtest-config.in b/3rdparty/gtest/scripts/gtest-config.in new file mode 100644 index 0000000..780f843 --- /dev/null +++ b/3rdparty/gtest/scripts/gtest-config.in @@ -0,0 +1,274 @@ +#!/bin/sh + +# These variables are automatically filled in by the configure script. +name="@PACKAGE_TARNAME@" +version="@PACKAGE_VERSION@" + +show_usage() +{ + echo "Usage: gtest-config [OPTIONS...]" +} + +show_help() +{ + show_usage + cat <<\EOF + +The `gtest-config' script provides access to the necessary compile and linking +flags to connect with Google C++ Testing Framework, both in a build prior to +installation, and on the system proper after installation. The installation +overrides may be issued in combination with any other queries, but will only +affect installation queries if called on a built but not installed gtest. The +installation queries may not be issued with any other types of queries, and +only one installation query may be made at a time. The version queries and +compiler flag queries may be combined as desired but not mixed. Different +version queries are always combined with logical "and" semantics, and only the +last of any particular query is used while all previous ones ignored. All +versions must be specified as a sequence of numbers separated by periods. +Compiler flag queries output the union of the sets of flags when combined. + + Examples: + gtest-config --min-version=1.0 || echo "Insufficient Google Test version." + + g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp + g++ $(gtest-config --ldflags --libs) -o foo foo.o + + # When using a built but not installed Google Test: + g++ $(../../my_gtest_build/scripts/gtest-config ...) ... + + # When using an installed Google Test, but with installation overrides: + export GTEST_PREFIX="/opt" + g++ $(gtest-config --libdir="/opt/lib64" ...) ... + + Help: + --usage brief usage information + --help display this help message + + Installation Overrides: + --prefix= overrides the installation prefix + --exec-prefix= overrides the executable installation prefix + --libdir= overrides the library installation prefix + --includedir= overrides the header file installation prefix + + Installation Queries: + --prefix installation prefix + --exec-prefix executable installation prefix + --libdir library installation directory + --includedir header file installation directory + --version the version of the Google Test installation + + Version Queries: + --min-version=VERSION return 0 if the version is at least VERSION + --exact-version=VERSION return 0 if the version is exactly VERSION + --max-version=VERSION return 0 if the version is at most VERSION + + Compilation Flag Queries: + --cppflags compile flags specific to the C-like preprocessors + --cxxflags compile flags appropriate for C++ programs + --ldflags linker flags + --libs libraries for linking + +EOF +} + +# This function bounds our version with a min and a max. It uses some clever +# POSIX-compliant variable expansion to portably do all the work in the shell +# and avoid any dependency on a particular "sed" or "awk" implementation. +# Notable is that it will only ever compare the first 3 components of versions. +# Further components will be cleanly stripped off. All versions must be +# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and +# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should +# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than +# continuing to maintain our own shell version. +check_versions() +{ + major_version=${version%%.*} + minor_version="0" + point_version="0" + if test "${version#*.}" != "${version}"; then + minor_version=${version#*.} + minor_version=${minor_version%%.*} + fi + if test "${version#*.*.}" != "${version}"; then + point_version=${version#*.*.} + point_version=${point_version%%.*} + fi + + min_version="$1" + min_major_version=${min_version%%.*} + min_minor_version="0" + min_point_version="0" + if test "${min_version#*.}" != "${min_version}"; then + min_minor_version=${min_version#*.} + min_minor_version=${min_minor_version%%.*} + fi + if test "${min_version#*.*.}" != "${min_version}"; then + min_point_version=${min_version#*.*.} + min_point_version=${min_point_version%%.*} + fi + + max_version="$2" + max_major_version=${max_version%%.*} + max_minor_version="0" + max_point_version="0" + if test "${max_version#*.}" != "${max_version}"; then + max_minor_version=${max_version#*.} + max_minor_version=${max_minor_version%%.*} + fi + if test "${max_version#*.*.}" != "${max_version}"; then + max_point_version=${max_version#*.*.} + max_point_version=${max_point_version%%.*} + fi + + test $(($major_version)) -lt $(($min_major_version)) && exit 1 + if test $(($major_version)) -eq $(($min_major_version)); then + test $(($minor_version)) -lt $(($min_minor_version)) && exit 1 + if test $(($minor_version)) -eq $(($min_minor_version)); then + test $(($point_version)) -lt $(($min_point_version)) && exit 1 + fi + fi + + test $(($major_version)) -gt $(($max_major_version)) && exit 1 + if test $(($major_version)) -eq $(($max_major_version)); then + test $(($minor_version)) -gt $(($max_minor_version)) && exit 1 + if test $(($minor_version)) -eq $(($max_minor_version)); then + test $(($point_version)) -gt $(($max_point_version)) && exit 1 + fi + fi + + exit 0 +} + +# Show the usage line when no arguments are specified. +if test $# -eq 0; then + show_usage + exit 1 +fi + +while test $# -gt 0; do + case $1 in + --usage) show_usage; exit 0;; + --help) show_help; exit 0;; + + # Installation overrides + --prefix=*) GTEST_PREFIX=${1#--prefix=};; + --exec-prefix=*) GTEST_EXEC_PREFIX=${1#--exec-prefix=};; + --libdir=*) GTEST_LIBDIR=${1#--libdir=};; + --includedir=*) GTEST_INCLUDEDIR=${1#--includedir=};; + + # Installation queries + --prefix|--exec-prefix|--libdir|--includedir|--version) + if test -n "${do_query}"; then + show_usage + exit 1 + fi + do_query=${1#--} + ;; + + # Version checking + --min-version=*) + do_check_versions=yes + min_version=${1#--min-version=} + ;; + --max-version=*) + do_check_versions=yes + max_version=${1#--max-version=} + ;; + --exact-version=*) + do_check_versions=yes + exact_version=${1#--exact-version=} + ;; + + # Compiler flag output + --cppflags) echo_cppflags=yes;; + --cxxflags) echo_cxxflags=yes;; + --ldflags) echo_ldflags=yes;; + --libs) echo_libs=yes;; + + # Everything else is an error + *) show_usage; exit 1;; + esac + shift +done + +# These have defaults filled in by the configure script but can also be +# overridden by environment variables or command line parameters. +prefix="${GTEST_PREFIX:-@prefix@}" +exec_prefix="${GTEST_EXEC_PREFIX:-@exec_prefix@}" +libdir="${GTEST_LIBDIR:-@libdir@}" +includedir="${GTEST_INCLUDEDIR:-@includedir@}" + +# We try and detect if our binary is not located at its installed location. If +# it's not, we provide variables pointing to the source and build tree rather +# than to the install tree. This allows building against a just-built gtest +# rather than an installed gtest. +bindir="@bindir@" +this_relative_bindir=`dirname $0` +this_bindir=`cd ${this_relative_bindir}; pwd -P` +if test "${this_bindir}" = "${this_bindir%${bindir}}"; then + # The path to the script doesn't end in the bindir sequence from Autoconf, + # assume that we are in a build tree. + build_dir=`dirname ${this_bindir}` + src_dir=`cd ${this_bindir}; cd @top_srcdir@; pwd -P` + + # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we + # should work to remove it, and/or remove libtool altogether, replacing it + # with direct references to the library and a link path. + gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" + gtest_ldflags="" + + # We provide hooks to include from either the source or build dir, where the + # build dir is always preferred. This will potentially allow us to write + # build rules for generated headers and have them automatically be preferred + # over provided versions. + gtest_cppflags="-I${build_dir}/include -I${src_dir}/include" + gtest_cxxflags="@PTHREAD_CFLAGS@" +else + # We're using an installed gtest, although it may be staged under some + # prefix. Assume (as our own libraries do) that we can resolve the prefix, + # and are present in the dynamic link paths. + gtest_ldflags="-L${libdir}" + gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" + gtest_cppflags="-I${includedir}" + gtest_cxxflags="@PTHREAD_CFLAGS@" +fi + +# Do an installation query if requested. +if test -n "$do_query"; then + case $do_query in + prefix) echo $prefix; exit 0;; + exec-prefix) echo $exec_prefix; exit 0;; + libdir) echo $libdir; exit 0;; + includedir) echo $includedir; exit 0;; + version) echo $version; exit 0;; + *) show_usage; exit 1;; + esac +fi + +# Do a version check if requested. +if test "$do_check_versions" = "yes"; then + # Make sure we didn't receive a bad combination of parameters. + test "$echo_cppflags" = "yes" && show_usage && exit 1 + test "$echo_cxxflags" = "yes" && show_usage && exit 1 + test "$echo_ldflags" = "yes" && show_usage && exit 1 + test "$echo_libs" = "yes" && show_usage && exit 1 + + if test "$exact_version" != ""; then + check_versions $exact_version $exact_version + # unreachable + else + check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999} + # unreachable + fi +fi + +# Do the output in the correct order so that these can be used in-line of +# a compiler invocation. +output="" +test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags" +test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags" +test "$echo_ldflags" = "yes" && output="$output $gtest_ldflags" +test "$echo_libs" = "yes" && output="$output $gtest_libs" +echo $output + +exit 0 diff --git a/3rdparty/gtest/scripts/pump.py b/3rdparty/gtest/scripts/pump.py new file mode 100644 index 0000000..5efb653 --- /dev/null +++ b/3rdparty/gtest/scripts/pump.py @@ -0,0 +1,855 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""pump v0.2.0 - Pretty Useful for Meta Programming. + +A tool for preprocessor meta programming. Useful for generating +repetitive boilerplate code. Especially useful for writing C++ +classes, functions, macros, and templates that need to work with +various number of arguments. + +USAGE: + pump.py SOURCE_FILE + +EXAMPLES: + pump.py foo.cc.pump + Converts foo.cc.pump to foo.cc. + +GRAMMAR: + CODE ::= ATOMIC_CODE* + ATOMIC_CODE ::= $var ID = EXPRESSION + | $var ID = [[ CODE ]] + | $range ID EXPRESSION..EXPRESSION + | $for ID SEPARATOR [[ CODE ]] + | $($) + | $ID + | $(EXPRESSION) + | $if EXPRESSION [[ CODE ]] ELSE_BRANCH + | [[ CODE ]] + | RAW_CODE + SEPARATOR ::= RAW_CODE | EMPTY + ELSE_BRANCH ::= $else [[ CODE ]] + | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH + | EMPTY + EXPRESSION has Python syntax. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sys + + +TOKEN_TABLE = [ + (re.compile(r'\$var\s+'), '$var'), + (re.compile(r'\$elif\s+'), '$elif'), + (re.compile(r'\$else\s+'), '$else'), + (re.compile(r'\$for\s+'), '$for'), + (re.compile(r'\$if\s+'), '$if'), + (re.compile(r'\$range\s+'), '$range'), + (re.compile(r'\$[_A-Za-z]\w*'), '$id'), + (re.compile(r'\$\(\$\)'), '$($)'), + (re.compile(r'\$'), '$'), + (re.compile(r'\[\[\n?'), '[['), + (re.compile(r'\]\]\n?'), ']]'), + ] + + +class Cursor: + """Represents a position (line and column) in a text file.""" + + def __init__(self, line=-1, column=-1): + self.line = line + self.column = column + + def __eq__(self, rhs): + return self.line == rhs.line and self.column == rhs.column + + def __ne__(self, rhs): + return not self == rhs + + def __lt__(self, rhs): + return self.line < rhs.line or ( + self.line == rhs.line and self.column < rhs.column) + + def __le__(self, rhs): + return self < rhs or self == rhs + + def __gt__(self, rhs): + return rhs < self + + def __ge__(self, rhs): + return rhs <= self + + def __str__(self): + if self == Eof(): + return 'EOF' + else: + return '%s(%s)' % (self.line + 1, self.column) + + def __add__(self, offset): + return Cursor(self.line, self.column + offset) + + def __sub__(self, offset): + return Cursor(self.line, self.column - offset) + + def Clone(self): + """Returns a copy of self.""" + + return Cursor(self.line, self.column) + + +# Special cursor to indicate the end-of-file. +def Eof(): + """Returns the special cursor to denote the end-of-file.""" + return Cursor(-1, -1) + + +class Token: + """Represents a token in a Pump source file.""" + + def __init__(self, start=None, end=None, value=None, token_type=None): + if start is None: + self.start = Eof() + else: + self.start = start + if end is None: + self.end = Eof() + else: + self.end = end + self.value = value + self.token_type = token_type + + def __str__(self): + return 'Token @%s: \'%s\' type=%s' % ( + self.start, self.value, self.token_type) + + def Clone(self): + """Returns a copy of self.""" + + return Token(self.start.Clone(), self.end.Clone(), self.value, + self.token_type) + + +def StartsWith(lines, pos, string): + """Returns True iff the given position in lines starts with 'string'.""" + + return lines[pos.line][pos.column:].startswith(string) + + +def FindFirstInLine(line, token_table): + best_match_start = -1 + for (regex, token_type) in token_table: + m = regex.search(line) + if m: + # We found regex in lines + if best_match_start < 0 or m.start() < best_match_start: + best_match_start = m.start() + best_match_length = m.end() - m.start() + best_match_token_type = token_type + + if best_match_start < 0: + return None + + return (best_match_start, best_match_length, best_match_token_type) + + +def FindFirst(lines, token_table, cursor): + """Finds the first occurrence of any string in strings in lines.""" + + start = cursor.Clone() + cur_line_number = cursor.line + for line in lines[start.line:]: + if cur_line_number == start.line: + line = line[start.column:] + m = FindFirstInLine(line, token_table) + if m: + # We found a regex in line. + (start_column, length, token_type) = m + if cur_line_number == start.line: + start_column += start.column + found_start = Cursor(cur_line_number, start_column) + found_end = found_start + length + return MakeToken(lines, found_start, found_end, token_type) + cur_line_number += 1 + # We failed to find str in lines + return None + + +def SubString(lines, start, end): + """Returns a substring in lines.""" + + if end == Eof(): + end = Cursor(len(lines) - 1, len(lines[-1])) + + if start >= end: + return '' + + if start.line == end.line: + return lines[start.line][start.column:end.column] + + result_lines = ([lines[start.line][start.column:]] + + lines[start.line + 1:end.line] + + [lines[end.line][:end.column]]) + return ''.join(result_lines) + + +def StripMetaComments(str): + """Strip meta comments from each line in the given string.""" + + # First, completely remove lines containing nothing but a meta + # comment, including the trailing \n. + str = re.sub(r'^\s*\$\$.*\n', '', str) + + # Then, remove meta comments from contentful lines. + return re.sub(r'\s*\$\$.*', '', str) + + +def MakeToken(lines, start, end, token_type): + """Creates a new instance of Token.""" + + return Token(start, end, SubString(lines, start, end), token_type) + + +def ParseToken(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = regex.search(line) + if m and not m.start(): + return MakeToken(lines, pos, pos + m.end(), token_type) + else: + print 'ERROR: %s expected at %s.' % (token_type, pos) + sys.exit(1) + + +ID_REGEX = re.compile(r'[_A-Za-z]\w*') +EQ_REGEX = re.compile(r'=') +REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)') +OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*') +WHITE_SPACE_REGEX = re.compile(r'\s') +DOT_DOT_REGEX = re.compile(r'\.\.') + + +def Skip(lines, pos, regex): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m and not m.start(): + return pos + m.end() + else: + return pos + + +def SkipUntil(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m: + return pos + m.start() + else: + print ('ERROR: %s expected on line %s after column %s.' % + (token_type, pos.line + 1, pos.column)) + sys.exit(1) + + +def ParseExpTokenInParens(lines, pos): + def ParseInParens(pos): + pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX) + pos = Skip(lines, pos, r'\(') + pos = Parse(pos) + pos = Skip(lines, pos, r'\)') + return pos + + def Parse(pos): + pos = SkipUntil(lines, pos, r'\(|\)', ')') + if SubString(lines, pos, pos + 1) == '(': + pos = Parse(pos + 1) + pos = Skip(lines, pos, r'\)') + return Parse(pos) + else: + return pos + + start = pos.Clone() + pos = ParseInParens(pos) + return MakeToken(lines, start, pos, 'exp') + + +def RStripNewLineFromToken(token): + if token.value.endswith('\n'): + return Token(token.start, token.end, token.value[:-1], token.token_type) + else: + return token + + +def TokenizeLines(lines, pos): + while True: + found = FindFirst(lines, TOKEN_TABLE, pos) + if not found: + yield MakeToken(lines, pos, Eof(), 'code') + return + + if found.start == pos: + prev_token = None + prev_token_rstripped = None + else: + prev_token = MakeToken(lines, pos, found.start, 'code') + prev_token_rstripped = RStripNewLineFromToken(prev_token) + + if found.token_type == '$var': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + eq_token = ParseToken(lines, pos, EQ_REGEX, '=') + yield eq_token + pos = Skip(lines, eq_token.end, r'\s*') + + if SubString(lines, pos, pos + 2) != '[[': + exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp') + yield exp_token + pos = Cursor(exp_token.end.line + 1, 0) + elif found.token_type == '$for': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX) + elif found.token_type == '$range': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..') + yield MakeToken(lines, pos, dots_pos, 'exp') + yield MakeToken(lines, dots_pos, dots_pos + 2, '..') + pos = dots_pos + 2 + new_pos = Cursor(pos.line + 1, 0) + yield MakeToken(lines, pos, new_pos, 'exp') + pos = new_pos + elif found.token_type == '$': + if prev_token: + yield prev_token + yield found + exp_token = ParseExpTokenInParens(lines, found.end) + yield exp_token + pos = exp_token.end + elif (found.token_type == ']]' or found.token_type == '$if' or + found.token_type == '$elif' or found.token_type == '$else'): + if prev_token_rstripped: + yield prev_token_rstripped + yield found + pos = found.end + else: + if prev_token: + yield prev_token + yield found + pos = found.end + + +def Tokenize(s): + """A generator that yields the tokens in the given string.""" + if s != '': + lines = s.splitlines(True) + for token in TokenizeLines(lines, Cursor(0, 0)): + yield token + + +class CodeNode: + def __init__(self, atomic_code_list=None): + self.atomic_code = atomic_code_list + + +class VarNode: + def __init__(self, identifier=None, atomic_code=None): + self.identifier = identifier + self.atomic_code = atomic_code + + +class RangeNode: + def __init__(self, identifier=None, exp1=None, exp2=None): + self.identifier = identifier + self.exp1 = exp1 + self.exp2 = exp2 + + +class ForNode: + def __init__(self, identifier=None, sep=None, code=None): + self.identifier = identifier + self.sep = sep + self.code = code + + +class ElseNode: + def __init__(self, else_branch=None): + self.else_branch = else_branch + + +class IfNode: + def __init__(self, exp=None, then_branch=None, else_branch=None): + self.exp = exp + self.then_branch = then_branch + self.else_branch = else_branch + + +class RawCodeNode: + def __init__(self, token=None): + self.raw_code = token + + +class LiteralDollarNode: + def __init__(self, token): + self.token = token + + +class ExpNode: + def __init__(self, token, python_exp): + self.token = token + self.python_exp = python_exp + + +def PopFront(a_list): + head = a_list[0] + a_list[:1] = [] + return head + + +def PushFront(a_list, elem): + a_list[:0] = [elem] + + +def PopToken(a_list, token_type=None): + token = PopFront(a_list) + if token_type is not None and token.token_type != token_type: + print 'ERROR: %s expected at %s' % (token_type, token.start) + print 'ERROR: %s found instead' % (token,) + sys.exit(1) + + return token + + +def PeekToken(a_list): + if not a_list: + return None + + return a_list[0] + + +def ParseExpNode(token): + python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value) + return ExpNode(token, python_exp) + + +def ParseElseNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + next = PeekToken(tokens) + if not next: + return None + if next.token_type == '$else': + Pop('$else') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + elif next.token_type == '$elif': + Pop('$elif') + exp = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + inner_else_node = ParseElseNode(tokens) + return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)]) + elif not next.value.strip(): + Pop('code') + return ParseElseNode(tokens) + else: + return None + + +def ParseAtomicCodeNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + head = PopFront(tokens) + t = head.token_type + if t == 'code': + return RawCodeNode(head) + elif t == '$var': + id_token = Pop('id') + Pop('=') + next = PeekToken(tokens) + if next.token_type == 'exp': + exp_token = Pop() + return VarNode(id_token, ParseExpNode(exp_token)) + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return VarNode(id_token, code_node) + elif t == '$for': + id_token = Pop('id') + next_token = PeekToken(tokens) + if next_token.token_type == 'code': + sep_token = next_token + Pop('code') + else: + sep_token = None + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return ForNode(id_token, sep_token, code_node) + elif t == '$if': + exp_token = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + else_node = ParseElseNode(tokens) + return IfNode(ParseExpNode(exp_token), code_node, else_node) + elif t == '$range': + id_token = Pop('id') + exp1_token = Pop('exp') + Pop('..') + exp2_token = Pop('exp') + return RangeNode(id_token, ParseExpNode(exp1_token), + ParseExpNode(exp2_token)) + elif t == '$id': + return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id')) + elif t == '$($)': + return LiteralDollarNode(head) + elif t == '$': + exp_token = Pop('exp') + return ParseExpNode(exp_token) + elif t == '[[': + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + else: + PushFront(tokens, head) + return None + + +def ParseCodeNode(tokens): + atomic_code_list = [] + while True: + if not tokens: + break + atomic_code_node = ParseAtomicCodeNode(tokens) + if atomic_code_node: + atomic_code_list.append(atomic_code_node) + else: + break + return CodeNode(atomic_code_list) + + +def ParseToAST(pump_src_text): + """Convert the given Pump source text into an AST.""" + tokens = list(Tokenize(pump_src_text)) + code_node = ParseCodeNode(tokens) + return code_node + + +class Env: + def __init__(self): + self.variables = [] + self.ranges = [] + + def Clone(self): + clone = Env() + clone.variables = self.variables[:] + clone.ranges = self.ranges[:] + return clone + + def PushVariable(self, var, value): + # If value looks like an int, store it as an int. + try: + int_value = int(value) + if ('%s' % int_value) == value: + value = int_value + except Exception: + pass + self.variables[:0] = [(var, value)] + + def PopVariable(self): + self.variables[:1] = [] + + def PushRange(self, var, lower, upper): + self.ranges[:0] = [(var, lower, upper)] + + def PopRange(self): + self.ranges[:1] = [] + + def GetValue(self, identifier): + for (var, value) in self.variables: + if identifier == var: + return value + + print 'ERROR: meta variable %s is undefined.' % (identifier,) + sys.exit(1) + + def EvalExp(self, exp): + try: + result = eval(exp.python_exp) + except Exception, e: + print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e) + print ('ERROR: failed to evaluate meta expression %s at %s' % + (exp.python_exp, exp.token.start)) + sys.exit(1) + return result + + def GetRange(self, identifier): + for (var, lower, upper) in self.ranges: + if identifier == var: + return (lower, upper) + + print 'ERROR: range %s is undefined.' % (identifier,) + sys.exit(1) + + +class Output: + def __init__(self): + self.string = '' + + def GetLastLine(self): + index = self.string.rfind('\n') + if index < 0: + return '' + + return self.string[index + 1:] + + def Append(self, s): + self.string += s + + +def RunAtomicCode(env, node, output): + if isinstance(node, VarNode): + identifier = node.identifier.value.strip() + result = Output() + RunAtomicCode(env.Clone(), node.atomic_code, result) + value = result.string + env.PushVariable(identifier, value) + elif isinstance(node, RangeNode): + identifier = node.identifier.value.strip() + lower = int(env.EvalExp(node.exp1)) + upper = int(env.EvalExp(node.exp2)) + env.PushRange(identifier, lower, upper) + elif isinstance(node, ForNode): + identifier = node.identifier.value.strip() + if node.sep is None: + sep = '' + else: + sep = node.sep.value + (lower, upper) = env.GetRange(identifier) + for i in range(lower, upper + 1): + new_env = env.Clone() + new_env.PushVariable(identifier, i) + RunCode(new_env, node.code, output) + if i != upper: + output.Append(sep) + elif isinstance(node, RawCodeNode): + output.Append(node.raw_code.value) + elif isinstance(node, IfNode): + cond = env.EvalExp(node.exp) + if cond: + RunCode(env.Clone(), node.then_branch, output) + elif node.else_branch is not None: + RunCode(env.Clone(), node.else_branch, output) + elif isinstance(node, ExpNode): + value = env.EvalExp(node) + output.Append('%s' % (value,)) + elif isinstance(node, LiteralDollarNode): + output.Append('$') + elif isinstance(node, CodeNode): + RunCode(env.Clone(), node, output) + else: + print 'BAD' + print node + sys.exit(1) + + +def RunCode(env, code_node, output): + for atomic_code in code_node.atomic_code: + RunAtomicCode(env, atomic_code, output) + + +def IsSingleLineComment(cur_line): + return '//' in cur_line + + +def IsInPreprocessorDirective(prev_lines, cur_line): + if cur_line.lstrip().startswith('#'): + return True + return prev_lines and prev_lines[-1].endswith('\\') + + +def WrapComment(line, output): + loc = line.find('//') + before_comment = line[:loc].rstrip() + if before_comment == '': + indent = loc + else: + output.append(before_comment) + indent = len(before_comment) - len(before_comment.lstrip()) + prefix = indent*' ' + '// ' + max_len = 80 - len(prefix) + comment = line[loc + 2:].strip() + segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != ''] + cur_line = '' + for seg in segs: + if len((cur_line + seg).rstrip()) < max_len: + cur_line += seg + else: + if cur_line.strip() != '': + output.append(prefix + cur_line.rstrip()) + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapCode(line, line_concat, output): + indent = len(line) - len(line.lstrip()) + prefix = indent*' ' # Prefix of the current line + max_len = 80 - indent - len(line_concat) # Maximum length of the current line + new_prefix = prefix + 4*' ' # Prefix of a continuation line + new_max_len = max_len - 4 # Maximum length of a continuation line + # Prefers to wrap a line after a ',' or ';'. + segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != ''] + cur_line = '' # The current line without leading spaces. + for seg in segs: + # If the line is still too long, wrap at a space. + while cur_line == '' and len(seg.strip()) > max_len: + seg = seg.lstrip() + split_at = seg.rfind(' ', 0, max_len) + output.append(prefix + seg[:split_at].strip() + line_concat) + seg = seg[split_at + 1:] + prefix = new_prefix + max_len = new_max_len + + if len((cur_line + seg).rstrip()) < max_len: + cur_line = (cur_line + seg).lstrip() + else: + output.append(prefix + cur_line.rstrip() + line_concat) + prefix = new_prefix + max_len = new_max_len + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapPreprocessorDirective(line, output): + WrapCode(line, ' \\', output) + + +def WrapPlainCode(line, output): + WrapCode(line, '', output) + + +def IsMultiLineIWYUPragma(line): + return re.search(r'/\* IWYU pragma: ', line) + + +def IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or + re.match(r'^#include\s', line) or + # Don't break IWYU pragmas, either; that causes iwyu.py problems. + re.search(r'// IWYU pragma: ', line)) + + +def WrapLongLine(line, output): + line = line.rstrip() + if len(line) <= 80: + output.append(line) + elif IsSingleLineComment(line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapComment(line, output) + elif IsInPreprocessorDirective(output, line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapPreprocessorDirective(line, output) + elif IsMultiLineIWYUPragma(line): + output.append(line) + else: + WrapPlainCode(line, output) + + +def BeautifyCode(string): + lines = string.splitlines() + output = [] + for line in lines: + WrapLongLine(line, output) + output2 = [line.rstrip() for line in output] + return '\n'.join(output2) + '\n' + + +def ConvertFromPumpSource(src_text): + """Return the text generated from the given Pump source text.""" + ast = ParseToAST(StripMetaComments(src_text)) + output = Output() + RunCode(Env(), ast, output) + return BeautifyCode(output.string) + + +def main(argv): + if len(argv) == 1: + print __doc__ + sys.exit(1) + + file_path = argv[-1] + output_str = ConvertFromPumpSource(file(file_path, 'r').read()) + if file_path.endswith('.pump'): + output_file_path = file_path[:-5] + else: + output_file_path = '-' + if output_file_path == '-': + print output_str, + else: + output_file = file(output_file_path, 'w') + output_file.write('// This file was GENERATED by command:\n') + output_file.write('// %s %s\n' % + (os.path.basename(__file__), os.path.basename(file_path))) + output_file.write('// DO NOT EDIT BY HAND!!!\n\n') + output_file.write(output_str) + output_file.close() + + +if __name__ == '__main__': + main(sys.argv) diff --git a/3rdparty/gtest/scripts/release_docs.py b/3rdparty/gtest/scripts/release_docs.py new file mode 100644 index 0000000..1291347 --- /dev/null +++ b/3rdparty/gtest/scripts/release_docs.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python +# +# Copyright 2013 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Script for branching Google Test/Mock wiki pages for a new version. + +SYNOPSIS + release_docs.py NEW_RELEASE_VERSION + + Google Test and Google Mock's external user documentation is in + interlinked wiki files. When we release a new version of + Google Test or Google Mock, we need to branch the wiki files + such that users of a specific version of Google Test/Mock can + look up documenation relevant for that version. This script + automates that process by: + + - branching the current wiki pages (which document the + behavior of the SVN trunk head) to pages for the specified + version (e.g. branching FAQ.wiki to V2_6_FAQ.wiki when + NEW_RELEASE_VERSION is 2.6); + - updating the links in the branched files to point to the branched + version (e.g. a link in V2_6_FAQ.wiki that pointed to + Primer.wiki#Anchor will now point to V2_6_Primer.wiki#Anchor). + + NOTE: NEW_RELEASE_VERSION must be a NEW version number for + which the wiki pages don't yet exist; otherwise you'll get SVN + errors like "svn: Path 'V1_7_PumpManual.wiki' is not a + directory" when running the script. + +EXAMPLE + $ cd PATH/TO/GTEST_SVN_WORKSPACE/trunk + $ scripts/release_docs.py 2.6 # create wiki pages for v2.6 + $ svn status # verify the file list + $ svn diff # verify the file contents + $ svn commit -m "release wiki pages for v2.6" +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sys + +import common + + +# Wiki pages that shouldn't be branched for every gtest/gmock release. +GTEST_UNVERSIONED_WIKIS = ['DevGuide.wiki'] +GMOCK_UNVERSIONED_WIKIS = [ + 'DesignDoc.wiki', + 'DevGuide.wiki', + 'KnownIssues.wiki' + ] + + +def DropWikiSuffix(wiki_filename): + """Removes the .wiki suffix (if any) from the given filename.""" + + return (wiki_filename[:-len('.wiki')] if wiki_filename.endswith('.wiki') + else wiki_filename) + + +class WikiBrancher(object): + """Branches ...""" + + def __init__(self, dot_version): + self.project, svn_root_path = common.GetSvnInfo() + if self.project not in ('googletest', 'googlemock'): + sys.exit('This script must be run in a gtest or gmock SVN workspace.') + self.wiki_dir = svn_root_path + '/wiki' + # Turn '2.6' to 'V2_6_'. + self.version_prefix = 'V' + dot_version.replace('.', '_') + '_' + self.files_to_branch = self.GetFilesToBranch() + page_names = [DropWikiSuffix(f) for f in self.files_to_branch] + # A link to Foo.wiki is in one of the following forms: + # [Foo words] + # [Foo#Anchor words] + # [http://code.google.com/.../wiki/Foo words] + # [http://code.google.com/.../wiki/Foo#Anchor words] + # We want to replace 'Foo' with 'V2_6_Foo' in the above cases. + self.search_for_re = re.compile( + # This regex matches either + # [Foo + # or + # /wiki/Foo + # followed by a space or a #, where Foo is the name of an + # unversioned wiki page. + r'(\[|/wiki/)(%s)([ #])' % '|'.join(page_names)) + self.replace_with = r'\1%s\2\3' % (self.version_prefix,) + + def GetFilesToBranch(self): + """Returns a list of .wiki file names that need to be branched.""" + + unversioned_wikis = (GTEST_UNVERSIONED_WIKIS if self.project == 'googletest' + else GMOCK_UNVERSIONED_WIKIS) + return [f for f in os.listdir(self.wiki_dir) + if (f.endswith('.wiki') and + not re.match(r'^V\d', f) and # Excluded versioned .wiki files. + f not in unversioned_wikis)] + + def BranchFiles(self): + """Branches the .wiki files needed to be branched.""" + + print 'Branching %d .wiki files:' % (len(self.files_to_branch),) + os.chdir(self.wiki_dir) + for f in self.files_to_branch: + command = 'svn cp %s %s%s' % (f, self.version_prefix, f) + print command + os.system(command) + + def UpdateLinksInBranchedFiles(self): + + for f in self.files_to_branch: + source_file = os.path.join(self.wiki_dir, f) + versioned_file = os.path.join(self.wiki_dir, self.version_prefix + f) + print 'Updating links in %s.' % (versioned_file,) + text = file(source_file, 'r').read() + new_text = self.search_for_re.sub(self.replace_with, text) + file(versioned_file, 'w').write(new_text) + + +def main(): + if len(sys.argv) != 2: + sys.exit(__doc__) + + brancher = WikiBrancher(sys.argv[1]) + brancher.BranchFiles() + brancher.UpdateLinksInBranchedFiles() + + +if __name__ == '__main__': + main() diff --git a/3rdparty/gtest/scripts/upload.py b/3rdparty/gtest/scripts/upload.py new file mode 100644 index 0000000..c852e4c --- /dev/null +++ b/3rdparty/gtest/scripts/upload.py @@ -0,0 +1,1387 @@ +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tool for uploading diffs from a version control system to the codereview app. + +Usage summary: upload.py [options] [-- diff_options] + +Diff options are passed to the diff command of the underlying system. + +Supported version control systems: + Git + Mercurial + Subversion + +It is important for Git/Mercurial users to specify a tree/node/branch to diff +against by using the '--rev' option. +""" +# This code is derived from appcfg.py in the App Engine SDK (open source), +# and from ASPN recipe #146306. + +import cookielib +import getpass +import logging +import md5 +import mimetypes +import optparse +import os +import re +import socket +import subprocess +import sys +import urllib +import urllib2 +import urlparse + +try: + import readline +except ImportError: + pass + +# The logging verbosity: +# 0: Errors only. +# 1: Status messages. +# 2: Info logs. +# 3: Debug logs. +verbosity = 1 + +# Max size of patch or base file. +MAX_UPLOAD_SIZE = 900 * 1024 + + +def GetEmail(prompt): + """Prompts the user for their email address and returns it. + + The last used email address is saved to a file and offered up as a suggestion + to the user. If the user presses enter without typing in anything the last + used email address is used. If the user enters a new address, it is saved + for next time we prompt. + + """ + last_email_file_name = os.path.expanduser("~/.last_codereview_email_address") + last_email = "" + if os.path.exists(last_email_file_name): + try: + last_email_file = open(last_email_file_name, "r") + last_email = last_email_file.readline().strip("\n") + last_email_file.close() + prompt += " [%s]" % last_email + except IOError, e: + pass + email = raw_input(prompt + ": ").strip() + if email: + try: + last_email_file = open(last_email_file_name, "w") + last_email_file.write(email) + last_email_file.close() + except IOError, e: + pass + else: + email = last_email + return email + + +def StatusUpdate(msg): + """Print a status message to stdout. + + If 'verbosity' is greater than 0, print the message. + + Args: + msg: The string to print. + """ + if verbosity > 0: + print msg + + +def ErrorExit(msg): + """Print an error message to stderr and exit.""" + print >>sys.stderr, msg + sys.exit(1) + + +class ClientLoginError(urllib2.HTTPError): + """Raised to indicate there was an error authenticating with ClientLogin.""" + + def __init__(self, url, code, msg, headers, args): + urllib2.HTTPError.__init__(self, url, code, msg, headers, None) + self.args = args + self.reason = args["Error"] + + +class AbstractRpcServer(object): + """Provides a common interface for a simple RPC server.""" + + def __init__(self, host, auth_function, host_override=None, extra_headers={}, + save_cookies=False): + """Creates a new HttpRpcServer. + + Args: + host: The host to send requests to. + auth_function: A function that takes no arguments and returns an + (email, password) tuple when called. Will be called if authentication + is required. + host_override: The host header to send to the server (defaults to host). + extra_headers: A dict of extra headers to append to every request. + save_cookies: If True, save the authentication cookies to local disk. + If False, use an in-memory cookiejar instead. Subclasses must + implement this functionality. Defaults to False. + """ + self.host = host + self.host_override = host_override + self.auth_function = auth_function + self.authenticated = False + self.extra_headers = extra_headers + self.save_cookies = save_cookies + self.opener = self._GetOpener() + if self.host_override: + logging.info("Server: %s; Host: %s", self.host, self.host_override) + else: + logging.info("Server: %s", self.host) + + def _GetOpener(self): + """Returns an OpenerDirector for making HTTP requests. + + Returns: + A urllib2.OpenerDirector object. + """ + raise NotImplementedError() + + def _CreateRequest(self, url, data=None): + """Creates a new urllib request.""" + logging.debug("Creating request for: '%s' with payload:\n%s", url, data) + req = urllib2.Request(url, data=data) + if self.host_override: + req.add_header("Host", self.host_override) + for key, value in self.extra_headers.iteritems(): + req.add_header(key, value) + return req + + def _GetAuthToken(self, email, password): + """Uses ClientLogin to authenticate the user, returning an auth token. + + Args: + email: The user's email address + password: The user's password + + Raises: + ClientLoginError: If there was an error authenticating with ClientLogin. + HTTPError: If there was some other form of HTTP error. + + Returns: + The authentication token returned by ClientLogin. + """ + account_type = "GOOGLE" + if self.host.endswith(".google.com"): + # Needed for use inside Google. + account_type = "HOSTED" + req = self._CreateRequest( + url="https://www.google.com/accounts/ClientLogin", + data=urllib.urlencode({ + "Email": email, + "Passwd": password, + "service": "ah", + "source": "rietveld-codereview-upload", + "accountType": account_type, + }), + ) + try: + response = self.opener.open(req) + response_body = response.read() + response_dict = dict(x.split("=") + for x in response_body.split("\n") if x) + return response_dict["Auth"] + except urllib2.HTTPError, e: + if e.code == 403: + body = e.read() + response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) + raise ClientLoginError(req.get_full_url(), e.code, e.msg, + e.headers, response_dict) + else: + raise + + def _GetAuthCookie(self, auth_token): + """Fetches authentication cookies for an authentication token. + + Args: + auth_token: The authentication token returned by ClientLogin. + + Raises: + HTTPError: If there was an error fetching the authentication cookies. + """ + # This is a dummy value to allow us to identify when we're successful. + continue_location = "http://localhost/" + args = {"continue": continue_location, "auth": auth_token} + req = self._CreateRequest("http://%s/_ah/login?%s" % + (self.host, urllib.urlencode(args))) + try: + response = self.opener.open(req) + except urllib2.HTTPError, e: + response = e + if (response.code != 302 or + response.info()["location"] != continue_location): + raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, + response.headers, response.fp) + self.authenticated = True + + def _Authenticate(self): + """Authenticates the user. + + The authentication process works as follows: + 1) We get a username and password from the user + 2) We use ClientLogin to obtain an AUTH token for the user + (see https://developers.google.com/identity/protocols/AuthForInstalledApps). + 3) We pass the auth token to /_ah/login on the server to obtain an + authentication cookie. If login was successful, it tries to redirect + us to the URL we provided. + + If we attempt to access the upload API without first obtaining an + authentication cookie, it returns a 401 response and directs us to + authenticate ourselves with ClientLogin. + """ + for i in range(3): + credentials = self.auth_function() + try: + auth_token = self._GetAuthToken(credentials[0], credentials[1]) + except ClientLoginError, e: + if e.reason == "BadAuthentication": + print >>sys.stderr, "Invalid username or password." + continue + if e.reason == "CaptchaRequired": + print >>sys.stderr, ( + "Please go to\n" + "https://www.google.com/accounts/DisplayUnlockCaptcha\n" + "and verify you are a human. Then try again.") + break + if e.reason == "NotVerified": + print >>sys.stderr, "Account not verified." + break + if e.reason == "TermsNotAgreed": + print >>sys.stderr, "User has not agreed to TOS." + break + if e.reason == "AccountDeleted": + print >>sys.stderr, "The user account has been deleted." + break + if e.reason == "AccountDisabled": + print >>sys.stderr, "The user account has been disabled." + break + if e.reason == "ServiceDisabled": + print >>sys.stderr, ("The user's access to the service has been " + "disabled.") + break + if e.reason == "ServiceUnavailable": + print >>sys.stderr, "The service is not available; try again later." + break + raise + self._GetAuthCookie(auth_token) + return + + def Send(self, request_path, payload=None, + content_type="application/octet-stream", + timeout=None, + **kwargs): + """Sends an RPC and returns the response. + + Args: + request_path: The path to send the request to, eg /api/appversion/create. + payload: The body of the request, or None to send an empty request. + content_type: The Content-Type header to use. + timeout: timeout in seconds; default None i.e. no timeout. + (Note: for large requests on OS X, the timeout doesn't work right.) + kwargs: Any keyword arguments are converted into query string parameters. + + Returns: + The response body, as a string. + """ + # TODO: Don't require authentication. Let the server say + # whether it is necessary. + if not self.authenticated: + self._Authenticate() + + old_timeout = socket.getdefaulttimeout() + socket.setdefaulttimeout(timeout) + try: + tries = 0 + while True: + tries += 1 + args = dict(kwargs) + url = "http://%s%s" % (self.host, request_path) + if args: + url += "?" + urllib.urlencode(args) + req = self._CreateRequest(url=url, data=payload) + req.add_header("Content-Type", content_type) + try: + f = self.opener.open(req) + response = f.read() + f.close() + return response + except urllib2.HTTPError, e: + if tries > 3: + raise + elif e.code == 401: + self._Authenticate() +## elif e.code >= 500 and e.code < 600: +## # Server Error - try again. +## continue + else: + raise + finally: + socket.setdefaulttimeout(old_timeout) + + +class HttpRpcServer(AbstractRpcServer): + """Provides a simplified RPC-style interface for HTTP requests.""" + + def _Authenticate(self): + """Save the cookie jar after authentication.""" + super(HttpRpcServer, self)._Authenticate() + if self.save_cookies: + StatusUpdate("Saving authentication cookies to %s" % self.cookie_file) + self.cookie_jar.save() + + def _GetOpener(self): + """Returns an OpenerDirector that supports cookies and ignores redirects. + + Returns: + A urllib2.OpenerDirector object. + """ + opener = urllib2.OpenerDirector() + opener.add_handler(urllib2.ProxyHandler()) + opener.add_handler(urllib2.UnknownHandler()) + opener.add_handler(urllib2.HTTPHandler()) + opener.add_handler(urllib2.HTTPDefaultErrorHandler()) + opener.add_handler(urllib2.HTTPSHandler()) + opener.add_handler(urllib2.HTTPErrorProcessor()) + if self.save_cookies: + self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") + self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file) + if os.path.exists(self.cookie_file): + try: + self.cookie_jar.load() + self.authenticated = True + StatusUpdate("Loaded authentication cookies from %s" % + self.cookie_file) + except (cookielib.LoadError, IOError): + # Failed to load cookies - just ignore them. + pass + else: + # Create an empty cookie file with mode 600 + fd = os.open(self.cookie_file, os.O_CREAT, 0600) + os.close(fd) + # Always chmod the cookie file + os.chmod(self.cookie_file, 0600) + else: + # Don't save cookies across runs of update.py. + self.cookie_jar = cookielib.CookieJar() + opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar)) + return opener + + +parser = optparse.OptionParser(usage="%prog [options] [-- diff_options]") +parser.add_option("-y", "--assume_yes", action="store_true", + dest="assume_yes", default=False, + help="Assume that the answer to yes/no questions is 'yes'.") +# Logging +group = parser.add_option_group("Logging options") +group.add_option("-q", "--quiet", action="store_const", const=0, + dest="verbose", help="Print errors only.") +group.add_option("-v", "--verbose", action="store_const", const=2, + dest="verbose", default=1, + help="Print info level logs (default).") +group.add_option("--noisy", action="store_const", const=3, + dest="verbose", help="Print all logs.") +# Review server +group = parser.add_option_group("Review server options") +group.add_option("-s", "--server", action="store", dest="server", + default="codereview.appspot.com", + metavar="SERVER", + help=("The server to upload to. The format is host[:port]. " + "Defaults to 'codereview.appspot.com'.")) +group.add_option("-e", "--email", action="store", dest="email", + metavar="EMAIL", default=None, + help="The username to use. Will prompt if omitted.") +group.add_option("-H", "--host", action="store", dest="host", + metavar="HOST", default=None, + help="Overrides the Host header sent with all RPCs.") +group.add_option("--no_cookies", action="store_false", + dest="save_cookies", default=True, + help="Do not save authentication cookies to local disk.") +# Issue +group = parser.add_option_group("Issue options") +group.add_option("-d", "--description", action="store", dest="description", + metavar="DESCRIPTION", default=None, + help="Optional description when creating an issue.") +group.add_option("-f", "--description_file", action="store", + dest="description_file", metavar="DESCRIPTION_FILE", + default=None, + help="Optional path of a file that contains " + "the description when creating an issue.") +group.add_option("-r", "--reviewers", action="store", dest="reviewers", + metavar="REVIEWERS", default=None, + help="Add reviewers (comma separated email addresses).") +group.add_option("--cc", action="store", dest="cc", + metavar="CC", default=None, + help="Add CC (comma separated email addresses).") +# Upload options +group = parser.add_option_group("Patch options") +group.add_option("-m", "--message", action="store", dest="message", + metavar="MESSAGE", default=None, + help="A message to identify the patch. " + "Will prompt if omitted.") +group.add_option("-i", "--issue", type="int", action="store", + metavar="ISSUE", default=None, + help="Issue number to which to add. Defaults to new issue.") +group.add_option("--download_base", action="store_true", + dest="download_base", default=False, + help="Base files will be downloaded by the server " + "(side-by-side diffs may not work on files with CRs).") +group.add_option("--rev", action="store", dest="revision", + metavar="REV", default=None, + help="Branch/tree/revision to diff against (used by DVCS).") +group.add_option("--send_mail", action="store_true", + dest="send_mail", default=False, + help="Send notification email to reviewers.") + + +def GetRpcServer(options): + """Returns an instance of an AbstractRpcServer. + + Returns: + A new AbstractRpcServer, on which RPC calls can be made. + """ + + rpc_server_class = HttpRpcServer + + def GetUserCredentials(): + """Prompts the user for a username and password.""" + email = options.email + if email is None: + email = GetEmail("Email (login for uploading to %s)" % options.server) + password = getpass.getpass("Password for %s: " % email) + return (email, password) + + # If this is the dev_appserver, use fake authentication. + host = (options.host or options.server).lower() + if host == "localhost" or host.startswith("localhost:"): + email = options.email + if email is None: + email = "test@example.com" + logging.info("Using debug user %s. Override with --email" % email) + server = rpc_server_class( + options.server, + lambda: (email, "password"), + host_override=options.host, + extra_headers={"Cookie": + 'dev_appserver_login="%s:False"' % email}, + save_cookies=options.save_cookies) + # Don't try to talk to ClientLogin. + server.authenticated = True + return server + + return rpc_server_class(options.server, GetUserCredentials, + host_override=options.host, + save_cookies=options.save_cookies) + + +def EncodeMultipartFormData(fields, files): + """Encode form fields for multipart/form-data. + + Args: + fields: A sequence of (name, value) elements for regular form fields. + files: A sequence of (name, filename, value) elements for data to be + uploaded as files. + Returns: + (content_type, body) ready for httplib.HTTP instance. + + Source: + https://web.archive.org/web/20160116052001/code.activestate.com/recipes/146306 + """ + BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' + CRLF = '\r\n' + lines = [] + for (key, value) in fields: + lines.append('--' + BOUNDARY) + lines.append('Content-Disposition: form-data; name="%s"' % key) + lines.append('') + lines.append(value) + for (key, filename, value) in files: + lines.append('--' + BOUNDARY) + lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % + (key, filename)) + lines.append('Content-Type: %s' % GetContentType(filename)) + lines.append('') + lines.append(value) + lines.append('--' + BOUNDARY + '--') + lines.append('') + body = CRLF.join(lines) + content_type = 'multipart/form-data; boundary=%s' % BOUNDARY + return content_type, body + + +def GetContentType(filename): + """Helper to guess the content-type from the filename.""" + return mimetypes.guess_type(filename)[0] or 'application/octet-stream' + + +# Use a shell for subcommands on Windows to get a PATH search. +use_shell = sys.platform.startswith("win") + +def RunShellWithReturnCode(command, print_output=False, + universal_newlines=True): + """Executes a command and returns the output from stdout and the return code. + + Args: + command: Command to execute. + print_output: If True, the output is printed to stdout. + If False, both stdout and stderr are ignored. + universal_newlines: Use universal_newlines flag (default: True). + + Returns: + Tuple (output, return code) + """ + logging.info("Running %s", command) + p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + shell=use_shell, universal_newlines=universal_newlines) + if print_output: + output_array = [] + while True: + line = p.stdout.readline() + if not line: + break + print line.strip("\n") + output_array.append(line) + output = "".join(output_array) + else: + output = p.stdout.read() + p.wait() + errout = p.stderr.read() + if print_output and errout: + print >>sys.stderr, errout + p.stdout.close() + p.stderr.close() + return output, p.returncode + + +def RunShell(command, silent_ok=False, universal_newlines=True, + print_output=False): + data, retcode = RunShellWithReturnCode(command, print_output, + universal_newlines) + if retcode: + ErrorExit("Got error status from %s:\n%s" % (command, data)) + if not silent_ok and not data: + ErrorExit("No output from %s" % command) + return data + + +class VersionControlSystem(object): + """Abstract base class providing an interface to the VCS.""" + + def __init__(self, options): + """Constructor. + + Args: + options: Command line options. + """ + self.options = options + + def GenerateDiff(self, args): + """Return the current diff as a string. + + Args: + args: Extra arguments to pass to the diff command. + """ + raise NotImplementedError( + "abstract method -- subclass %s must override" % self.__class__) + + def GetUnknownFiles(self): + """Return a list of files unknown to the VCS.""" + raise NotImplementedError( + "abstract method -- subclass %s must override" % self.__class__) + + def CheckForUnknownFiles(self): + """Show an "are you sure?" prompt if there are unknown files.""" + unknown_files = self.GetUnknownFiles() + if unknown_files: + print "The following files are not added to version control:" + for line in unknown_files: + print line + prompt = "Are you sure to continue?(y/N) " + answer = raw_input(prompt).strip() + if answer != "y": + ErrorExit("User aborted") + + def GetBaseFile(self, filename): + """Get the content of the upstream version of a file. + + Returns: + A tuple (base_content, new_content, is_binary, status) + base_content: The contents of the base file. + new_content: For text files, this is empty. For binary files, this is + the contents of the new file, since the diff output won't contain + information to reconstruct the current file. + is_binary: True iff the file is binary. + status: The status of the file. + """ + + raise NotImplementedError( + "abstract method -- subclass %s must override" % self.__class__) + + + def GetBaseFiles(self, diff): + """Helper that calls GetBase file for each file in the patch. + + Returns: + A dictionary that maps from filename to GetBaseFile's tuple. Filenames + are retrieved based on lines that start with "Index:" or + "Property changes on:". + """ + files = {} + for line in diff.splitlines(True): + if line.startswith('Index:') or line.startswith('Property changes on:'): + unused, filename = line.split(':', 1) + # On Windows if a file has property changes its filename uses '\' + # instead of '/'. + filename = filename.strip().replace('\\', '/') + files[filename] = self.GetBaseFile(filename) + return files + + + def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options, + files): + """Uploads the base files (and if necessary, the current ones as well).""" + + def UploadFile(filename, file_id, content, is_binary, status, is_base): + """Uploads a file to the server.""" + file_too_large = False + if is_base: + type = "base" + else: + type = "current" + if len(content) > MAX_UPLOAD_SIZE: + print ("Not uploading the %s file for %s because it's too large." % + (type, filename)) + file_too_large = True + content = "" + checksum = md5.new(content).hexdigest() + if options.verbose > 0 and not file_too_large: + print "Uploading %s file for %s" % (type, filename) + url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id) + form_fields = [("filename", filename), + ("status", status), + ("checksum", checksum), + ("is_binary", str(is_binary)), + ("is_current", str(not is_base)), + ] + if file_too_large: + form_fields.append(("file_too_large", "1")) + if options.email: + form_fields.append(("user", options.email)) + ctype, body = EncodeMultipartFormData(form_fields, + [("data", filename, content)]) + response_body = rpc_server.Send(url, body, + content_type=ctype) + if not response_body.startswith("OK"): + StatusUpdate(" --> %s" % response_body) + sys.exit(1) + + patches = dict() + [patches.setdefault(v, k) for k, v in patch_list] + for filename in patches.keys(): + base_content, new_content, is_binary, status = files[filename] + file_id_str = patches.get(filename) + if file_id_str.find("nobase") != -1: + base_content = None + file_id_str = file_id_str[file_id_str.rfind("_") + 1:] + file_id = int(file_id_str) + if base_content != None: + UploadFile(filename, file_id, base_content, is_binary, status, True) + if new_content != None: + UploadFile(filename, file_id, new_content, is_binary, status, False) + + def IsImage(self, filename): + """Returns true if the filename has an image extension.""" + mimetype = mimetypes.guess_type(filename)[0] + if not mimetype: + return False + return mimetype.startswith("image/") + + +class SubversionVCS(VersionControlSystem): + """Implementation of the VersionControlSystem interface for Subversion.""" + + def __init__(self, options): + super(SubversionVCS, self).__init__(options) + if self.options.revision: + match = re.match(r"(\d+)(:(\d+))?", self.options.revision) + if not match: + ErrorExit("Invalid Subversion revision %s." % self.options.revision) + self.rev_start = match.group(1) + self.rev_end = match.group(3) + else: + self.rev_start = self.rev_end = None + # Cache output from "svn list -r REVNO dirname". + # Keys: dirname, Values: 2-tuple (output for start rev and end rev). + self.svnls_cache = {} + # SVN base URL is required to fetch files deleted in an older revision. + # Result is cached to not guess it over and over again in GetBaseFile(). + required = self.options.download_base or self.options.revision is not None + self.svn_base = self._GuessBase(required) + + def GuessBase(self, required): + """Wrapper for _GuessBase.""" + return self.svn_base + + def _GuessBase(self, required): + """Returns the SVN base URL. + + Args: + required: If true, exits if the url can't be guessed, otherwise None is + returned. + """ + info = RunShell(["svn", "info"]) + for line in info.splitlines(): + words = line.split() + if len(words) == 2 and words[0] == "URL:": + url = words[1] + scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) + username, netloc = urllib.splituser(netloc) + if username: + logging.info("Removed username from base URL") + if netloc.endswith("svn.python.org"): + if netloc == "svn.python.org": + if path.startswith("/projects/"): + path = path[9:] + elif netloc != "pythondev@svn.python.org": + ErrorExit("Unrecognized Python URL: %s" % url) + base = "http://svn.python.org/view/*checkout*%s/" % path + logging.info("Guessed Python base = %s", base) + elif netloc.endswith("svn.collab.net"): + if path.startswith("/repos/"): + path = path[6:] + base = "http://svn.collab.net/viewvc/*checkout*%s/" % path + logging.info("Guessed CollabNet base = %s", base) + elif netloc.endswith(".googlecode.com"): + path = path + "/" + base = urlparse.urlunparse(("http", netloc, path, params, + query, fragment)) + logging.info("Guessed Google Code base = %s", base) + else: + path = path + "/" + base = urlparse.urlunparse((scheme, netloc, path, params, + query, fragment)) + logging.info("Guessed base = %s", base) + return base + if required: + ErrorExit("Can't find URL in output from svn info") + return None + + def GenerateDiff(self, args): + cmd = ["svn", "diff"] + if self.options.revision: + cmd += ["-r", self.options.revision] + cmd.extend(args) + data = RunShell(cmd) + count = 0 + for line in data.splitlines(): + if line.startswith("Index:") or line.startswith("Property changes on:"): + count += 1 + logging.info(line) + if not count: + ErrorExit("No valid patches found in output from svn diff") + return data + + def _CollapseKeywords(self, content, keyword_str): + """Collapses SVN keywords.""" + # svn cat translates keywords but svn diff doesn't. As a result of this + # behavior patching.PatchChunks() fails with a chunk mismatch error. + # This part was originally written by the Review Board development team + # who had the same problem (https://reviews.reviewboard.org/r/276/). + # Mapping of keywords to known aliases + svn_keywords = { + # Standard keywords + 'Date': ['Date', 'LastChangedDate'], + 'Revision': ['Revision', 'LastChangedRevision', 'Rev'], + 'Author': ['Author', 'LastChangedBy'], + 'HeadURL': ['HeadURL', 'URL'], + 'Id': ['Id'], + + # Aliases + 'LastChangedDate': ['LastChangedDate', 'Date'], + 'LastChangedRevision': ['LastChangedRevision', 'Rev', 'Revision'], + 'LastChangedBy': ['LastChangedBy', 'Author'], + 'URL': ['URL', 'HeadURL'], + } + + def repl(m): + if m.group(2): + return "$%s::%s$" % (m.group(1), " " * len(m.group(3))) + return "$%s$" % m.group(1) + keywords = [keyword + for name in keyword_str.split(" ") + for keyword in svn_keywords.get(name, [])] + return re.sub(r"\$(%s):(:?)([^\$]+)\$" % '|'.join(keywords), repl, content) + + def GetUnknownFiles(self): + status = RunShell(["svn", "status", "--ignore-externals"], silent_ok=True) + unknown_files = [] + for line in status.split("\n"): + if line and line[0] == "?": + unknown_files.append(line) + return unknown_files + + def ReadFile(self, filename): + """Returns the contents of a file.""" + file = open(filename, 'rb') + result = "" + try: + result = file.read() + finally: + file.close() + return result + + def GetStatus(self, filename): + """Returns the status of a file.""" + if not self.options.revision: + status = RunShell(["svn", "status", "--ignore-externals", filename]) + if not status: + ErrorExit("svn status returned no output for %s" % filename) + status_lines = status.splitlines() + # If file is in a cl, the output will begin with + # "\n--- Changelist 'cl_name':\n". See + # https://web.archive.org/web/20090918234815/svn.collab.net/repos/svn/trunk/notes/changelist-design.txt + if (len(status_lines) == 3 and + not status_lines[0] and + status_lines[1].startswith("--- Changelist")): + status = status_lines[2] + else: + status = status_lines[0] + # If we have a revision to diff against we need to run "svn list" + # for the old and the new revision and compare the results to get + # the correct status for a file. + else: + dirname, relfilename = os.path.split(filename) + if dirname not in self.svnls_cache: + cmd = ["svn", "list", "-r", self.rev_start, dirname or "."] + out, returncode = RunShellWithReturnCode(cmd) + if returncode: + ErrorExit("Failed to get status for %s." % filename) + old_files = out.splitlines() + args = ["svn", "list"] + if self.rev_end: + args += ["-r", self.rev_end] + cmd = args + [dirname or "."] + out, returncode = RunShellWithReturnCode(cmd) + if returncode: + ErrorExit("Failed to run command %s" % cmd) + self.svnls_cache[dirname] = (old_files, out.splitlines()) + old_files, new_files = self.svnls_cache[dirname] + if relfilename in old_files and relfilename not in new_files: + status = "D " + elif relfilename in old_files and relfilename in new_files: + status = "M " + else: + status = "A " + return status + + def GetBaseFile(self, filename): + status = self.GetStatus(filename) + base_content = None + new_content = None + + # If a file is copied its status will be "A +", which signifies + # "addition-with-history". See "svn st" for more information. We need to + # upload the original file or else diff parsing will fail if the file was + # edited. + if status[0] == "A" and status[3] != "+": + # We'll need to upload the new content if we're adding a binary file + # since diff's output won't contain it. + mimetype = RunShell(["svn", "propget", "svn:mime-type", filename], + silent_ok=True) + base_content = "" + is_binary = mimetype and not mimetype.startswith("text/") + if is_binary and self.IsImage(filename): + new_content = self.ReadFile(filename) + elif (status[0] in ("M", "D", "R") or + (status[0] == "A" and status[3] == "+") or # Copied file. + (status[0] == " " and status[1] == "M")): # Property change. + args = [] + if self.options.revision: + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + else: + # Don't change filename, it's needed later. + url = filename + args += ["-r", "BASE"] + cmd = ["svn"] + args + ["propget", "svn:mime-type", url] + mimetype, returncode = RunShellWithReturnCode(cmd) + if returncode: + # File does not exist in the requested revision. + # Reset mimetype, it contains an error message. + mimetype = "" + get_base = False + is_binary = mimetype and not mimetype.startswith("text/") + if status[0] == " ": + # Empty base content just to force an upload. + base_content = "" + elif is_binary: + if self.IsImage(filename): + get_base = True + if status[0] == "M": + if not self.rev_end: + new_content = self.ReadFile(filename) + else: + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end) + new_content = RunShell(["svn", "cat", url], + universal_newlines=True, silent_ok=True) + else: + base_content = "" + else: + get_base = True + + if get_base: + if is_binary: + universal_newlines = False + else: + universal_newlines = True + if self.rev_start: + # "svn cat -r REV delete_file.txt" doesn't work. cat requires + # the full URL with "@REV" appended instead of using "-r" option. + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + base_content = RunShell(["svn", "cat", url], + universal_newlines=universal_newlines, + silent_ok=True) + else: + base_content = RunShell(["svn", "cat", filename], + universal_newlines=universal_newlines, + silent_ok=True) + if not is_binary: + args = [] + if self.rev_start: + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + else: + url = filename + args += ["-r", "BASE"] + cmd = ["svn"] + args + ["propget", "svn:keywords", url] + keywords, returncode = RunShellWithReturnCode(cmd) + if keywords and not returncode: + base_content = self._CollapseKeywords(base_content, keywords) + else: + StatusUpdate("svn status returned unexpected output: %s" % status) + sys.exit(1) + return base_content, new_content, is_binary, status[0:5] + + +class GitVCS(VersionControlSystem): + """Implementation of the VersionControlSystem interface for Git.""" + + def __init__(self, options): + super(GitVCS, self).__init__(options) + # Map of filename -> hash of base file. + self.base_hashes = {} + + def GenerateDiff(self, extra_args): + # This is more complicated than svn's GenerateDiff because we must convert + # the diff output to include an svn-style "Index:" line as well as record + # the hashes of the base files, so we can upload them along with our diff. + if self.options.revision: + extra_args = [self.options.revision] + extra_args + gitdiff = RunShell(["git", "diff", "--full-index"] + extra_args) + svndiff = [] + filecount = 0 + filename = None + for line in gitdiff.splitlines(): + match = re.match(r"diff --git a/(.*) b/.*$", line) + if match: + filecount += 1 + filename = match.group(1) + svndiff.append("Index: %s\n" % filename) + else: + # The "index" line in a git diff looks like this (long hashes elided): + # index 82c0d44..b2cee3f 100755 + # We want to save the left hash, as that identifies the base file. + match = re.match(r"index (\w+)\.\.", line) + if match: + self.base_hashes[filename] = match.group(1) + svndiff.append(line + "\n") + if not filecount: + ErrorExit("No valid patches found in output from git diff") + return "".join(svndiff) + + def GetUnknownFiles(self): + status = RunShell(["git", "ls-files", "--exclude-standard", "--others"], + silent_ok=True) + return status.splitlines() + + def GetBaseFile(self, filename): + hash = self.base_hashes[filename] + base_content = None + new_content = None + is_binary = False + if hash == "0" * 40: # All-zero hash indicates no base file. + status = "A" + base_content = "" + else: + status = "M" + base_content, returncode = RunShellWithReturnCode(["git", "show", hash]) + if returncode: + ErrorExit("Got error status from 'git show %s'" % hash) + return (base_content, new_content, is_binary, status) + + +class MercurialVCS(VersionControlSystem): + """Implementation of the VersionControlSystem interface for Mercurial.""" + + def __init__(self, options, repo_dir): + super(MercurialVCS, self).__init__(options) + # Absolute path to repository (we can be in a subdir) + self.repo_dir = os.path.normpath(repo_dir) + # Compute the subdir + cwd = os.path.normpath(os.getcwd()) + assert cwd.startswith(self.repo_dir) + self.subdir = cwd[len(self.repo_dir):].lstrip(r"\/") + if self.options.revision: + self.base_rev = self.options.revision + else: + self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip() + + def _GetRelPath(self, filename): + """Get relative path of a file according to the current directory, + given its logical path in the repo.""" + assert filename.startswith(self.subdir), filename + return filename[len(self.subdir):].lstrip(r"\/") + + def GenerateDiff(self, extra_args): + # If no file specified, restrict to the current subdir + extra_args = extra_args or ["."] + cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args + data = RunShell(cmd, silent_ok=True) + svndiff = [] + filecount = 0 + for line in data.splitlines(): + m = re.match("diff --git a/(\S+) b/(\S+)", line) + if m: + # Modify line to make it look like as it comes from svn diff. + # With this modification no changes on the server side are required + # to make upload.py work with Mercurial repos. + # NOTE: for proper handling of moved/copied files, we have to use + # the second filename. + filename = m.group(2) + svndiff.append("Index: %s" % filename) + svndiff.append("=" * 67) + filecount += 1 + logging.info(line) + else: + svndiff.append(line) + if not filecount: + ErrorExit("No valid patches found in output from hg diff") + return "\n".join(svndiff) + "\n" + + def GetUnknownFiles(self): + """Return a list of files unknown to the VCS.""" + args = [] + status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], + silent_ok=True) + unknown_files = [] + for line in status.splitlines(): + st, fn = line.split(" ", 1) + if st == "?": + unknown_files.append(fn) + return unknown_files + + def GetBaseFile(self, filename): + # "hg status" and "hg cat" both take a path relative to the current subdir + # rather than to the repo root, but "hg diff" has given us the full path + # to the repo root. + base_content = "" + new_content = None + is_binary = False + oldrelpath = relpath = self._GetRelPath(filename) + # "hg status -C" returns two lines for moved/copied files, one otherwise + out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) + out = out.splitlines() + # HACK: strip error message about missing file/directory if it isn't in + # the working copy + if out[0].startswith('%s: ' % relpath): + out = out[1:] + if len(out) > 1: + # Moved/copied => considered as modified, use old filename to + # retrieve base contents + oldrelpath = out[1].strip() + status = "M" + else: + status, _ = out[0].split(' ', 1) + if status != "A": + base_content = RunShell(["hg", "cat", "-r", self.base_rev, oldrelpath], + silent_ok=True) + is_binary = "\0" in base_content # Mercurial's heuristic + if status != "R": + new_content = open(relpath, "rb").read() + is_binary = is_binary or "\0" in new_content + if is_binary and base_content: + # Fetch again without converting newlines + base_content = RunShell(["hg", "cat", "-r", self.base_rev, oldrelpath], + silent_ok=True, universal_newlines=False) + if not is_binary or not self.IsImage(relpath): + new_content = None + return base_content, new_content, is_binary, status + + +# NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. +def SplitPatch(data): + """Splits a patch into separate pieces for each file. + + Args: + data: A string containing the output of svn diff. + + Returns: + A list of 2-tuple (filename, text) where text is the svn diff output + pertaining to filename. + """ + patches = [] + filename = None + diff = [] + for line in data.splitlines(True): + new_filename = None + if line.startswith('Index:'): + unused, new_filename = line.split(':', 1) + new_filename = new_filename.strip() + elif line.startswith('Property changes on:'): + unused, temp_filename = line.split(':', 1) + # When a file is modified, paths use '/' between directories, however + # when a property is modified '\' is used on Windows. Make them the same + # otherwise the file shows up twice. + temp_filename = temp_filename.strip().replace('\\', '/') + if temp_filename != filename: + # File has property changes but no modifications, create a new diff. + new_filename = temp_filename + if new_filename: + if filename and diff: + patches.append((filename, ''.join(diff))) + filename = new_filename + diff = [line] + continue + if diff is not None: + diff.append(line) + if filename and diff: + patches.append((filename, ''.join(diff))) + return patches + + +def UploadSeparatePatches(issue, rpc_server, patchset, data, options): + """Uploads a separate patch for each file in the diff output. + + Returns a list of [patch_key, filename] for each file. + """ + patches = SplitPatch(data) + rv = [] + for patch in patches: + if len(patch[1]) > MAX_UPLOAD_SIZE: + print ("Not uploading the patch for " + patch[0] + + " because the file is too large.") + continue + form_fields = [("filename", patch[0])] + if not options.download_base: + form_fields.append(("content_upload", "1")) + files = [("data", "data.diff", patch[1])] + ctype, body = EncodeMultipartFormData(form_fields, files) + url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) + print "Uploading patch for " + patch[0] + response_body = rpc_server.Send(url, body, content_type=ctype) + lines = response_body.splitlines() + if not lines or lines[0] != "OK": + StatusUpdate(" --> %s" % response_body) + sys.exit(1) + rv.append([lines[1], patch[0]]) + return rv + + +def GuessVCS(options): + """Helper to guess the version control system. + + This examines the current directory, guesses which VersionControlSystem + we're using, and returns an instance of the appropriate class. Exit with an + error if we can't figure it out. + + Returns: + A VersionControlSystem instance. Exits if the VCS can't be guessed. + """ + # Mercurial has a command to get the base directory of a repository + # Try running it, but don't die if we don't have hg installed. + # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. + try: + out, returncode = RunShellWithReturnCode(["hg", "root"]) + if returncode == 0: + return MercurialVCS(options, out.strip()) + except OSError, (errno, message): + if errno != 2: # ENOENT -- they don't have hg installed. + raise + + # Subversion has a .svn in all working directories. + if os.path.isdir('.svn'): + logging.info("Guessed VCS = Subversion") + return SubversionVCS(options) + + # Git has a command to test if you're in a git tree. + # Try running it, but don't die if we don't have git installed. + try: + out, returncode = RunShellWithReturnCode(["git", "rev-parse", + "--is-inside-work-tree"]) + if returncode == 0: + return GitVCS(options) + except OSError, (errno, message): + if errno != 2: # ENOENT -- they don't have git installed. + raise + + ErrorExit(("Could not guess version control system. " + "Are you in a working copy directory?")) + + +def RealMain(argv, data=None): + """The real main function. + + Args: + argv: Command line arguments. + data: Diff contents. If None (default) the diff is generated by + the VersionControlSystem implementation returned by GuessVCS(). + + Returns: + A 2-tuple (issue id, patchset id). + The patchset id is None if the base files are not uploaded by this + script (applies only to SVN checkouts). + """ + logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" + "%(lineno)s %(message)s ")) + os.environ['LC_ALL'] = 'C' + options, args = parser.parse_args(argv[1:]) + global verbosity + verbosity = options.verbose + if verbosity >= 3: + logging.getLogger().setLevel(logging.DEBUG) + elif verbosity >= 2: + logging.getLogger().setLevel(logging.INFO) + vcs = GuessVCS(options) + if isinstance(vcs, SubversionVCS): + # base field is only allowed for Subversion. + # Note: Fetching base files may become deprecated in future releases. + base = vcs.GuessBase(options.download_base) + else: + base = None + if not base and options.download_base: + options.download_base = True + logging.info("Enabled upload of base file") + if not options.assume_yes: + vcs.CheckForUnknownFiles() + if data is None: + data = vcs.GenerateDiff(args) + files = vcs.GetBaseFiles(data) + if verbosity >= 1: + print "Upload server:", options.server, "(change with -s/--server)" + if options.issue: + prompt = "Message describing this patch set: " + else: + prompt = "New issue subject: " + message = options.message or raw_input(prompt).strip() + if not message: + ErrorExit("A non-empty message is required") + rpc_server = GetRpcServer(options) + form_fields = [("subject", message)] + if base: + form_fields.append(("base", base)) + if options.issue: + form_fields.append(("issue", str(options.issue))) + if options.email: + form_fields.append(("user", options.email)) + if options.reviewers: + for reviewer in options.reviewers.split(','): + if "@" in reviewer and not reviewer.split("@")[1].count(".") == 1: + ErrorExit("Invalid email address: %s" % reviewer) + form_fields.append(("reviewers", options.reviewers)) + if options.cc: + for cc in options.cc.split(','): + if "@" in cc and not cc.split("@")[1].count(".") == 1: + ErrorExit("Invalid email address: %s" % cc) + form_fields.append(("cc", options.cc)) + description = options.description + if options.description_file: + if options.description: + ErrorExit("Can't specify description and description_file") + file = open(options.description_file, 'r') + description = file.read() + file.close() + if description: + form_fields.append(("description", description)) + # Send a hash of all the base file so the server can determine if a copy + # already exists in an earlier patchset. + base_hashes = "" + for file, info in files.iteritems(): + if not info[0] is None: + checksum = md5.new(info[0]).hexdigest() + if base_hashes: + base_hashes += "|" + base_hashes += checksum + ":" + file + form_fields.append(("base_hashes", base_hashes)) + # If we're uploading base files, don't send the email before the uploads, so + # that it contains the file status. + if options.send_mail and options.download_base: + form_fields.append(("send_mail", "1")) + if not options.download_base: + form_fields.append(("content_upload", "1")) + if len(data) > MAX_UPLOAD_SIZE: + print "Patch is large, so uploading file patches separately." + uploaded_diff_file = [] + form_fields.append(("separate_patches", "1")) + else: + uploaded_diff_file = [("data", "data.diff", data)] + ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file) + response_body = rpc_server.Send("/upload", body, content_type=ctype) + patchset = None + if not options.download_base or not uploaded_diff_file: + lines = response_body.splitlines() + if len(lines) >= 2: + msg = lines[0] + patchset = lines[1].strip() + patches = [x.split(" ", 1) for x in lines[2:]] + else: + msg = response_body + else: + msg = response_body + StatusUpdate(msg) + if not response_body.startswith("Issue created.") and \ + not response_body.startswith("Issue updated."): + sys.exit(0) + issue = msg[msg.rfind("/")+1:] + + if not uploaded_diff_file: + result = UploadSeparatePatches(issue, rpc_server, patchset, data, options) + if not options.download_base: + patches = result + + if not options.download_base: + vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) + if options.send_mail: + rpc_server.Send("/" + issue + "/mail", payload="") + return issue, patchset + + +def main(): + try: + RealMain(sys.argv) + except KeyboardInterrupt: + print + StatusUpdate("Interrupted.") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/3rdparty/gtest/scripts/upload_gtest.py b/3rdparty/gtest/scripts/upload_gtest.py new file mode 100644 index 0000000..be19ae8 --- /dev/null +++ b/3rdparty/gtest/scripts/upload_gtest.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""upload_gtest.py v0.1.0 -- uploads a Google Test patch for review. + +This simple wrapper passes all command line flags and +--cc=googletestframework@googlegroups.com to upload.py. + +USAGE: upload_gtest.py [options for upload.py] +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import sys + +CC_FLAG = '--cc=' +GTEST_GROUP = 'googletestframework@googlegroups.com' + + +def main(): + # Finds the path to upload.py, assuming it is in the same directory + # as this file. + my_dir = os.path.dirname(os.path.abspath(__file__)) + upload_py_path = os.path.join(my_dir, 'upload.py') + + # Adds Google Test discussion group to the cc line if it's not there + # already. + upload_py_argv = [upload_py_path] + found_cc_flag = False + for arg in sys.argv[1:]: + if arg.startswith(CC_FLAG): + found_cc_flag = True + cc_line = arg[len(CC_FLAG):] + cc_list = [addr for addr in cc_line.split(',') if addr] + if GTEST_GROUP not in cc_list: + cc_list.append(GTEST_GROUP) + upload_py_argv.append(CC_FLAG + ','.join(cc_list)) + else: + upload_py_argv.append(arg) + + if not found_cc_flag: + upload_py_argv.append(CC_FLAG + GTEST_GROUP) + + # Invokes upload.py with the modified command line flags. + os.execv(upload_py_path, upload_py_argv) + + +if __name__ == '__main__': + main() diff --git a/3rdparty/gtest/src/gtest-all.cc b/3rdparty/gtest/src/gtest-all.cc new file mode 100644 index 0000000..ad29290 --- /dev/null +++ b/3rdparty/gtest/src/gtest-all.cc @@ -0,0 +1,48 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Google C++ Testing and Mocking Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include "gtest/gtest.h" + +// The following lines pull in the real gtest *.cc files. +#include "src/gtest.cc" +#include "src/gtest-death-test.cc" +#include "src/gtest-filepath.cc" +#include "src/gtest-matchers.cc" +#include "src/gtest-port.cc" +#include "src/gtest-printers.cc" +#include "src/gtest-test-part.cc" +#include "src/gtest-typed-test.cc" diff --git a/3rdparty/gtest/src/gtest-death-test.cc b/3rdparty/gtest/src/gtest-death-test.cc new file mode 100644 index 0000000..da09a1c --- /dev/null +++ b/3rdparty/gtest/src/gtest-death-test.cc @@ -0,0 +1,1653 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// This file implements death tests. + +#include "gtest/gtest-death-test.h" + +#include + +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/custom/gtest.h" + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_MAC +# include +# endif // GTEST_OS_MAC + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include + +# if GTEST_OS_WINDOWS +# include +# else +# include +# include +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_QNX +# include +# endif // GTEST_OS_QNX + +# if GTEST_OS_FUCHSIA +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# endif // GTEST_OS_FUCHSIA + +#endif // GTEST_HAS_DEATH_TEST + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-string.h" +#include "src/gtest-internal-inl.h" + +namespace testing { + +// Constants. + +// The default death test style. +// +// This is defined in internal/gtest-port.h as "fast", but can be overridden by +// a definition in internal/custom/gtest-port.h. The recommended value, which is +// used internally at Google, is "threadsafe". +static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "the '|' characters. This flag is specified if and only if the " + "current process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Valid only for fast death tests. Indicates the code is running in the +// child process of a fast style death test. +# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +static bool g_in_fast_death_test_child = false; +# endif + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +bool InDeathTestChild() { +# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA + + // On Windows and Fuchsia, death tests are thread-safe regardless of the value + // of the death_test_style flag. + return !GTEST_FLAG(internal_run_death_test).empty(); + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") + return !GTEST_FLAG(internal_run_death_test).empty(); + else + return g_in_fast_death_test_child; +#endif +} + +} // namespace internal + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA + + return exit_status == exit_code_; + +# else + + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; + +# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA +} + +# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { +# if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) + { + bool result; + if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { + return result; + } + } +# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static std::string ExitSummary(int exit_code) { + Message m; + +# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA + + m << "Exited with exit status " << exit_code; + +# else + + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +# ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +# endif +# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA + + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static std::string DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) { + msg << "couldn't detect the number of threads."; + } else { + msg << "detected " << thread_count << " threads."; + } + msg << " See " + "https://github.com/google/googletest/blob/master/googletest/docs/" + "advanced.md#death-tests-and-threads" + << " for more explanation and suggested solutions, especially if" + << " this is the last message you see before your test times out."; + return msg.GetString(); +} +# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestThrew = 'T'; +static const char kDeathTestInternalError = 'I'; + +#if GTEST_OS_FUCHSIA + +// File descriptor used for the pipe in the child process. +static const int kFuchsiaReadPipeFd = 3; + +#endif + +// An enumeration describing all of the possible ways that a death test can +// conclude. DIED means that the process died while executing the test +// code; LIVED means that process lived beyond the end of the test code; +// RETURNED means that the test statement attempted to execute a return +// statement, which is not allowed; THREW means that the test statement +// returned control by throwing an exception. IN_PROGRESS means the test +// has not yet concluded. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +static void DeathTestAbort(const std::string& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != nullptr) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + posix::Abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +# define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression + " != -1"); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +std::string GetLastErrnoDescription() { + return errno == 0 ? "" : posix::StrError(errno); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == nullptr) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, + Matcher matcher, const char* file, + int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, std::move(matcher), file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const std::string& message) { + last_death_test_message_ = message; +} + +std::string DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, Matcher matcher) + : statement_(a_statement), + matcher_(std::move(matcher)), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() override { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason) override; + bool Passed(bool status_ok) override; + + const char* statement() const { return statement_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + // Returns stderr output from the child process. + virtual std::string GetErrorLogs(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // A matcher that's expected to match the stderr output by the child process. + Matcher matcher_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestThrew: + set_outcome(THREW); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +std::string DeathTestImpl::GetErrorLogs() { + return GetCapturedStderr(); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : + reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, THREW, or RETURNED. The death test +// fails in the latter three cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// matcher_: A matcher that's expected to match the stderr output by the child +// process. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true if and only if all of the above conditions are met. Otherwise, +// the first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const std::string error_message = GetErrorLogs(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case DIED: + if (status_ok) { + if (matcher_.Matches(error_message)) { + success = true; + } else { + std::ostringstream stream; + matcher_.DescribeTo(&stream); + buffer << " Result: died but not with expected error.\n" + << " Expected: " << stream.str() << "\n" + << "Actual msg:\n" + << FormatDeathTestOutput(error_message); + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +# if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* a_statement, Matcher matcher, + const char* file, int line) + : DeathTestImpl(a_statement, std::move(matcher)), + file_(file), + line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); + child_handle_.Reset(); + set_status(static_cast(status_code)); + return status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != nullptr) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES), + nullptr, TRUE}; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + nullptr)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr); + const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + + kFilterFlag + "=" + info->test_suite_name() + + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + + "=" + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(static_cast(::GetCurrentProcessId())) + + // size_t has the same width as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + "|" + StreamableToString(reinterpret_cast(write_handle)) + + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr, + executable_path, + _MAX_PATH)); + + std::string command_line = + std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + + internal_flag + "\""; + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_( + ::CreateProcessA( + executable_path, const_cast(command_line.c_str()), + nullptr, // Retuned process handle is not inheritable. + nullptr, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + nullptr, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} + +# elif GTEST_OS_FUCHSIA + +class FuchsiaDeathTest : public DeathTestImpl { + public: + FuchsiaDeathTest(const char* a_statement, Matcher matcher, + const char* file, int line) + : DeathTestImpl(a_statement, std::move(matcher)), + file_(file), + line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + int Wait() override; + TestRole AssumeRole() override; + std::string GetErrorLogs() override; + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // The stderr data captured by the child process. + std::string captured_stderr_; + + zx::process child_process_; + zx::channel exception_channel_; + zx::socket stderr_socket_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { args_.push_back(nullptr); } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + + int size() { + return args_.size() - 1; + } + + private: + std::vector args_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int FuchsiaDeathTest::Wait() { + const int kProcessKey = 0; + const int kSocketKey = 1; + const int kExceptionKey = 2; + + if (!spawned()) + return 0; + + // Create a port to wait for socket/task/exception events. + zx_status_t status_zx; + zx::port port; + status_zx = zx::port::create(0, &port); + GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); + + // Register to wait for the child process to terminate. + status_zx = child_process_.wait_async( + port, kProcessKey, ZX_PROCESS_TERMINATED, ZX_WAIT_ASYNC_ONCE); + GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); + + // Register to wait for the socket to be readable or closed. + status_zx = stderr_socket_.wait_async( + port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, + ZX_WAIT_ASYNC_ONCE); + GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); + + // Register to wait for an exception. + status_zx = exception_channel_.wait_async( + port, kExceptionKey, ZX_CHANNEL_READABLE, ZX_WAIT_ASYNC_ONCE); + GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); + + bool process_terminated = false; + bool socket_closed = false; + do { + zx_port_packet_t packet = {}; + status_zx = port.wait(zx::time::infinite(), &packet); + GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); + + if (packet.key == kExceptionKey) { + // Process encountered an exception. Kill it directly rather than + // letting other handlers process the event. We will get a kProcessKey + // event when the process actually terminates. + status_zx = child_process_.kill(); + GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); + } else if (packet.key == kProcessKey) { + // Process terminated. + GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type)); + GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED); + process_terminated = true; + } else if (packet.key == kSocketKey) { + GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type)); + if (packet.signal.observed & ZX_SOCKET_READABLE) { + // Read data from the socket. + constexpr size_t kBufferSize = 1024; + do { + size_t old_length = captured_stderr_.length(); + size_t bytes_read = 0; + captured_stderr_.resize(old_length + kBufferSize); + status_zx = stderr_socket_.read( + 0, &captured_stderr_.front() + old_length, kBufferSize, + &bytes_read); + captured_stderr_.resize(old_length + bytes_read); + } while (status_zx == ZX_OK); + if (status_zx == ZX_ERR_PEER_CLOSED) { + socket_closed = true; + } else { + GTEST_DEATH_TEST_CHECK_(status_zx == ZX_ERR_SHOULD_WAIT); + status_zx = stderr_socket_.wait_async( + port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, + ZX_WAIT_ASYNC_ONCE); + GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); + } + } else { + GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_SOCKET_PEER_CLOSED); + socket_closed = true; + } + } + } while (!process_terminated && !socket_closed); + + ReadAndInterpretStatusByte(); + + zx_info_process_t buffer; + status_zx = child_process_.get_info( + ZX_INFO_PROCESS, &buffer, sizeof(buffer), nullptr, nullptr); + GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); + + GTEST_DEATH_TEST_CHECK_(buffer.exited); + set_status(buffer.return_code); + return status(); +} + +// The AssumeRole process for a Fuchsia death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != nullptr) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(kFuchsiaReadPipeFd); + return EXECUTE_TEST; + } + + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // Build the child process command line. + const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + + kFilterFlag + "=" + info->test_suite_name() + + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + + file_ + "|" + + StreamableToString(line_) + "|" + + StreamableToString(death_test_index); + Arguments args; + args.AddArguments(GetInjectableArgvs()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + // Build the pipe for communication with the child. + zx_status_t status; + zx_handle_t child_pipe_handle; + int child_pipe_fd; + status = fdio_pipe_half(&child_pipe_fd, &child_pipe_handle); + GTEST_DEATH_TEST_CHECK_(status == ZX_OK); + set_read_fd(child_pipe_fd); + + // Set the pipe handle for the child. + fdio_spawn_action_t spawn_actions[2] = {}; + fdio_spawn_action_t* add_handle_action = &spawn_actions[0]; + add_handle_action->action = FDIO_SPAWN_ACTION_ADD_HANDLE; + add_handle_action->h.id = PA_HND(PA_FD, kFuchsiaReadPipeFd); + add_handle_action->h.handle = child_pipe_handle; + + // Create a socket pair will be used to receive the child process' stderr. + zx::socket stderr_producer_socket; + status = + zx::socket::create(0, &stderr_producer_socket, &stderr_socket_); + GTEST_DEATH_TEST_CHECK_(status >= 0); + int stderr_producer_fd = -1; + status = + fdio_fd_create(stderr_producer_socket.release(), &stderr_producer_fd); + GTEST_DEATH_TEST_CHECK_(status >= 0); + + // Make the stderr socket nonblocking. + GTEST_DEATH_TEST_CHECK_(fcntl(stderr_producer_fd, F_SETFL, 0) == 0); + + fdio_spawn_action_t* add_stderr_action = &spawn_actions[1]; + add_stderr_action->action = FDIO_SPAWN_ACTION_CLONE_FD; + add_stderr_action->fd.local_fd = stderr_producer_fd; + add_stderr_action->fd.target_fd = STDERR_FILENO; + + // Create a child job. + zx_handle_t child_job = ZX_HANDLE_INVALID; + status = zx_job_create(zx_job_default(), 0, & child_job); + GTEST_DEATH_TEST_CHECK_(status == ZX_OK); + zx_policy_basic_t policy; + policy.condition = ZX_POL_NEW_ANY; + policy.policy = ZX_POL_ACTION_ALLOW; + status = zx_job_set_policy( + child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, &policy, 1); + GTEST_DEATH_TEST_CHECK_(status == ZX_OK); + + // Create an exception channel attached to the |child_job|, to allow + // us to suppress the system default exception handler from firing. + status = + zx_task_create_exception_channel( + child_job, 0, exception_channel_.reset_and_get_address()); + GTEST_DEATH_TEST_CHECK_(status == ZX_OK); + + // Spawn the child process. + status = fdio_spawn_etc( + child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], args.Argv(), nullptr, + 2, spawn_actions, child_process_.reset_and_get_address(), nullptr); + GTEST_DEATH_TEST_CHECK_(status == ZX_OK); + + set_spawned(true); + return OVERSEE_TEST; +} + +std::string FuchsiaDeathTest::GetErrorLogs() { + return captured_stderr_; +} + +#else // We are neither on Windows, nor on Fuchsia. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, Matcher matcher); + + // All of these virtual functions are inherited from DeathTest. + int Wait() override; + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, + Matcher matcher) + : DeathTestImpl(a_statement, std::move(matcher)), child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, Matcher matcher) + : ForkingDeathTest(a_statement, std::move(matcher)) {} + TestRole AssumeRole() override; +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + g_in_fast_death_test_child = true; + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, Matcher matcher, + const char* file, int line) + : ForkingDeathTest(a_statement, std::move(matcher)), + file_(file), + line_(line) {} + TestRole AssumeRole() override; + + private: + static ::std::vector GetArgvsForDeathTestChildProcess() { + ::std::vector args = GetInjectableArgvs(); +# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) + ::std::vector extra_args = + GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); + args.insert(args.end(), extra_args.begin(), extra_args.end()); +# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) + return args; + } + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { args_.push_back(nullptr); } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + + private: + std::vector args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +# if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +# else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +# endif // GTEST_OS_MAC + +# if !GTEST_OS_QNX +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + + original_dir + " failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; +} +# endif // !GTEST_OS_QNX + +# if GTEST_HAS_CLONE +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +// +// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining +// StackLowerThanAddress into StackGrowsDown, which then doesn't give +// correct answer. +static void StackLowerThanAddress(const void* ptr, + bool* result) GTEST_NO_INLINE_; +// HWAddressSanitizer add a random tag to the MSB of the local variable address, +// making comparison result unpredictable. +GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ +static void StackLowerThanAddress(const void* ptr, bool* result) { + int dummy; + *result = (&dummy < ptr); +} + +// Make sure AddressSanitizer does not tamper with the stack here. +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ +static bool StackGrowsDown() { + int dummy; + bool result; + StackLowerThanAddress(&dummy, &result); + return result; +} +# endif // GTEST_HAS_CLONE + +// Spawns a child process with the same executable as the current process in +// a thread-safe manner and instructs it to run the death test. The +// implementation uses fork(2) + exec. On systems where clone(2) is +// available, it is used instead, being slightly more thread-safe. On QNX, +// fork supports only single-threaded environments, so this function uses +// spawn(2) there instead. The function dies with an error message if +// anything goes wrong. +static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +# if GTEST_OS_QNX + // Obtains the current directory and sets it to be closed in the child + // process. + const int cwd_fd = open(".", O_RDONLY); + GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + int fd_flags; + // Set close_fd to be closed after spawn. + GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, + fd_flags | FD_CLOEXEC)); + struct inheritance inherit = {0}; + // spawn is a system call. + child_pid = + spawn(args.argv[0], 0, nullptr, &inherit, args.argv, GetEnviron()); + // Restores the current working directory. + GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); + +# else // GTEST_OS_QNX +# if GTEST_OS_LINUX + // When a SIGPROF signal is received while fork() or clone() are executing, + // the process may hang. To avoid this, we ignore SIGPROF here and re-enable + // it after the call to fork()/clone() is complete. + struct sigaction saved_sigprof_action; + struct sigaction ignore_sigprof_action; + memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); + sigemptyset(&ignore_sigprof_action.sa_mask); + ignore_sigprof_action.sa_handler = SIG_IGN; + GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( + SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); +# endif // GTEST_OS_LINUX + +# if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const auto stack_size = static_cast(getpagesize()); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + + // Maximum stack alignment in bytes: For a downward-growing stack, this + // amount is subtracted from size of the stack space to get an address + // that is within the stack space and is aligned on all systems we care + // about. As far as I know there is no ABI with stack alignment greater + // than 64. We assume stack and stack_size already have alignment of + // kMaxStackAlignment. + const size_t kMaxStackAlignment = 64; + void* const stack_top = + static_cast(stack) + + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); + GTEST_DEATH_TEST_CHECK_( + static_cast(stack_size) > kMaxStackAlignment && + reinterpret_cast(stack_top) % kMaxStackAlignment == 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +# else + const bool use_fork = true; +# endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } +# endif // GTEST_OS_QNX +# if GTEST_OS_LINUX + GTEST_DEATH_TEST_CHECK_SYSCALL_( + sigaction(SIGPROF, &saved_sigprof_action, nullptr)); +# endif // GTEST_OS_LINUX + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != nullptr) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + + kFilterFlag + "=" + info->test_suite_name() + + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvsForDeathTestChildProcess()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +# endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, + Matcher matcher, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != nullptr) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message( + "Death test count (" + StreamableToString(death_test_index) + + ") somehow exceeded expected maximum (" + + StreamableToString(flag->index()) + ")"); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = nullptr; + return true; + } + } + +# if GTEST_OS_WINDOWS + + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, std::move(matcher), file, line); + } + +# elif GTEST_OS_FUCHSIA + + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new FuchsiaDeathTest(statement, std::move(matcher), file, line); + } + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, std::move(matcher), file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, std::move(matcher)); + } + +# endif // GTEST_OS_WINDOWS + + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message( + "Unknown death test style \"" + GTEST_FLAG(death_test_style) + + "\" encountered"); + return false; + } + + return true; +} + +# if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +static int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort("Unable to open parent process " + + StreamableToString(parent_process_id)); + } + + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the pipe handle " + + StreamableToString(write_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the event handle " + + StreamableToString(event_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort("Unable to convert pipe handle " + + StreamableToString(write_handle_as_size_t) + + " to a file descriptor"); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +# endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return nullptr; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +# if GTEST_OS_WINDOWS + + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); + +# elif GTEST_OS_FUCHSIA + + if (fields.size() != 3 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + +# else + + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + +# endif // GTEST_OS_WINDOWS + + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing diff --git a/3rdparty/gtest/src/gtest-filepath.cc b/3rdparty/gtest/src/gtest-filepath.cc new file mode 100644 index 0000000..bd7b99f --- /dev/null +++ b/3rdparty/gtest/src/gtest-filepath.cc @@ -0,0 +1,379 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "gtest/internal/gtest-filepath.h" + +#include +#include "gtest/internal/gtest-port.h" +#include "gtest/gtest-message.h" + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +# include +#else +# include +# include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#include "gtest/internal/gtest-string.h" + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +# define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kAlternatePathSeparatorString[] = "/"; +# if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +# else +const char kCurrentDirectoryString[] = ".\\"; +# endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ + GTEST_OS_WINDOWS_RT || ARDUINO || defined(ESP_PLATFORM) + // These platforms do not have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + char* result = getcwd(cwd, sizeof(cwd)); +# if GTEST_OS_NACL + // getcwd will likely fail in NaCl due to the sandbox, so return something + // reasonable. The user may have provided a shim implementation for getcwd, + // however, so fallback only when failure is detected. + return FilePath(result == nullptr ? kCurrentDirectoryString : cwd); +# endif // GTEST_OS_NACL + return FilePath(result == nullptr ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + const std::string dot_extension = std::string(".") + extension; + if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { + return FilePath(pathname_.substr( + 0, pathname_.length() - dot_extension.length())); + } + return *this; +} + +// Returns a pointer to the last occurrence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != nullptr && + (last_sep == nullptr || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(last_sep + 1) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + std::string dir; + if (last_sep) { + dir = std::string(c_str(), static_cast(last_sep + 1 - c_str())); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + std::string file; + if (number == 0) { + file = base_name.string() + "." + extension; + } else { + file = base_name.string() + "_" + StreamableToString(number) + + "." + extension; + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(dir.string() + kPathSeparator + relative_path.string()); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, nullptr) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(pathname_.substr(0, pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +void FilePath::Normalize() { + if (pathname_.c_str() == nullptr) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing diff --git a/3rdparty/gtest/src/gtest-internal-inl.h b/3rdparty/gtest/src/gtest-internal-inl.h new file mode 100644 index 0000000..8ed70da --- /dev/null +++ b/3rdparty/gtest/src/gtest-internal-inl.h @@ -0,0 +1,1211 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Utility functions and classes used by the Google C++ testing framework.// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +#ifndef _WIN32_WCE +# include +#endif // !_WIN32_WCE +#include +#include // For strtoll/_strtoul64/malloc/free. +#include // For memmove. + +#include +#include +#include +#include + +#include "gtest/internal/gtest-port.h" + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +#if GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kPrintUTF8Flag[] = "print_utf8"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kStreamResultToFlag[] = "stream_result_to"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; +const char kFlagfileFlag[] = "flagfile"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true if and only if the --help flag or an equivalent form +// is specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true if and only if Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Converts the given time in milliseconds to a date string in the ISO 8601 +// format, without the timezone information. N.B.: due to the use the +// non-reentrant localtime() function, this function is not thread safe. Do +// not use it in any code that can be called from multiple threads. +GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast(GetTimeInMillis()) : + static_cast(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + print_utf8_ = GTEST_FLAG(print_utf8); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(print_utf8) = print_utf8_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + std::string color_; + std::string death_test_style_; + bool death_test_use_fork_; + std::string filter_; + std::string internal_run_death_test_; + bool list_tests_; + std::string output_; + bool print_time_; + bool print_utf8_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + std::string stream_result_to_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true if and only if the test should be run on this shard. The test id +// is some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template +inline int CountIf(const Container& c, Predicate predicate) { + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) + ++count; + } + return count; +} + +// Applies a function/functor to each element in the container. +template +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template +inline E GetElementOr(const std::vector& v, int i, E default_value) { + return (i < 0 || i >= static_cast(v.size())) ? default_value + : v[static_cast(i)]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector* v) { + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = + begin + + static_cast(random->Generate(static_cast(range_width))); + std::swap((*v)[static_cast(selected)], + (*v)[static_cast(last_in_range)]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template +inline void Shuffle(internal::Random* random, std::vector* v) { + ShuffleRange(random, 0, static_cast(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} + + // Returns true if and only if the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return test_property.key() == key_; + } + + private: + std::string key_; +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static std::string GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static std::string GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true if and only if the wildcard pattern matches the string. + // The first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true if and only if the user-specified filter matches the test + // suite name and the test name. + static bool FilterMatchesTest(const std::string& test_suite_name, + const std::string& test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const std::string& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as an std::string. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual std::string CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() {} + + std::string CurrentStackTrace(int max_depth, int skip_count) override; + void UponLeavingGTest() override; + + private: +#if GTEST_HAS_ABSL + Mutex mutex_; // Protects all internal state. + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to the stack trace code from within the user code. + void* caller_frame_ = nullptr; +#endif // GTEST_HAS_ABSL + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + std::string message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + void ReportTestPartResult(const TestPartResult& result) override; + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + void ReportTestPartResult(const TestPartResult& result) override; + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test suites. + int successful_test_suite_count() const; + + // Gets the number of failed test suites. + int failed_test_suite_count() const; + + // Gets the number of all test suites. + int total_test_suite_count() const; + + // Gets the number of all test suites that contain at least one test + // that should run. + int test_suite_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of skipped tests. + int skipped_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true if and only if the unit test passed (i.e. all test suites + // passed). + bool Passed() const { return !Failed(); } + + // Returns true if and only if the unit test failed (i.e. some test suite + // failed or something outside of all tests failed). + bool Failed() const { + return failed_test_suite_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test suite among all the test suites. i can range from 0 to + // total_test_suite_count() - 1. If i is not in that range, returns NULL. + const TestSuite* GetTestSuite(int i) const { + const int index = GetElementOr(test_suite_indices_, i, -1); + return index < 0 ? nullptr : test_suites_[static_cast(i)]; + } + + // Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + const TestCase* GetTestCase(int i) const { return GetTestSuite(i); } +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + // Gets the i-th test suite among all the test suites. i can range from 0 to + // total_test_suite_count() - 1. If i is not in that range, returns NULL. + TestSuite* GetMutableSuiteCase(int i) { + const int index = GetElementOr(test_suite_indices_, i, -1); + return index < 0 ? nullptr : test_suites_[static_cast(index)]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as an std::string. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + + // Finds and returns a TestSuite with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_suite_name: name of the test suite + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test suite + // tear_down_tc: pointer to the function that tears down the test suite + TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param, + internal::SetUpTestSuiteFunc set_up_tc, + internal::TearDownTestSuiteFunc tear_down_tc); + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + TestCase* GetTestCase(const char* test_case_name, const char* type_param, + internal::SetUpTestSuiteFunc set_up_tc, + internal::TearDownTestSuiteFunc tear_down_tc) { + return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc); + } +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test suite + // tear_down_tc: pointer to the function that tears down the test suite + // test_info: the TestInfo object + void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc, + internal::TearDownTestSuiteFunc tear_down_tc, + TestInfo* test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestSuite(test_info->test_suite_name(), test_info->type_param(), + set_up_tc, tear_down_tc) + ->AddTestInfo(test_info); + } + + // Returns ParameterizedTestSuiteRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } + + // Sets the TestSuite object for the test that's currently running. + void set_current_test_suite(TestSuite* a_current_test_suite) { + current_test_suite_ = a_current_test_suite; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); + + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() { + ForEach(test_suites_, TestSuite::ClearTestSuiteResult); + } + + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() { + ad_hoc_test_result_.Clear(); + } + + // Adds a TestProperty to the current TestResult object when invoked in a + // context of a test or a test suite, or to the global property set. If the + // result already contains a property with the same key, the value will be + // updated. + void RecordProperty(const TestProperty& test_property); + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestSuite and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestSuite* current_test_suite() const { return current_test_suite_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); +#endif + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test suites, and the tests within each test suite, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test suites and tests to their order before the first shuffle. + void UnshuffleTests(); + + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } + + private: + friend class ::testing::UnitTest; + + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; + + // The vector of TestSuites in their original order. It owns the + // elements in the vector. + std::vector test_suites_; + + // Provides a level of indirection for the test suite list to allow + // easy shuffling and restoring the test suite order. The i-th + // element of this vector is the index of the i-th test suite in the + // shuffled order. + std::vector test_suite_indices_; + + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestSuiteRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; + + // Index of the last death test suite registered. Initially -1. + int last_death_test_suite_; + + // This points to the TestSuite for the currently running test. It + // changes as Google Test goes through one test suite after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestSuite* current_test_suite_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True if and only if PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // The time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + std::unique_ptr internal_run_death_test_flag_; + std::unique_ptr death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; + + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +#if GTEST_USES_SIMPLE_RE + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsAsciiDigit(char ch); +GTEST_API_ bool IsAsciiPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsAsciiWhiteSpace(char ch); +GTEST_API_ bool IsAsciiWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +#endif // GTEST_USES_SIMPLE_RE + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +GTEST_API_ std::string GetLastErrnoDescription(); + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !IsDigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. + +# if GTEST_OS_WINDOWS && !defined(__GNUC__) + + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); + +# else + + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); + +# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + + const bool parse_success = *end == '\0' && errno == 0; + + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const std::string& xml_element, + const TestProperty& property) { + test_result->RecordProperty(xml_element, property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class StreamingListener : public EmptyTestEventListener { + public: + // Abstract base class for writing strings to a socket. + class AbstractSocketWriter { + public: + virtual ~AbstractSocketWriter() {} + + // Sends a string to the socket. + virtual void Send(const std::string& message) = 0; + + // Closes the socket. + virtual void CloseConnection() {} + + // Sends a string and a newline to the socket. + void SendLn(const std::string& message) { Send(message + "\n"); } + }; + + // Concrete class for actually writing strings to a socket. + class SocketWriter : public AbstractSocketWriter { + public: + SocketWriter(const std::string& host, const std::string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + } + + ~SocketWriter() override { + if (sockfd_ != -1) + CloseConnection(); + } + + // Sends a string to the socket. + void Send(const std::string& message) override { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const auto len = static_cast(message.length()); + if (write(sockfd_, message.c_str(), len) != static_cast(len)) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() override { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + int sockfd_; // socket file descriptor + const std::string host_name_; + const std::string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); + }; // class SocketWriter + + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static std::string UrlEncode(const char* str); + + StreamingListener(const std::string& host, const std::string& port) + : socket_writer_(new SocketWriter(host, port)) { + Start(); + } + + explicit StreamingListener(AbstractSocketWriter* socket_writer) + : socket_writer_(socket_writer) { Start(); } + + void OnTestProgramStart(const UnitTest& /* unit_test */) override { + SendLn("event=TestProgramStart"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) override { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); + + // Notify the streaming server to stop. + socket_writer_->CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, + int iteration) override { + SendLn("event=TestIterationStart&iteration=" + + StreamableToString(iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, + int /* iteration */) override { + SendLn("event=TestIterationEnd&passed=" + + FormatBool(unit_test.Passed()) + "&elapsed_time=" + + StreamableToString(unit_test.elapsed_time()) + "ms"); + } + + // Note that "event=TestCaseStart" is a wire format and has to remain + // "case" for compatibilty + void OnTestCaseStart(const TestCase& test_case) override { + SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); + } + + // Note that "event=TestCaseEnd" is a wire format and has to remain + // "case" for compatibilty + void OnTestCaseEnd(const TestCase& test_case) override { + SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + + "ms"); + } + + void OnTestStart(const TestInfo& test_info) override { + SendLn(std::string("event=TestStart&name=") + test_info.name()); + } + + void OnTestEnd(const TestInfo& test_info) override { + SendLn("event=TestEnd&passed=" + + FormatBool((test_info.result())->Passed()) + + "&elapsed_time=" + + StreamableToString((test_info.result())->elapsed_time()) + "ms"); + } + + void OnTestPartResult(const TestPartResult& test_part_result) override { + const char* file_name = test_part_result.file_name(); + if (file_name == nullptr) file_name = ""; + SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + + "&line=" + StreamableToString(test_part_result.line_number()) + + "&message=" + UrlEncode(test_part_result.message())); + } + + private: + // Sends the given message and a newline to the socket. + void SendLn(const std::string& message) { socket_writer_->SendLn(message); } + + // Called at the start of streaming to notify the receiver what + // protocol we are using. + void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } + + std::string FormatBool(bool value) { return value ? "1" : "0"; } + + const std::unique_ptr socket_writer_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +#endif // GTEST_CAN_STREAM_RESULTS_ + +} // namespace internal +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ diff --git a/3rdparty/gtest/src/gtest-matchers.cc b/3rdparty/gtest/src/gtest-matchers.cc new file mode 100644 index 0000000..7d2fb68 --- /dev/null +++ b/3rdparty/gtest/src/gtest-matchers.cc @@ -0,0 +1,97 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This file implements just enough of the matcher interface to allow +// EXPECT_DEATH and friends to accept a matcher argument. + +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-port.h" +#include "gtest/gtest-matchers.h" + +#include + +namespace testing { + +// Constructs a matcher that matches a const std::string& whose value is +// equal to s. +Matcher::Matcher(const std::string& s) { *this = Eq(s); } + +// Constructs a matcher that matches a const std::string& whose value is +// equal to s. +Matcher::Matcher(const char* s) { + *this = Eq(std::string(s)); +} + +// Constructs a matcher that matches a std::string whose value is equal to +// s. +Matcher::Matcher(const std::string& s) { *this = Eq(s); } + +// Constructs a matcher that matches a std::string whose value is equal to +// s. +Matcher::Matcher(const char* s) { *this = Eq(std::string(s)); } + +#if GTEST_HAS_ABSL +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher::Matcher(const std::string& s) { + *this = Eq(s); +} + +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher::Matcher(const char* s) { + *this = Eq(std::string(s)); +} + +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher::Matcher(absl::string_view s) { + *this = Eq(std::string(s)); +} + +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher::Matcher(const std::string& s) { *this = Eq(s); } + +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher::Matcher(const char* s) { + *this = Eq(std::string(s)); +} + +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher::Matcher(absl::string_view s) { + *this = Eq(std::string(s)); +} +#endif // GTEST_HAS_ABSL + +} // namespace testing diff --git a/3rdparty/gtest/src/gtest-port.cc b/3rdparty/gtest/src/gtest-port.cc new file mode 100644 index 0000000..fc5ba6b --- /dev/null +++ b/3rdparty/gtest/src/gtest-port.cc @@ -0,0 +1,1399 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "gtest/internal/gtest-port.h" + +#include +#include +#include +#include +#include +#include + +#if GTEST_OS_WINDOWS +# include +# include +# include +# include // Used in ThreadLocal. +# ifdef _MSC_VER +# include +# endif // _MSC_VER +#else +# include +#endif // GTEST_OS_WINDOWS + +#if GTEST_OS_MAC +# include +# include +# include +#endif // GTEST_OS_MAC + +#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ + GTEST_OS_NETBSD || GTEST_OS_OPENBSD +# include +# if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD +# include +# endif +#endif + +#if GTEST_OS_QNX +# include +# include +# include +#endif // GTEST_OS_QNX + +#if GTEST_OS_AIX +# include +# include +#endif // GTEST_OS_AIX + +#if GTEST_OS_FUCHSIA +# include +# include +#endif // GTEST_OS_FUCHSIA + +#include "gtest/gtest-spi.h" +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" +#include "src/gtest-internal-inl.h" + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_LINUX + +namespace { +template +T ReadProcFileField(const std::string& filename, int field) { + std::string dummy; + std::ifstream file(filename.c_str()); + while (field-- > 0) { + file >> dummy; + } + T output = 0; + file >> output; + return output; +} +} // namespace + +// Returns the number of active threads, or 0 when there is an error. +size_t GetThreadCount() { + const std::string filename = + (Message() << "/proc/" << getpid() << "/stat").GetString(); + return ReadProcFileField(filename, 19); +} + +#elif GTEST_OS_MAC + +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } else { + return 0; + } +} + +#elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ + GTEST_OS_NETBSD + +#if GTEST_OS_NETBSD +#undef KERN_PROC +#define KERN_PROC KERN_PROC2 +#define kinfo_proc kinfo_proc2 +#endif + +#if GTEST_OS_DRAGONFLY +#define KP_NLWP(kp) (kp.kp_nthreads) +#elif GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD +#define KP_NLWP(kp) (kp.ki_numthreads) +#elif GTEST_OS_NETBSD +#define KP_NLWP(kp) (kp.p_nlwps) +#endif + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + int mib[] = { + CTL_KERN, + KERN_PROC, + KERN_PROC_PID, + getpid(), +#if GTEST_OS_NETBSD + sizeof(struct kinfo_proc), + 1, +#endif + }; + u_int miblen = sizeof(mib) / sizeof(mib[0]); + struct kinfo_proc info; + size_t size = sizeof(info); + if (sysctl(mib, miblen, &info, &size, NULL, 0)) { + return 0; + } + return static_cast(KP_NLWP(info)); +} +#elif GTEST_OS_OPENBSD + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + int mib[] = { + CTL_KERN, + KERN_PROC, + KERN_PROC_PID | KERN_PROC_SHOW_THREADS, + getpid(), + sizeof(struct kinfo_proc), + 0, + }; + u_int miblen = sizeof(mib) / sizeof(mib[0]); + + // get number of structs + size_t size; + if (sysctl(mib, miblen, NULL, &size, NULL, 0)) { + return 0; + } + mib[5] = size / mib[4]; + + // populate array of structs + struct kinfo_proc info[mib[5]]; + if (sysctl(mib, miblen, &info, &size, NULL, 0)) { + return 0; + } + + // exclude empty members + int nthreads = 0; + for (int i = 0; i < size / mib[4]; i++) { + if (info[i].p_tid != -1) + nthreads++; + } + return nthreads; +} + +#elif GTEST_OS_QNX + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const int fd = open("/proc/self/as", O_RDONLY); + if (fd < 0) { + return 0; + } + procfs_info process_info; + const int status = + devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr); + close(fd); + if (status == EOK) { + return static_cast(process_info.num_threads); + } else { + return 0; + } +} + +#elif GTEST_OS_AIX + +size_t GetThreadCount() { + struct procentry64 entry; + pid_t pid = getpid(); + int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1); + if (status == 1) { + return entry.pi_thcount; + } else { + return 0; + } +} + +#elif GTEST_OS_FUCHSIA + +size_t GetThreadCount() { + int dummy_buffer; + size_t avail; + zx_status_t status = zx_object_get_info( + zx_process_self(), + ZX_INFO_PROCESS_THREADS, + &dummy_buffer, + 0, + nullptr, + &avail); + if (status == ZX_OK) { + return avail; + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_LINUX + +#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS + +void SleepMilliseconds(int n) { + ::Sleep(static_cast(n)); +} + +AutoHandle::AutoHandle() + : handle_(INVALID_HANDLE_VALUE) {} + +AutoHandle::AutoHandle(Handle handle) + : handle_(handle) {} + +AutoHandle::~AutoHandle() { + Reset(); +} + +AutoHandle::Handle AutoHandle::Get() const { + return handle_; +} + +void AutoHandle::Reset() { + Reset(INVALID_HANDLE_VALUE); +} + +void AutoHandle::Reset(HANDLE handle) { + // Resetting with the same handle we already own is invalid. + if (handle_ != handle) { + if (IsCloseable()) { + ::CloseHandle(handle_); + } + handle_ = handle; + } else { + GTEST_CHECK_(!IsCloseable()) + << "Resetting a valid handle to itself is likely a programmer error " + "and thus not allowed."; + } +} + +bool AutoHandle::IsCloseable() const { + // Different Windows APIs may use either of these values to represent an + // invalid handle. + return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE; +} + +Notification::Notification() + : event_(::CreateEvent(nullptr, // Default security attributes. + TRUE, // Do not reset automatically. + FALSE, // Initially unset. + nullptr)) { // Anonymous event. + GTEST_CHECK_(event_.Get() != nullptr); +} + +void Notification::Notify() { + GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); +} + +void Notification::WaitForNotification() { + GTEST_CHECK_( + ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); +} + +Mutex::Mutex() + : owner_thread_id_(0), + type_(kDynamic), + critical_section_init_phase_(0), + critical_section_(new CRITICAL_SECTION) { + ::InitializeCriticalSection(critical_section_); +} + +Mutex::~Mutex() { + // Static mutexes are leaked intentionally. It is not thread-safe to try + // to clean them up. + if (type_ == kDynamic) { + ::DeleteCriticalSection(critical_section_); + delete critical_section_; + critical_section_ = nullptr; + } +} + +void Mutex::Lock() { + ThreadSafeLazyInit(); + ::EnterCriticalSection(critical_section_); + owner_thread_id_ = ::GetCurrentThreadId(); +} + +void Mutex::Unlock() { + ThreadSafeLazyInit(); + // We don't protect writing to owner_thread_id_ here, as it's the + // caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_thread_id_ = 0; + ::LeaveCriticalSection(critical_section_); +} + +// Does nothing if the current thread holds the mutex. Otherwise, crashes +// with high probability. +void Mutex::AssertHeld() { + ThreadSafeLazyInit(); + GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) + << "The current thread is not holding the mutex @" << this; +} + +namespace { + +#ifdef _MSC_VER +// Use the RAII idiom to flag mem allocs that are intentionally never +// deallocated. The motivation is to silence the false positive mem leaks +// that are reported by the debug version of MS's CRT which can only detect +// if an alloc is missing a matching deallocation. +// Example: +// MemoryIsNotDeallocated memory_is_not_deallocated; +// critical_section_ = new CRITICAL_SECTION; +// +class MemoryIsNotDeallocated +{ + public: + MemoryIsNotDeallocated() : old_crtdbg_flag_(0) { + old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT + // doesn't report mem leak if there's no matching deallocation. + _CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF); + } + + ~MemoryIsNotDeallocated() { + // Restore the original _CRTDBG_ALLOC_MEM_DF flag + _CrtSetDbgFlag(old_crtdbg_flag_); + } + + private: + int old_crtdbg_flag_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated); +}; +#endif // _MSC_VER + +} // namespace + +// Initializes owner_thread_id_ and critical_section_ in static mutexes. +void Mutex::ThreadSafeLazyInit() { + // Dynamic mutexes are initialized in the constructor. + if (type_ == kStatic) { + switch ( + ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { + case 0: + // If critical_section_init_phase_ was 0 before the exchange, we + // are the first to test it and need to perform the initialization. + owner_thread_id_ = 0; + { + // Use RAII to flag that following mem alloc is never deallocated. +#ifdef _MSC_VER + MemoryIsNotDeallocated memory_is_not_deallocated; +#endif // _MSC_VER + critical_section_ = new CRITICAL_SECTION; + } + ::InitializeCriticalSection(critical_section_); + // Updates the critical_section_init_phase_ to 2 to signal + // initialization complete. + GTEST_CHECK_(::InterlockedCompareExchange( + &critical_section_init_phase_, 2L, 1L) == + 1L); + break; + case 1: + // Somebody else is already initializing the mutex; spin until they + // are done. + while (::InterlockedCompareExchange(&critical_section_init_phase_, + 2L, + 2L) != 2L) { + // Possibly yields the rest of the thread's time slice to other + // threads. + ::Sleep(0); + } + break; + + case 2: + break; // The mutex is already initialized and ready for use. + + default: + GTEST_CHECK_(false) + << "Unexpected value of critical_section_init_phase_ " + << "while initializing a static mutex."; + } + } +} + +namespace { + +class ThreadWithParamSupport : public ThreadWithParamBase { + public: + static HANDLE CreateThread(Runnable* runnable, + Notification* thread_can_start) { + ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); + DWORD thread_id; + HANDLE thread_handle = ::CreateThread( + nullptr, // Default security. + 0, // Default stack size. + &ThreadWithParamSupport::ThreadMain, + param, // Parameter to ThreadMainStatic + 0x0, // Default creation flags. + &thread_id); // Need a valid pointer for the call to work under Win98. + GTEST_CHECK_(thread_handle != nullptr) + << "CreateThread failed with error " << ::GetLastError() << "."; + if (thread_handle == nullptr) { + delete param; + } + return thread_handle; + } + + private: + struct ThreadMainParam { + ThreadMainParam(Runnable* runnable, Notification* thread_can_start) + : runnable_(runnable), + thread_can_start_(thread_can_start) { + } + std::unique_ptr runnable_; + // Does not own. + Notification* thread_can_start_; + }; + + static DWORD WINAPI ThreadMain(void* ptr) { + // Transfers ownership. + std::unique_ptr param(static_cast(ptr)); + if (param->thread_can_start_ != nullptr) + param->thread_can_start_->WaitForNotification(); + param->runnable_->Run(); + return 0; + } + + // Prohibit instantiation. + ThreadWithParamSupport(); + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); +}; + +} // namespace + +ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, + Notification* thread_can_start) + : thread_(ThreadWithParamSupport::CreateThread(runnable, + thread_can_start)) { +} + +ThreadWithParamBase::~ThreadWithParamBase() { + Join(); +} + +void ThreadWithParamBase::Join() { + GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) + << "Failed to join the thread with error " << ::GetLastError() << "."; +} + +// Maps a thread to a set of ThreadIdToThreadLocals that have values +// instantiated on that thread and notifies them when the thread exits. A +// ThreadLocal instance is expected to persist until all threads it has +// values on have terminated. +class ThreadLocalRegistryImpl { + public: + // Registers thread_local_instance as having value on the current thread. + // Returns a value that can be used to identify the thread from other threads. + static ThreadLocalValueHolderBase* GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + DWORD current_thread = ::GetCurrentThreadId(); + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(current_thread); + if (thread_local_pos == thread_to_thread_locals->end()) { + thread_local_pos = thread_to_thread_locals->insert( + std::make_pair(current_thread, ThreadLocalValues())).first; + StartWatcherThreadFor(current_thread); + } + ThreadLocalValues& thread_local_values = thread_local_pos->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos == thread_local_values.end()) { + value_pos = + thread_local_values + .insert(std::make_pair( + thread_local_instance, + std::shared_ptr( + thread_local_instance->NewValueForCurrentThread()))) + .first; + } + return value_pos->second.get(); + } + + static void OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + std::vector > value_holders; + // Clean up the ThreadLocalValues data structure while holding the lock, but + // defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + for (ThreadIdToThreadLocals::iterator it = + thread_to_thread_locals->begin(); + it != thread_to_thread_locals->end(); + ++it) { + ThreadLocalValues& thread_local_values = it->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos != thread_local_values.end()) { + value_holders.push_back(value_pos->second); + thread_local_values.erase(value_pos); + // This 'if' can only be successful at most once, so theoretically we + // could break out of the loop here, but we don't bother doing so. + } + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + static void OnThreadExit(DWORD thread_id) { + GTEST_CHECK_(thread_id != 0) << ::GetLastError(); + std::vector > value_holders; + // Clean up the ThreadIdToThreadLocals data structure while holding the + // lock, but defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(thread_id); + if (thread_local_pos != thread_to_thread_locals->end()) { + ThreadLocalValues& thread_local_values = thread_local_pos->second; + for (ThreadLocalValues::iterator value_pos = + thread_local_values.begin(); + value_pos != thread_local_values.end(); + ++value_pos) { + value_holders.push_back(value_pos->second); + } + thread_to_thread_locals->erase(thread_local_pos); + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + private: + // In a particular thread, maps a ThreadLocal object to its value. + typedef std::map > + ThreadLocalValues; + // Stores all ThreadIdToThreadLocals having values in a thread, indexed by + // thread's ID. + typedef std::map ThreadIdToThreadLocals; + + // Holds the thread id and thread handle that we pass from + // StartWatcherThreadFor to WatcherThreadFunc. + typedef std::pair ThreadIdAndHandle; + + static void StartWatcherThreadFor(DWORD thread_id) { + // The returned handle will be kept in thread_map and closed by + // watcher_thread in WatcherThreadFunc. + HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, + FALSE, + thread_id); + GTEST_CHECK_(thread != nullptr); + // We need to pass a valid thread ID pointer into CreateThread for it + // to work correctly under Win98. + DWORD watcher_thread_id; + HANDLE watcher_thread = ::CreateThread( + nullptr, // Default security. + 0, // Default stack size + &ThreadLocalRegistryImpl::WatcherThreadFunc, + reinterpret_cast(new ThreadIdAndHandle(thread_id, thread)), + CREATE_SUSPENDED, &watcher_thread_id); + GTEST_CHECK_(watcher_thread != nullptr); + // Give the watcher thread the same priority as ours to avoid being + // blocked by it. + ::SetThreadPriority(watcher_thread, + ::GetThreadPriority(::GetCurrentThread())); + ::ResumeThread(watcher_thread); + ::CloseHandle(watcher_thread); + } + + // Monitors exit from a given thread and notifies those + // ThreadIdToThreadLocals about thread termination. + static DWORD WINAPI WatcherThreadFunc(LPVOID param) { + const ThreadIdAndHandle* tah = + reinterpret_cast(param); + GTEST_CHECK_( + ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); + OnThreadExit(tah->first); + ::CloseHandle(tah->second); + delete tah; + return 0; + } + + // Returns map of thread local instances. + static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { + mutex_.AssertHeld(); +#ifdef _MSC_VER + MemoryIsNotDeallocated memory_is_not_deallocated; +#endif // _MSC_VER + static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals(); + return map; + } + + // Protects access to GetThreadLocalsMapLocked() and its return value. + static Mutex mutex_; + // Protects access to GetThreadMapLocked() and its return value. + static Mutex thread_map_mutex_; +}; + +Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); +Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); + +ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + return ThreadLocalRegistryImpl::GetValueOnCurrentThread( + thread_local_instance); +} + +void ThreadLocalRegistry::OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); +} + +#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); +} + +// Returns true if and only if regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true if and only if regular expression re matches a substring of +// str (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true if and only if ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != nullptr; +} + +// Returns true if and only if ch belongs to the given classification. +// Unlike similar functions in , these aren't affected by the +// current locale. +bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsAsciiPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsAsciiWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true if and only if "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true if and only if the given atom (specified by escaped and +// pattern) matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsAsciiDigit(ch); + case 'D': return !IsAsciiDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsAsciiWhiteSpace(ch); + case 'S': return !IsAsciiWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsAsciiWordChar(ch); + case 'W': return !IsAsciiWordChar(ch); + } + return IsAsciiPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +static std::string FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == nullptr) { + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True if and only if ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true if and only if regex matches a prefix of str. regex must +// be a valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true if and only if regex matches any substring of str. regex must +// be a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == nullptr || str == nullptr) return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); +} + +// Returns true if and only if regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true if and only if regular expression re matches a substring of +// str (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = nullptr; + if (regex != nullptr) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const std::string file_name(file == nullptr ? kUnknownFile : file); + + if (line < 0) { + return file_name + ":"; + } +#ifdef _MSC_VER + return file_name + "(" + StreamableToString(line) + "):"; +#else + return file_name + ":" + StreamableToString(line) + ":"; +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const std::string file_name(file == nullptr ? kUnknownFile : file); + + if (line < 0) + return file_name; + else + return file_name + ":" + StreamableToString(line); +} + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} + +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +GTEST_DISABLE_MSC_DEPRECATED_PUSH_() + +#if GTEST_HAS_STREAM_REDIRECTION + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +# if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +# else + // There's no guarantee that a test has write access to the current + // directory, so we create the temporary file in the /tmp directory + // instead. We use /tmp on most systems, and /sdcard on Android. + // That's because Android doesn't have /tmp. +# if GTEST_OS_LINUX_ANDROID + // Note: Android applications are expected to call the framework's + // Context.getExternalStorageDirectory() method through JNI to get + // the location of the world-writable SD Card directory. However, + // this requires a Context handle, which cannot be retrieved + // globally from native code. Doing so also precludes running the + // code as part of a regular standalone executable, which doesn't + // run in a Dalvik process (e.g. when running it through 'adb shell'). + // + // The location /data/local/tmp is directly accessible from native code. + // '/sdcard' and other variants cannot be relied on, as they are not + // guaranteed to be mounted, or may have a delay in mounting. + char name_template[] = "/data/local/tmp/gtest_captured_stream.XXXXXX"; +# else + char name_template[] = "/tmp/captured_stream.XXXXXX"; +# endif // GTEST_OS_LINUX_ANDROID + const int captured_fd = mkstemp(name_template); + if (captured_fd == -1) { + GTEST_LOG_(WARNING) + << "Failed to create tmp file " << name_template + << " for test; does the test have access to the /tmp directory?"; + } + filename_ = name_template; +# endif // GTEST_OS_WINDOWS + fflush(nullptr); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + std::string GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(nullptr); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + if (file == nullptr) { + GTEST_LOG_(FATAL) << "Failed to open tmp file " << filename_ + << " for capturing stream."; + } + const std::string content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +GTEST_DISABLE_MSC_DEPRECATED_POP_() + +static CapturedStream* g_captured_stderr = nullptr; +static CapturedStream* g_captured_stdout = nullptr; + +// Starts capturing an output stream (stdout/stderr). +static void CaptureStream(int fd, const char* stream_name, + CapturedStream** stream) { + if (*stream != nullptr) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +static std::string GetCapturedStream(CapturedStream** captured_stream) { + const std::string content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = nullptr; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +std::string GetCapturedStdout() { + return GetCapturedStream(&g_captured_stdout); +} + +// Stops capturing stderr and returns the captured string. +std::string GetCapturedStderr() { + return GetCapturedStream(&g_captured_stderr); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + + + + + +size_t GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +std::string ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const std::string content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +#if GTEST_HAS_DEATH_TEST +static const std::vector* g_injected_test_argvs = + nullptr; // Owned. + +std::vector GetInjectableArgvs() { + if (g_injected_test_argvs != nullptr) { + return *g_injected_test_argvs; + } + return GetArgvs(); +} + +void SetInjectableArgvs(const std::vector* new_argvs) { + if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs; + g_injected_test_argvs = new_argvs; +} + +void SetInjectableArgvs(const std::vector& new_argvs) { + SetInjectableArgvs( + new std::vector(new_argvs.begin(), new_argvs.end())); +} + +void ClearInjectableArgvs() { + delete g_injected_test_argvs; + g_injected_test_argvs = nullptr; +} +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static std::string FlagToEnvVar(const char* flag) { + const std::string full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << ToUpper(full_flag.c_str()[i]); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = nullptr; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true if and only if it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { +#if defined(GTEST_GET_BOOL_FROM_ENV_) + return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); +#else + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == nullptr ? default_value + : strcmp(string_value, "0") != 0; +#endif // defined(GTEST_GET_BOOL_FROM_ENV_) +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { +#if defined(GTEST_GET_INT32_FROM_ENV_) + return GTEST_GET_INT32_FROM_ENV_(flag, default_value); +#else + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == nullptr) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +#endif // defined(GTEST_GET_INT32_FROM_ENV_) +} + +// As a special case for the 'output' flag, if GTEST_OUTPUT is not +// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build +// system. The value of XML_OUTPUT_FILE is a filename without the +// "xml:" prefix of GTEST_OUTPUT. +// Note that this is meant to be called at the call site so it does +// not check that the flag is 'output' +// In essence this checks an env variable called XML_OUTPUT_FILE +// and if it is set we prepend "xml:" to its value, if it not set we return "" +std::string OutputFlagAlsoCheckEnvVar(){ + std::string default_value_for_output_flag = ""; + const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE"); + if (nullptr != xml_output_file_env) { + default_value_for_output_flag = std::string("xml:") + xml_output_file_env; + } + return default_value_for_output_flag; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { +#if defined(GTEST_GET_STRING_FROM_ENV_) + return GTEST_GET_STRING_FROM_ENV_(flag, default_value); +#else + const std::string env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == nullptr ? default_value : value; +#endif // defined(GTEST_GET_STRING_FROM_ENV_) +} + +} // namespace internal +} // namespace testing diff --git a/3rdparty/gtest/src/gtest-printers.cc b/3rdparty/gtest/src/gtest-printers.cc new file mode 100644 index 0000000..3337be3 --- /dev/null +++ b/3rdparty/gtest/src/gtest-printers.cc @@ -0,0 +1,442 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Test - The Google C++ Testing and Mocking Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// It uses the << operator when possible, and prints the bytes in the +// object otherwise. A user can override its behavior for a class +// type Foo by defining either operator<<(::std::ostream&, const Foo&) +// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that +// defines Foo. + +#include "gtest/gtest-printers.h" +#include +#include +#include +#include // NOLINT +#include +#include "gtest/internal/gtest-port.h" +#include "src/gtest-internal-inl.h" + +namespace testing { + +namespace { + +using ::std::ostream; + +// Prints a segment of bytes in the given object. +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, + size_t count, ostream* os) { + char text[5] = ""; + for (size_t i = 0; i != count; i++) { + const size_t j = start + i; + if (i != 0) { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } +} + +// Prints the bytes in the given value to the given ostream. +void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, + ostream* os) { + // Tells the user how big the object is. + *os << count << "-byte object <"; + + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + if (count < kThreshold) { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } else { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1)/2*2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; +} + +} // namespace + +namespace internal2 { + +// Delegates to PrintBytesInObjectToImpl() to print the bytes in the +// given object. The delegation simplifies the implementation, which +// uses the << operator and thus is easier done outside of the +// ::testing::internal namespace, which contains a << operator that +// sometimes conflicts with the one in STL. +void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, + ostream* os) { + PrintBytesInObjectToImpl(obj_bytes, count, os); +} + +} // namespace internal2 + +namespace internal { + +// Depending on the value of a char (or wchar_t), we print it in one +// of three formats: +// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), +// - as a hexadecimal escape sequence (e.g. '\x7F'), or +// - as a special escape sequence (e.g. '\r', '\n'). +enum CharFormat { + kAsIs, + kHexEscape, + kSpecialEscape +}; + +// Returns true if c is a printable ASCII character. We test the +// value of c directly instead of calling isprint(), which is buggy on +// Windows Mobile. +inline bool IsPrintableAscii(wchar_t c) { + return 0x20 <= c && c <= 0x7E; +} + +// Prints a wide or narrow char c as a character literal without the +// quotes, escaping it when necessary; returns how c was formatted. +// The template argument UnsignedChar is the unsigned version of Char, +// which is the type of c. +template +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { + wchar_t w_c = static_cast(c); + switch (w_c) { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(w_c)) { + *os << static_cast(c); + return kAsIs; + } else { + ostream::fmtflags flags = os->flags(); + *os << "\\x" << std::hex << std::uppercase + << static_cast(static_cast(c)); + os->flags(flags); + return kHexEscape; + } + } + return kSpecialEscape; +} + +// Prints a wchar_t c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { + switch (c) { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo(c, os); + } +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { + return PrintAsStringLiteralTo( + static_cast(static_cast(c)), os); +} + +// Prints a wide or narrow character c and its code. '\0' is printed +// as "'\\0'", other unprintable characters are also properly escaped +// using the standard C++ escape sequence. The template argument +// UnsignedChar is the unsigned version of Char, which is the type of c. +template +void PrintCharAndCodeTo(Char c, ostream* os) { + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo(c, os); + *os << "'"; + + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << static_cast(c); + + // For more convenience, we print c's code again in hexadecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) { + // Do nothing. + } else { + *os << ", 0x" << String::FormatHexInt(static_cast(c)); + } + *os << ")"; +} + +void PrintTo(unsigned char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} +void PrintTo(signed char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} + +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its code. L'\0' is printed as "L'\\0'". +void PrintTo(wchar_t wc, ostream* os) { + PrintCharAndCodeTo(wc, os); +} + +// Prints the given array of characters to the ostream. CharType must be either +// char or wchar_t. +// The array starts at begin, the length is len, it may include '\0' characters +// and may not be NUL-terminated. +template +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +static CharFormat PrintCharsAsStringTo( + const CharType* begin, size_t len, ostream* os) { + const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; + *os << kQuoteBegin; + bool is_previous_hex = false; + CharFormat print_format = kAsIs; + for (size_t index = 0; index < len; ++index) { + const CharType cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" " << kQuoteBegin; + } + is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; + // Remember if any characters required hex escaping. + if (is_previous_hex) { + print_format = kHexEscape; + } + } + *os << "\""; + return print_format; +} + +// Prints a (const) char/wchar_t array of 'len' elements, starting at address +// 'begin'. CharType must be either char or wchar_t. +template +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +static void UniversalPrintCharArray( + const CharType* begin, size_t len, ostream* os) { + // The code + // const char kFoo[] = "foo"; + // generates an array of 4, not 3, elements, with the last one being '\0'. + // + // Therefore when printing a char array, we don't print the last element if + // it's '\0', such that the output matches the string literal as it's + // written in the source code. + if (len > 0 && begin[len - 1] == '\0') { + PrintCharsAsStringTo(begin, len - 1, os); + return; + } + + // If, however, the last element in the array is not '\0', e.g. + // const char kFoo[] = { 'f', 'o', 'o' }; + // we must print the entire array. We also print a message to indicate + // that the array is not NUL-terminated. + PrintCharsAsStringTo(begin, len, os); + *os << " (no terminating NUL)"; +} + +// Prints a (const) char array of 'len' elements, starting at address 'begin'. +void UniversalPrintArray(const char* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints a (const) wchar_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints the given C string to the ostream. +void PrintTo(const char* s, ostream* os) { + if (s == nullptr) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Prints the given wide C string to the ostream. +void PrintTo(const wchar_t* s, ostream* os) { + if (s == nullptr) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, wcslen(s), os); + } +} +#endif // wchar_t is native + +namespace { + +bool ContainsUnprintableControlCodes(const char* str, size_t length) { + const unsigned char *s = reinterpret_cast(str); + + for (size_t i = 0; i < length; i++) { + unsigned char ch = *s++; + if (std::iscntrl(ch)) { + switch (ch) { + case '\t': + case '\n': + case '\r': + break; + default: + return true; + } + } + } + return false; +} + +bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; } + +bool IsValidUTF8(const char* str, size_t length) { + const unsigned char *s = reinterpret_cast(str); + + for (size_t i = 0; i < length;) { + unsigned char lead = s[i++]; + + if (lead <= 0x7f) { + continue; // single-byte character (ASCII) 0..7F + } + if (lead < 0xc2) { + return false; // trail byte or non-shortest form + } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) { + ++i; // 2-byte character + } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length && + IsUTF8TrailByte(s[i]) && + IsUTF8TrailByte(s[i + 1]) && + // check for non-shortest form and surrogate + (lead != 0xe0 || s[i] >= 0xa0) && + (lead != 0xed || s[i] < 0xa0)) { + i += 2; // 3-byte character + } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length && + IsUTF8TrailByte(s[i]) && + IsUTF8TrailByte(s[i + 1]) && + IsUTF8TrailByte(s[i + 2]) && + // check for non-shortest form + (lead != 0xf0 || s[i] >= 0x90) && + (lead != 0xf4 || s[i] < 0x90)) { + i += 3; // 4-byte character + } else { + return false; + } + } + return true; +} + +void ConditionalPrintAsText(const char* str, size_t length, ostream* os) { + if (!ContainsUnprintableControlCodes(str, length) && + IsValidUTF8(str, length)) { + *os << "\n As Text: \"" << str << "\""; + } +} + +} // anonymous namespace + +void PrintStringTo(const ::std::string& s, ostream* os) { + if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) { + if (GTEST_FLAG(print_utf8)) { + ConditionalPrintAsText(s.data(), s.size(), os); + } + } +} + +#if GTEST_HAS_STD_WSTRING +void PrintWideStringTo(const ::std::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_STD_WSTRING + +} // namespace internal + +} // namespace testing diff --git a/3rdparty/gtest/src/gtest-test-part.cc b/3rdparty/gtest/src/gtest-test-part.cc new file mode 100644 index 0000000..178317a --- /dev/null +++ b/3rdparty/gtest/src/gtest-test-part.cc @@ -0,0 +1,104 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// The Google C++ Testing and Mocking Framework (Google Test) + +#include "gtest/gtest-test-part.h" +#include "src/gtest-internal-inl.h" + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +std::string TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == nullptr ? message : std::string(message, stack_trace); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess + ? "Success" + : result.type() == TestPartResult::kSkip + ? "Skipped" + : result.type() == TestPartResult::kFatalFailure + ? "Fatal failure" + : "Non-fatal failure") + << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[static_cast(index)]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing diff --git a/3rdparty/gtest/src/gtest-typed-test.cc b/3rdparty/gtest/src/gtest-typed-test.cc new file mode 100644 index 0000000..8677caf --- /dev/null +++ b/3rdparty/gtest/src/gtest-typed-test.cc @@ -0,0 +1,118 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "gtest/gtest-typed-test.h" + +#include "gtest/gtest.h" + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (IsSpace(*str)) + str++; + return str; +} + +static std::vector SplitIntoTestNames(const char* src) { + std::vector name_vec; + src = SkipSpaces(src); + for (; src != nullptr; src = SkipComma(src)) { + name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); + } + return name_vec; +} + +// Verifies that registered_tests match the test names in +// registered_tests_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestSuitePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef RegisteredTestsMap::const_iterator RegisteredTestIter; + registered_ = true; + + std::vector name_vec = SplitIntoTestNames(registered_tests); + + Message errors; + + std::set tests; + for (std::vector::const_iterator name_it = name_vec.begin(); + name_it != name_vec.end(); ++name_it) { + const std::string& name = *name_it; + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (RegisteredTestIter it = registered_tests_.begin(); + it != registered_tests_.end(); + ++it) { + if (name == it->first) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test suite.\n"; + } + } + + for (RegisteredTestIter it = registered_tests_.begin(); + it != registered_tests_.end(); + ++it) { + if (tests.count(it->first) == 0) { + errors << "You forgot to list test " << it->first << ".\n"; + } + } + + const std::string& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/3rdparty/gtest/src/gtest.cc b/3rdparty/gtest/src/gtest.cc new file mode 100644 index 0000000..a5b4e5a --- /dev/null +++ b/3rdparty/gtest/src/gtest.cc @@ -0,0 +1,6177 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// The Google C++ Testing and Mocking Framework (Google Test) + +#include "gtest/gtest.h" +#include "gtest/internal/custom/gtest.h" +#include "gtest/gtest-spi.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include // NOLINT +#include +#include + +#if GTEST_OS_LINUX + +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +# include // NOLINT +# include // NOLINT +# include // NOLINT +// Declares vsnprintf(). This header is not available on Windows. +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include + +#elif GTEST_OS_ZOS +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +# include // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +# include // NOLINT +# undef min + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +# include // NOLINT +# undef min + +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT + +# if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT +# endif // GTEST_OS_WINDOWS_MINGW + +#else + +// Assume other platforms have gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT +# include // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +#endif + +#include "src/gtest-internal-inl.h" + +#if GTEST_OS_WINDOWS +# define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +#if GTEST_OS_MAC +#ifndef GTEST_OS_IOS +#include +#endif +#endif + +#if GTEST_HAS_ABSL +#include "absl/debugging/failure_signal_handler.h" +#include "absl/debugging/stacktrace.h" +#include "absl/debugging/symbolize.h" +#include "absl/strings/str_cat.h" +#endif // GTEST_HAS_ABSL + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test suite name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test suite whose name matches this filter is considered a death +// test suite and will be run before test suites whose name doesn't +// match this filter. +static const char kDeathTestSuiteFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output format. +static const char kDefaultOutputFormat[] = "xml"; +// The default output file. +static const char kDefaultOutputFile[] = "test_detail"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true if and only if the --help flag or an equivalent form +// is specified on the command line. +bool g_help_flag = false; + +// Utilty function to Open File for Writing +static FILE* OpenFileForWriting(const std::string& output_file) { + FILE* fileout = nullptr; + FilePath output_file_path(output_file); + FilePath output_dir(output_file_path.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + fileout = posix::FOpen(output_file.c_str(), "w"); + } + if (fileout == nullptr) { + GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file << "\""; + } + return fileout; +} + +} // namespace internal + +// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY +// environment variable. +static const char* GetDefaultFilter() { + const char* const testbridge_test_only = + internal::posix::GetEnv("TESTBRIDGE_TEST_ONLY"); + if (testbridge_test_only != nullptr) { + return testbridge_test_only; + } + return kUniversalFilter; +} + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), + "True if and only if a failed assertion should be a debugger " + "break-point."); + +GTEST_DEFINE_bool_(catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", true), + "True if and only if " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to a terminal type that supports colors."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", GetDefaultFilter()), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_( + install_failure_signal_handler, + internal::BoolFromGTestEnv("install_failure_signal_handler", false), + "If true and supported on the current platform, " GTEST_NAME_ " should " + "install a signal handler that dumps debugging information when fatal " + "signals are raised."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +// The net priority order after flag processing is thus: +// --gtest_output command line flag +// GTEST_OUTPUT environment variable +// XML_OUTPUT_FILE environment variable +// '' +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", + internal::OutputFlagAlsoCheckEnvVar().c_str()), + "A format (defaults to \"xml\" but can be specified to be \"json\"), " + "optionally followed by a colon and an output file name or directory. " + "A directory is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_(print_time, internal::BoolFromGTestEnv("print_time", true), + "True if and only if " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_bool_(print_utf8, internal::BoolFromGTestEnv("print_utf8", true), + "True if and only if " GTEST_NAME_ + " prints UTF8 characters as text."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_(show_internal_stack_frames, false, + "True if and only if " GTEST_NAME_ + " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_(shuffle, internal::BoolFromGTestEnv("shuffle", false), + "True if and only if " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_string_( + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise. For use with an external test framework."); + +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +GTEST_DEFINE_string_( + flagfile, + internal::StringFromGTestEnv("flagfile", ""), + "This flag specifies the flagfile to read command-line flags from."); +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + // Use wider types than necessary to prevent unsigned overflow diagnostics. + state_ = static_cast(1103515245ULL*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true if and only if the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +static bool GTestIsInitialized() { return GetArgvs().size() > 0; } + +// Iterates over a vector of TestSuites, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestSuiteList(const std::vector& case_list, + int (TestSuite::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true if and only if the test suite passed. +static bool TestSuitePassed(const TestSuite* test_suite) { + return test_suite->should_run() && test_suite->Passed(); +} + +// Returns true if and only if the test suite failed. +static bool TestSuiteFailed(const TestSuite* test_suite) { + return test_suite->should_run() && test_suite->Failed(); +} + +// Returns true if and only if test_suite contains at least one test that +// should run. +static bool ShouldRunTestSuite(const TestSuite* test_suite) { + return test_suite->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// A copy of all command line arguments. Set by InitGoogleTest(). +static ::std::vector g_argvs; + +::std::vector GetArgvs() { +#if defined(GTEST_CUSTOM_GET_ARGVS_) + // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or + // ::string. This code converts it to the appropriate type. + const auto& custom = GTEST_CUSTOM_GET_ARGVS_(); + return ::std::vector(custom.begin(), custom.end()); +#else // defined(GTEST_CUSTOM_GET_ARGVS_) + return g_argvs; +#endif // defined(GTEST_CUSTOM_GET_ARGVS_) +} + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS || GTEST_OS_OS2 + result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe")); +#else + result.Set(FilePath(GetArgvs()[0])); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +std::string UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == nullptr) + ? std::string(gtest_output_flag) + : std::string(gtest_output_flag, + static_cast(colon - gtest_output_flag)); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +std::string UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + + std::string format = GetOutputFormat(); + if (format.empty()) + format = std::string(kDefaultOutputFormat); + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == nullptr) + return internal::FilePath::MakeFileName( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile), 0, + format.c_str()).string(); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.string(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.string(); +} + +// Returns true if and only if the wildcard pattern matches the string. +// The first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter( + const std::string& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == nullptr) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// Returns true if and only if the user-specified filter matches the test +// suite name and the test name. +bool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name, + const std::string& test_name) { + const std::string& full_name = test_suite_name + "." + test_name.c_str(); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + std::string positive; + std::string negative; + if (dash == nullptr) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = ""; + } else { + positive = std::string(p, dash); // Everything up to the dash + negative = std::string(dash + 1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_HAS_SEH +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle a SEH exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; + + bool should_handle = true; + + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; + + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_HAS_SEH + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +static AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const std::string& substr) { + const std::string expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure() << msg; + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + } + + if (strstr(r.message(), substr.c_str()) == nullptr) { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker::SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const std::string& substr) + : results_(results), type_(type), substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test suites. +int UnitTestImpl::successful_test_suite_count() const { + return CountIf(test_suites_, TestSuitePassed); +} + +// Gets the number of failed test suites. +int UnitTestImpl::failed_test_suite_count() const { + return CountIf(test_suites_, TestSuiteFailed); +} + +// Gets the number of all test suites. +int UnitTestImpl::total_test_suite_count() const { + return static_cast(test_suites_.size()); +} + +// Gets the number of all test suites that contain at least one test +// that should run. +int UnitTestImpl::test_suite_to_run_count() const { + return CountIf(test_suites_, ShouldRunTestSuite); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestSuiteList(test_suites_, &TestSuite::successful_test_count); +} + +// Gets the number of skipped tests. +int UnitTestImpl::skipped_test_count() const { + return SumOverTestSuiteList(test_suites_, &TestSuite::skipped_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestSuiteList(test_suites_, &TestSuite::failed_test_count); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTestImpl::reportable_disabled_test_count() const { + return SumOverTestSuiteList(test_suites_, + &TestSuite::reportable_disabled_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestSuiteList(test_suites_, &TestSuite::disabled_test_count); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTestImpl::reportable_test_count() const { + return SumOverTestSuiteList(test_suites_, &TestSuite::reportable_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestSuiteList(test_suites_, &TestSuite::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestSuiteList(test_suites_, &TestSuite::test_to_run_count); +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + return os_stack_trace_getter()->CurrentStackTrace( + static_cast(GTEST_FLAG(stack_trace_depth)), + skip_count + 1 + // Skips the user-specified number of frames plus this function + // itself. + ); // NOLINT +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; + + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + GTEST_DISABLE_MSC_DEPRECATED_PUSH_() + _ftime64(&now); + GTEST_DISABLE_MSC_DEPRECATED_POP_() + + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, nullptr); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +# error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String. + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return nullptr; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, nullptr, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return nullptr; + const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, nullptr, + 0, nullptr, nullptr); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, nullptr, + nullptr); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true if and only if they have the same +// content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if (lhs == nullptr) return rhs == nullptr; + + if (rhs == nullptr) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING + +void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +} // namespace internal + +// Constructs an empty Message. +// We allocate the stringstream separately because otherwise each use of +// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's +// stack frame leading to huge stack frames in some cases; gcc does not reuse +// the stack space. +Message::Message() : ss_(new ::std::stringstream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); +} + +// These two overloads allow streaming a wide C string to a Message +// using the UTF-8 encoding. +Message& Message::operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} +Message& Message::operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +// Gets the text streamed to this object so far as an std::string. +// Each '\0' character in the buffer is replaced with "\\0". +std::string Message::GetString() const { + return internal::StringStreamToString(ss_.get()); +} + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != nullptr + ? new ::std::string(*other.message_) + : static_cast< ::std::string*>(nullptr)) {} + +// Swaps two AssertionResults. +void AssertionResult::swap(AssertionResult& other) { + using std::swap; + swap(success_, other.success_); + swap(message_, other.message_); +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != nullptr) negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +namespace edit_distance { +std::vector CalculateOptimalEdits(const std::vector& left, + const std::vector& right) { + std::vector > costs( + left.size() + 1, std::vector(right.size() + 1)); + std::vector > best_move( + left.size() + 1, std::vector(right.size() + 1)); + + // Populate for empty right. + for (size_t l_i = 0; l_i < costs.size(); ++l_i) { + costs[l_i][0] = static_cast(l_i); + best_move[l_i][0] = kRemove; + } + // Populate for empty left. + for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) { + costs[0][r_i] = static_cast(r_i); + best_move[0][r_i] = kAdd; + } + + for (size_t l_i = 0; l_i < left.size(); ++l_i) { + for (size_t r_i = 0; r_i < right.size(); ++r_i) { + if (left[l_i] == right[r_i]) { + // Found a match. Consume it. + costs[l_i + 1][r_i + 1] = costs[l_i][r_i]; + best_move[l_i + 1][r_i + 1] = kMatch; + continue; + } + + const double add = costs[l_i + 1][r_i]; + const double remove = costs[l_i][r_i + 1]; + const double replace = costs[l_i][r_i]; + if (add < remove && add < replace) { + costs[l_i + 1][r_i + 1] = add + 1; + best_move[l_i + 1][r_i + 1] = kAdd; + } else if (remove < add && remove < replace) { + costs[l_i + 1][r_i + 1] = remove + 1; + best_move[l_i + 1][r_i + 1] = kRemove; + } else { + // We make replace a little more expensive than add/remove to lower + // their priority. + costs[l_i + 1][r_i + 1] = replace + 1.00001; + best_move[l_i + 1][r_i + 1] = kReplace; + } + } + } + + // Reconstruct the best path. We do it in reverse order. + std::vector best_path; + for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) { + EditType move = best_move[l_i][r_i]; + best_path.push_back(move); + l_i -= move != kAdd; + r_i -= move != kRemove; + } + std::reverse(best_path.begin(), best_path.end()); + return best_path; +} + +namespace { + +// Helper class to convert string into ids with deduplication. +class InternalStrings { + public: + size_t GetId(const std::string& str) { + IdMap::iterator it = ids_.find(str); + if (it != ids_.end()) return it->second; + size_t id = ids_.size(); + return ids_[str] = id; + } + + private: + typedef std::map IdMap; + IdMap ids_; +}; + +} // namespace + +std::vector CalculateOptimalEdits( + const std::vector& left, + const std::vector& right) { + std::vector left_ids, right_ids; + { + InternalStrings intern_table; + for (size_t i = 0; i < left.size(); ++i) { + left_ids.push_back(intern_table.GetId(left[i])); + } + for (size_t i = 0; i < right.size(); ++i) { + right_ids.push_back(intern_table.GetId(right[i])); + } + } + return CalculateOptimalEdits(left_ids, right_ids); +} + +namespace { + +// Helper class that holds the state for one hunk and prints it out to the +// stream. +// It reorders adds/removes when possible to group all removes before all +// adds. It also adds the hunk header before printint into the stream. +class Hunk { + public: + Hunk(size_t left_start, size_t right_start) + : left_start_(left_start), + right_start_(right_start), + adds_(), + removes_(), + common_() {} + + void PushLine(char edit, const char* line) { + switch (edit) { + case ' ': + ++common_; + FlushEdits(); + hunk_.push_back(std::make_pair(' ', line)); + break; + case '-': + ++removes_; + hunk_removes_.push_back(std::make_pair('-', line)); + break; + case '+': + ++adds_; + hunk_adds_.push_back(std::make_pair('+', line)); + break; + } + } + + void PrintTo(std::ostream* os) { + PrintHeader(os); + FlushEdits(); + for (std::list >::const_iterator it = + hunk_.begin(); + it != hunk_.end(); ++it) { + *os << it->first << it->second << "\n"; + } + } + + bool has_edits() const { return adds_ || removes_; } + + private: + void FlushEdits() { + hunk_.splice(hunk_.end(), hunk_removes_); + hunk_.splice(hunk_.end(), hunk_adds_); + } + + // Print a unified diff header for one hunk. + // The format is + // "@@ -, +, @@" + // where the left/right parts are omitted if unnecessary. + void PrintHeader(std::ostream* ss) const { + *ss << "@@ "; + if (removes_) { + *ss << "-" << left_start_ << "," << (removes_ + common_); + } + if (removes_ && adds_) { + *ss << " "; + } + if (adds_) { + *ss << "+" << right_start_ << "," << (adds_ + common_); + } + *ss << " @@\n"; + } + + size_t left_start_, right_start_; + size_t adds_, removes_, common_; + std::list > hunk_, hunk_adds_, hunk_removes_; +}; + +} // namespace + +// Create a list of diff hunks in Unified diff format. +// Each hunk has a header generated by PrintHeader above plus a body with +// lines prefixed with ' ' for no change, '-' for deletion and '+' for +// addition. +// 'context' represents the desired unchanged prefix/suffix around the diff. +// If two hunks are close enough that their contexts overlap, then they are +// joined into one hunk. +std::string CreateUnifiedDiff(const std::vector& left, + const std::vector& right, + size_t context) { + const std::vector edits = CalculateOptimalEdits(left, right); + + size_t l_i = 0, r_i = 0, edit_i = 0; + std::stringstream ss; + while (edit_i < edits.size()) { + // Find first edit. + while (edit_i < edits.size() && edits[edit_i] == kMatch) { + ++l_i; + ++r_i; + ++edit_i; + } + + // Find the first line to include in the hunk. + const size_t prefix_context = std::min(l_i, context); + Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1); + for (size_t i = prefix_context; i > 0; --i) { + hunk.PushLine(' ', left[l_i - i].c_str()); + } + + // Iterate the edits until we found enough suffix for the hunk or the input + // is over. + size_t n_suffix = 0; + for (; edit_i < edits.size(); ++edit_i) { + if (n_suffix >= context) { + // Continue only if the next hunk is very close. + auto it = edits.begin() + static_cast(edit_i); + while (it != edits.end() && *it == kMatch) ++it; + if (it == edits.end() || + static_cast(it - edits.begin()) - edit_i >= context) { + // There is no next edit or it is too far away. + break; + } + } + + EditType edit = edits[edit_i]; + // Reset count when a non match is found. + n_suffix = edit == kMatch ? n_suffix + 1 : 0; + + if (edit == kMatch || edit == kRemove || edit == kReplace) { + hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str()); + } + if (edit == kAdd || edit == kReplace) { + hunk.PushLine('+', right[r_i].c_str()); + } + + // Advance indices, depending on edit type. + l_i += edit != kAdd; + r_i += edit != kRemove; + } + + if (!hunk.has_edits()) { + // We are done. We don't want this hunk. + break; + } + + hunk.PrintTo(&ss); + } + return ss.str(); +} + +} // namespace edit_distance + +namespace { + +// The string representation of the values received in EqFailure() are already +// escaped. Split them on escaped '\n' boundaries. Leave all other escaped +// characters the same. +std::vector SplitEscapedString(const std::string& str) { + std::vector lines; + size_t start = 0, end = str.size(); + if (end > 2 && str[0] == '"' && str[end - 1] == '"') { + ++start; + --end; + } + bool escaped = false; + for (size_t i = start; i + 1 < end; ++i) { + if (escaped) { + escaped = false; + if (str[i] == 'n') { + lines.push_back(str.substr(start, i - start - 1)); + start = i + 1; + } + } else { + escaped = str[i] == '\\'; + } + } + lines.push_back(str.substr(start, end - start)); + return lines; +} + +} // namespace + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// lhs_expression: "foo" +// rhs_expression: "bar" +// lhs_value: "5" +// rhs_value: "6" +// +// The ignoring_case parameter is true if and only if the assertion is a +// *_STRCASEEQ*. When it's true, the string "Ignoring case" will +// be inserted into the message. +AssertionResult EqFailure(const char* lhs_expression, + const char* rhs_expression, + const std::string& lhs_value, + const std::string& rhs_value, + bool ignoring_case) { + Message msg; + msg << "Expected equality of these values:"; + msg << "\n " << lhs_expression; + if (lhs_value != lhs_expression) { + msg << "\n Which is: " << lhs_value; + } + msg << "\n " << rhs_expression; + if (rhs_value != rhs_expression) { + msg << "\n Which is: " << rhs_value; + } + + if (ignoring_case) { + msg << "\nIgnoring case"; + } + + if (!lhs_value.empty() && !rhs_value.empty()) { + const std::vector lhs_lines = + SplitEscapedString(lhs_value); + const std::vector rhs_lines = + SplitEscapedString(rhs_value); + if (lhs_lines.size() > 1 || rhs_lines.size() > 1) { + msg << "\nWith diff:\n" + << edit_distance::CreateUnifiedDiff(lhs_lines, rhs_lines); + } + } + + return AssertionFailure() << msg; +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + ::std::stringstream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; + + ::std::stringstream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; + + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* lhs_expression, + const char* rhs_expression, + BiggestInt lhs, + BiggestInt rhs) { + if (lhs == rhs) { + return AssertionSuccess(); + } + + return EqFailure(lhs_expression, + rhs_expression, + FormatForComparisonFailureMessage(lhs, rhs), + FormatForComparisonFailureMessage(rhs, lhs), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* lhs_expression, + const char* rhs_expression, + const char* lhs, + const char* rhs) { + if (String::CStringEquals(lhs, rhs)) { + return AssertionSuccess(); + } + + return EqFailure(lhs_expression, + rhs_expression, + PrintToString(lhs), + PrintToString(rhs), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression, + const char* rhs_expression, + const char* lhs, + const char* rhs) { + if (String::CaseInsensitiveCStringEquals(lhs, rhs)) { + return AssertionSuccess(); + } + + return EqFailure(lhs_expression, + rhs_expression, + PrintToString(lhs), + PrintToString(rhs), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true if and only if needle +// is a substring of haystack. NULL is considered a substring of +// itself only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == nullptr || haystack == nullptr) return needle == haystack; + + return strstr(haystack, needle) != nullptr; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == nullptr || haystack == nullptr) return needle == haystack; + + return wcsstr(haystack, needle) != nullptr; +} + +// StringType here can be either ::std::string or ::std::wstring. +template +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE + + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; + +# else + + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + static_cast(hr), // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + nullptr); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing CR-LF) + for (; message_length && IsSpace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } + +# endif // GTEST_OS_WINDOWS_MOBILE + + const std::string error_hex("0x" + String::FormatHexInt(hr)); + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << " " << error_text << "\n"; +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +std::string CodePointToUtf8(UInt32 code_point) { + if (code_point > kMaxCodePoint4) { + return "(Invalid Unicode 0x" + String::FormatHexUInt32(code_point) + ")"; + } + + char str[5]; // Big enough for the largest valid code point. + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } else { // code_point <= kMaxCodePoint4 + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } + return str; +} + +// The following two functions only make sense if the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const auto first_u = static_cast(first); + const auto second_u = static_cast(second); + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) + ? (((first_u & mask) << 10) | (second_u & mask)) + 0x10000 + : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + first_u; +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +std::string WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); + + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast(str[i]); + } + + stream << CodePointToUtf8(unicode_code_point); + } + return StringStreamToString(&stream); +} + +// Converts a wide C string to an std::string using the UTF-8 encoding. +// NULL will be converted to "(null)". +std::string String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == nullptr) return "(null)"; + + return internal::WideStringToUtf8(wide_c_str, -1); +} + +// Compares two wide C strings. Returns true if and only if they have the +// same content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == nullptr) return rhs == nullptr; + + if (rhs == nullptr) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* lhs_expression, + const char* rhs_expression, + const wchar_t* lhs, + const wchar_t* rhs) { + if (String::WideCStringEquals(lhs, rhs)) { + return AssertionSuccess(); + } + + return EqFailure(lhs_expression, + rhs_expression, + PrintToString(lhs), + PrintToString(rhs), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << PrintToString(s1) + << " vs " << PrintToString(s2); +} + +// Compares two C strings, ignoring case. Returns true if and only if they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == nullptr) return rhs == nullptr; + if (rhs == nullptr) return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + +// Compares two wide C strings, ignoring case. Returns true if and only if they +// have the same content. +// +// Unlike wcscasecmp(), this function can handle NULL argument(s). +// A NULL C string is considered different to any non-NULL wide C string, +// including the empty string. +// NB: The implementations on different platforms slightly differ. +// On windows, this method uses _wcsicmp which compares according to LC_CTYPE +// environment variable. On GNU platform this method uses wcscasecmp +// which compares according to LC_CTYPE category of the current locale. +// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the +// current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if (lhs == nullptr) return rhs == nullptr; + + if (rhs == nullptr) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID + return wcscasecmp(lhs, rhs) == 0; +#else + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. + wint_t left, right; + do { + left = towlower(static_cast(*lhs++)); + right = towlower(static_cast(*rhs++)); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Returns true if and only if str ends with the given suffix, ignoring case. +// Any string is considered to end with an empty suffix. +bool String::EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix) { + const size_t str_len = str.length(); + const size_t suffix_len = suffix.length(); + return (str_len >= suffix_len) && + CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, + suffix.c_str()); +} + +// Formats an int value as "%02d". +std::string String::FormatIntWidth2(int value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << value; + return ss.str(); +} + +// Formats an int value as "%X". +std::string String::FormatHexUInt32(UInt32 value) { + std::stringstream ss; + ss << std::hex << std::uppercase << value; + return ss.str(); +} + +// Formats an int value as "%X". +std::string String::FormatHexInt(int value) { + return FormatHexUInt32(static_cast(value)); +} + +// Formats a byte as "%02X". +std::string String::FormatByte(unsigned char value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase + << static_cast(value); + return ss.str(); +} + +// Converts the buffer in a stringstream to an std::string, converting NUL +// bytes to "\\0" along the way. +std::string StringStreamToString(::std::stringstream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + std::string result; + result.reserve(static_cast(2 * (end - start))); + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + result += "\\0"; // Replaces NUL with "\\0"; + } else { + result += *ch; + } + } + + return result; +} + +// Appends the user-supplied message to the Google-Test-generated message. +std::string AppendUserMessage(const std::string& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const std::string user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + return gtest_msg + "\n" + user_msg_string; +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(static_cast(i)); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(static_cast(i)); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const std::string& xml_element, + const TestProperty& test_property) { + if (!ValidateTestProperty(xml_element, test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuitesAttributes[] = { + "disabled", + "errors", + "failures", + "name", + "random_seed", + "tests", + "time", + "timestamp" +}; + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuiteAttributes[] = { + "disabled", "errors", "failures", "name", "tests", "time", "timestamp"}; + +// The list of reserved attributes used in the element of XML output. +static const char* const kReservedTestCaseAttributes[] = { + "classname", "name", "status", "time", "type_param", + "value_param", "file", "line"}; + +// Use a slightly different set for allowed output to ensure existing tests can +// still RecordProperty("result") or "RecordProperty(timestamp") +static const char* const kReservedOutputTestCaseAttributes[] = { + "classname", "name", "status", "time", "type_param", + "value_param", "file", "line", "result", "timestamp"}; + +template +std::vector ArrayAsVector(const char* const (&array)[kSize]) { + return std::vector(array, array + kSize); +} + +static std::vector GetReservedAttributesForElement( + const std::string& xml_element) { + if (xml_element == "testsuites") { + return ArrayAsVector(kReservedTestSuitesAttributes); + } else if (xml_element == "testsuite") { + return ArrayAsVector(kReservedTestSuiteAttributes); + } else if (xml_element == "testcase") { + return ArrayAsVector(kReservedTestCaseAttributes); + } else { + GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; + } + // This code is unreachable but some compilers may not realizes that. + return std::vector(); +} + +// TODO(jdesprez): Merge the two getReserved attributes once skip is improved +static std::vector GetReservedOutputAttributesForElement( + const std::string& xml_element) { + if (xml_element == "testsuites") { + return ArrayAsVector(kReservedTestSuitesAttributes); + } else if (xml_element == "testsuite") { + return ArrayAsVector(kReservedTestSuiteAttributes); + } else if (xml_element == "testcase") { + return ArrayAsVector(kReservedOutputTestCaseAttributes); + } else { + GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; + } + // This code is unreachable but some compilers may not realizes that. + return std::vector(); +} + +static std::string FormatWordList(const std::vector& words) { + Message word_list; + for (size_t i = 0; i < words.size(); ++i) { + if (i > 0 && words.size() > 2) { + word_list << ", "; + } + if (i == words.size() - 1) { + word_list << "and "; + } + word_list << "'" << words[i] << "'"; + } + return word_list.GetString(); +} + +static bool ValidateTestPropertyName( + const std::string& property_name, + const std::vector& reserved_names) { + if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != + reserved_names.end()) { + ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name + << " (" << FormatWordList(reserved_names) + << " are reserved by " << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Adds a failure if the key is a reserved attribute of the element named +// xml_element. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const std::string& xml_element, + const TestProperty& test_property) { + return ValidateTestPropertyName(test_property.key(), + GetReservedAttributesForElement(xml_element)); +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true off the test part was skipped. +static bool TestPartSkipped(const TestPartResult& result) { + return result.skipped(); +} + +// Returns true if and only if the test was skipped. +bool TestResult::Skipped() const { + return !Failed() && CountIf(test_part_results_, TestPartSkipped) > 0; +} + +// Returns true if and only if the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true if and only if the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true if and only if the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true if and only if the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true if and only if the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the states of all flags. +Test::Test() + : gtest_flag_saver_(new GTEST_FLAG_SAVER_) { +} + +// The d'tor restores the states of all flags. The actual work is +// done by the d'tor of the gtest_flag_saver_ field, and thus not +// visible here. +Test::~Test() { +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, const std::string& value) { + UnitTest::GetInstance()->RecordProperty(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + nullptr, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + ""); // No stack trace, either. +} + +} // namespace internal + +// Google Test requires all tests in the same test suite to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test suite. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestSuite* const test_suite = impl->current_test_suite(); + + // Info about the first test in the current test suite. + const TestInfo* const first_test_info = test_suite->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // Both TEST and TEST_F appear in same test suite, which is incorrect. + // Tell the user how to fix this. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test suite must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test suite is\n" + << "illegal. In test suite " << this_test_info->test_suite_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // Two fixture classes with the same name appear in two different + // namespaces, which is not allowed. Tell the user how to fix this. + ADD_FAILURE() + << "All tests in the same test suite must use the same test fixture\n" + << "class. However, in test suite " + << this_test_info->test_suite_name() << ",\n" + << "you defined test " << first_test_name << " and test " + << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test suites."; + } + return false; + } + + return true; +} + +#if GTEST_HAS_SEH + +// Adds an "exception thrown" fatal failure to the current test. This +// function returns its result via an output parameter pointer because VC++ +// prohibits creation of objects with destructors on stack in functions +// using __try (see error C2712). +static std::string* FormatSehExceptionMessage(DWORD exception_code, + const char* location) { + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " thrown in " << location << "."; + + return new std::string(message.GetString()); +} + +#endif // GTEST_HAS_SEH + +namespace internal { + +#if GTEST_HAS_EXCEPTIONS + +// Adds an "exception thrown" fatal failure to the current test. +static std::string FormatCxxExceptionMessage(const char* description, + const char* location) { + Message message; + if (description != nullptr) { + message << "C++ exception with description \"" << description << "\""; + } else { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; + + return message.GetString(); +} + +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result); + +GoogleTestFailureException::GoogleTestFailureException( + const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} + +#endif // GTEST_HAS_EXCEPTIONS + +// We put these helper functions in the internal namespace as IBM's xlC +// compiler rejects the code if they were declared static. + +// Runs the given method and handles SEH exceptions it throws, when +// SEH is supported; returns the 0-value for type Result in case of an +// SEH exception. (Microsoft compilers cannot handle SEH and C++ +// exceptions in the same function. Therefore, we provide a separate +// wrapper function for handling SEH exceptions.) +template +Result HandleSehExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { +#if GTEST_HAS_SEH + __try { + return (object->*method)(); + } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + std::string* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast(0); + } +#else + (void)location; + return (object->*method)(); +#endif // GTEST_HAS_SEH +} + +// Runs the given method and catches and reports C++ and/or SEH-style +// exceptions, if they are supported; returns the 0-value for type +// Result in case of an SEH exception. +template +Result HandleExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) { +#if GTEST_HAS_EXCEPTIONS + try { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const AssertionException&) { // NOLINT + // This failure was reported already. + } catch (const internal::GoogleTestFailureException&) { // NOLINT + // This exception type can only be thrown by a failed Google + // Test assertion with the intention of letting another testing + // framework catch it. Therefore we just re-throw it. + throw; + } catch (const std::exception& e) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } catch (...) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(nullptr, location)); + } + return static_cast(0); +#else + return HandleSehExceptionsInMethodIfSupported(object, method, location); +#endif // GTEST_HAS_EXCEPTIONS + } else { + return (object->*method)(); + } +} + +} // namespace internal + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); + // We will run the test only if SetUp() was successful and didn't call + // GTEST_SKIP(). + if (!HasFatalFailure() && !IsSkipped()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); +} + +// Returns true if and only if the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true if and only if the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// Returns true if and only if the current test was skipped. +bool Test::IsSkipped() { + return internal::GetUnitTestImpl()->current_test_result()->Skipped(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object. +TestInfo::TestInfo(const std::string& a_test_suite_name, + const std::string& a_name, const char* a_type_param, + const char* a_value_param, + internal::CodeLocation a_code_location, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) + : test_suite_name_(a_test_suite_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : nullptr), + value_param_(a_value_param ? new std::string(a_value_param) : nullptr), + location_(a_code_location), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { delete factory_; } + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_suite_name: name of the test suite +// name: name of the test +// type_param: the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param: text representation of the test's value parameter, +// or NULL if this is not a value-parameterized test. +// code_location: code location where the test is defined +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test suite +// tear_down_tc: pointer to the function that tears down the test suite +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_suite_name, const char* name, const char* type_param, + const char* value_param, CodeLocation code_location, + TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc, + TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_suite_name, name, type_param, value_param, + code_location, fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +void ReportInvalidTestSuiteType(const char* test_suite_name, + CodeLocation code_location) { + Message errors; + errors + << "Attempted redefinition of test suite " << test_suite_name << ".\n" + << "All tests in the same test suite must use the same test fixture\n" + << "class. However, in test suite " << test_suite_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test suites."; + + GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(), + code_location.line) + << " " << errors.GetString(); +} +} // namespace internal + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestSuite class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true if and only if the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && test_info->name() == name_; + } + + private: + std::string name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +} + +} // namespace internal + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfo::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); + + const TimeInMillis start = internal::GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); + + // Creates the test object. + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); + + // Runs the test if the constructor didn't generate a fatal failure or invoke + // GTEST_SKIP(). + // Note that the object will not be null + if (!Test::HasFatalFailure() && !Test::IsSkipped()) { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. + test->Run(); + } + + if (test != nullptr) { + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); + } + + result_.set_start_timestamp(start); + result_.set_elapsed_time(internal::GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(nullptr); +} + +// class TestSuite + +// Gets the number of successful tests in this test suite. +int TestSuite::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of successful tests in this test suite. +int TestSuite::skipped_test_count() const { + return CountIf(test_info_list_, TestSkipped); +} + +// Gets the number of failed tests in this test suite. +int TestSuite::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int TestSuite::reportable_disabled_test_count() const { + return CountIf(test_info_list_, TestReportableDisabled); +} + +// Gets the number of disabled tests in this test suite. +int TestSuite::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Gets the number of tests to be printed in the XML report. +int TestSuite::reportable_test_count() const { + return CountIf(test_info_list_, TestReportable); +} + +// Get the number of tests in this test suite that should run. +int TestSuite::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestSuite::total_test_count() const { + return static_cast(test_info_list_.size()); +} + +// Creates a TestSuite with the given name. +// +// Arguments: +// +// name: name of the test suite +// a_type_param: the name of the test suite's type parameter, or NULL if +// this is not a typed or a type-parameterized test suite. +// set_up_tc: pointer to the function that sets up the test suite +// tear_down_tc: pointer to the function that tears down the test suite +TestSuite::TestSuite(const char* a_name, const char* a_type_param, + internal::SetUpTestSuiteFunc set_up_tc, + internal::TearDownTestSuiteFunc tear_down_tc) + : name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : nullptr), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + start_timestamp_(0), + elapsed_time_(0) {} + +// Destructor of TestSuite. +TestSuite::~TestSuite() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestSuite::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? nullptr : test_info_list_[static_cast(index)]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestSuite::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? nullptr : test_info_list_[static_cast(index)]; +} + +// Adds a test to this test suite. Will delete the test upon +// destruction of the TestSuite object. +void TestSuite::AddTestInfo(TestInfo* test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); +} + +// Runs every test in this TestSuite. +void TestSuite::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_suite(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Call both legacy and the new API + repeater->OnTestSuiteStart(*this); +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI + repeater->OnTestCaseStart(*this); +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI + + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()"); + + start_timestamp_ = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start_timestamp_; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()"); + + // Call both legacy and the new API + repeater->OnTestSuiteEnd(*this); +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI + repeater->OnTestCaseEnd(*this); +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI + + impl->set_current_test_suite(nullptr); +} + +// Clears the results of all tests in this test suite. +void TestSuite::ClearResult() { + ad_hoc_test_result_.Clear(); + ForEach(test_info_list_, TestInfo::ClearTestResult); +} + +// Shuffles the tests in this test suite. +void TestSuite::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestSuite::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static std::string FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::StreamableToString(count) + " " + + (count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static std::string FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test suites. +static std::string FormatTestSuiteCount(int test_suite_count) { + return FormatCountableNoun(test_suite_count, "test suite", "test suites"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSkip: + return "Skipped"; + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + default: + return "Unknown result type"; + } +} + +namespace internal { + +// Prints a TestPartResult to an std::string. +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const std::string& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW + +// Returns the character attribute for the given color. +static WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +static int GetBitOffset(WORD color_mask) { + if (color_mask == 0) return 0; + + int bitOffset = 0; + while ((color_mask & 1) == 0) { + color_mask >>= 1; + ++bitOffset; + } + return bitOffset; +} + +static WORD GetNewColor(GTestColor color, WORD old_color_attrs) { + // Let's reuse the BG + static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | + BACKGROUND_RED | BACKGROUND_INTENSITY; + static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | + FOREGROUND_RED | FOREGROUND_INTENSITY; + const WORD existing_bg = old_color_attrs & background_mask; + + WORD new_color = + GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY; + static const int bg_bitOffset = GetBitOffset(background_mask); + static const int fg_bitOffset = GetBitOffset(foreground_mask); + + if (((new_color & background_mask) >> bg_bitOffset) == + ((new_color & foreground_mask) >> fg_bitOffset)) { + new_color ^= FOREGROUND_INTENSITY; // invert intensity + } + return new_color; +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +static const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: + return nullptr; + } +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true if and only if Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "screen-256color") || + String::CStringEquals(term, "tmux") || + String::CStringEquals(term, "tmux-256color") || + String::CStringEquals(term, "rxvt-unicode") || + String::CStringEquals(term, "rxvt-unicode-256color") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \ + GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM) + const bool use_color = AlwaysFalse(); +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + const WORD new_color = GetNewColor(color, old_color_attrs); + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, new_color); + + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +// Text printed in Google Test's text output and --gtest_list_tests +// output to label the type parameter and value parameter for a test. +static const char kTypeParamLabel[] = "TypeParam"; +static const char kValueParamLabel[] = "GetParam()"; + +static void PrintFullTestCommentIfPresent(const TestInfo& test_info) { + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); + + if (type_param != nullptr || value_param != nullptr) { + printf(", where "); + if (type_param != nullptr) { + printf("%s = %s", kTypeParamLabel, type_param); + if (value_param != nullptr) printf(" and "); + } + if (value_param != nullptr) { + printf("%s = %s", kValueParamLabel, value_param); + } + } +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char* test_suite, const char* test) { + printf("%s.%s", test_suite, test); + } + + // The following methods override what's in the TestEventListener class. + void OnTestProgramStart(const UnitTest& /*unit_test*/) override {} + void OnTestIterationStart(const UnitTest& unit_test, int iteration) override; + void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override; + void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {} +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseStart(const TestCase& test_case) override; +#else + void OnTestSuiteStart(const TestSuite& test_suite) override; +#endif // OnTestCaseStart + + void OnTestStart(const TestInfo& test_info) override; + + void OnTestPartResult(const TestPartResult& result) override; + void OnTestEnd(const TestInfo& test_info) override; +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseEnd(const TestCase& test_case) override; +#else + void OnTestSuiteEnd(const TestSuite& test_suite) override; +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override; + void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {} + void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; + void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); + static void PrintSkippedTests(const UnitTest& unit_test); +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %d of %s.\n", + static_cast(shard_index) + 1, + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case.name()); + if (test_case.type_param() == nullptr) { + printf("\n"); + } else { + printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); + } + fflush(stdout); +} +#else +void PrettyUnitTestResultPrinter::OnTestSuiteStart( + const TestSuite& test_suite) { + const std::string counts = + FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_suite.name()); + if (test_suite.type_param() == nullptr) { + printf("\n"); + } else { + printf(", where %s = %s\n", kTypeParamLabel, test_suite.type_param()); + } + fflush(stdout); +} +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_info.test_suite_name(), test_info.name()); + printf("\n"); + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + switch (result.type()) { + // If the test part succeeded, or was skipped, + // we don't need to do anything. + case TestPartResult::kSkip: + case TestPartResult::kSuccess: + return; + default: + // Print failure message from the assertion + // (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); + } +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else if (test_info.result()->Skipped()) { + ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_info.test_suite_name(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); + + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} +#else +void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) { + if (!GTEST_FLAG(print_time)) return; + + const std::string counts = + FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(), + internal::StreamableToString(test_suite.elapsed_time()).c_str()); + fflush(stdout); +} +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { + const TestSuite& test_suite = *unit_test.GetTestSuite(i); + if (!test_suite.should_run() || (test_suite.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_suite.total_test_count(); ++j) { + const TestInfo& test_info = *test_suite.GetTestInfo(j); + if (!test_info.should_run() || !test_info.result()->Failed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_suite.name(), test_info.name()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); + } + } +} + +// Internal helper for printing the list of skipped tests. +void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) { + const int skipped_test_count = unit_test.skipped_test_count(); + if (skipped_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { + const TestSuite& test_suite = *unit_test.GetTestSuite(i); + if (!test_suite.should_run() || (test_suite.skipped_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_suite.total_test_count(); ++j) { + const TestInfo& test_info = *test_suite.GetTestInfo(j); + if (!test_info.should_run() || !test_info.result()->Skipped()) { + continue; + } + ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] "); + printf("%s.%s", test_suite.name(), test_info.name()); + printf("\n"); + } + } +} + +void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + const int skipped_test_count = unit_test.skipped_test_count(); + if (skipped_test_count > 0) { + ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] "); + printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str()); + PrintSkippedTests(unit_test); + } + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.reportable_disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + ~TestEventRepeater() override; + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + void OnTestProgramStart(const UnitTest& unit_test) override; + void OnTestIterationStart(const UnitTest& unit_test, int iteration) override; + void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override; + void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) override; +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseStart(const TestSuite& parameter) override; +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestSuiteStart(const TestSuite& parameter) override; + void OnTestStart(const TestInfo& test_info) override; + void OnTestPartResult(const TestPartResult& result) override; + void OnTestEnd(const TestInfo& test_info) override; +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseEnd(const TestCase& parameter) override; +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestSuiteEnd(const TestSuite& parameter) override; + void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override; + void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) override; + void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; + void OnTestProgramEnd(const UnitTest& unit_test) override; + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + static_cast(i)); + return listener; + } + } + + return nullptr; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ + void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = listeners_.size(); i != 0; i--) { \ + listeners_[i - 1]->Name(parameter); \ + } \ + } \ + } + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite) +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestSuite) +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +GTEST_REVERSE_REPEATER_METHOD_(OnTestSuiteEnd, TestSuite) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = listeners_.size(); i > 0; i--) { + listeners_[i - 1]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; + void ListTestsMatchingFilter(const std::vector& test_suites); + + // Prints an XML summary of all unit tests. + static void PrintXmlTestsList(std::ostream* stream, + const std::vector& test_suites); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static std::string EscapeXml(const std::string& str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static std::string RemoveInvalidXmlCharacters(const std::string& str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static std::string EscapeXmlAttribute(const std::string& str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static std::string EscapeXmlText(const char* str) { + return EscapeXml(str, false); + } + + // Verifies that the given attribute belongs to the given element and + // streams the attribute as XML. + static void OutputXmlAttribute(std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value); + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_suite_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestSuite object + static void PrintXmlTestSuite(::std::ostream* stream, + const TestSuite& test_suite); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(::std::ostream* stream, + const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the std::string is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static std::string TestPropertiesAsXmlAttributes(const TestResult& result); + + // Streams an XML representation of the test properties of a TestResult + // object. + static void OutputXmlTestProperties(std::ostream* stream, + const TestResult& result); + + // The output file. + const std::string output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.empty()) { + GTEST_LOG_(FATAL) << "XML output file may not be null"; + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = OpenFileForWriting(output_file_); + std::stringstream stream; + PrintXmlUnitTest(&stream, unit_test); + fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); + fclose(xmlout); +} + +void XmlUnitTestResultPrinter::ListTestsMatchingFilter( + const std::vector& test_suites) { + FILE* xmlout = OpenFileForWriting(output_file_); + std::stringstream stream; + PrintXmlTestsList(&stream, test_suites); + fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +std::string XmlUnitTestResultPrinter::EscapeXml( + const std::string& str, bool is_attribute) { + Message m; + + for (size_t i = 0; i < str.size(); ++i) { + const char ch = str[i]; + switch (ch) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(ch)) { + if (is_attribute && IsNormalizableWhitespace(ch)) + m << "&#x" << String::FormatByte(static_cast(ch)) + << ";"; + else + m << ch; + } + break; + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( + const std::string& str) { + std::string output; + output.reserve(str.size()); + for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); + + return output; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// GOOGLETEST_CM0009 DO NOT DELETE +// +// This is how Google Test concepts map to the DTD: +// +// <-- corresponds to a UnitTest object +// <-- corresponds to a TestSuite object +// <-- corresponds to a TestInfo object +// ... +// ... +// ... +// <-- individual assertion failures +// +// +// + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << (static_cast(ms) * 1e-3); + return ss.str(); +} + +static bool PortableLocaltime(time_t seconds, struct tm* out) { +#if defined(_MSC_VER) + return localtime_s(out, &seconds) == 0; +#elif defined(__MINGW32__) || defined(__MINGW64__) + // MINGW provides neither localtime_r nor localtime_s, but uses + // Windows' localtime(), which has a thread-local tm buffer. + struct tm* tm_ptr = localtime(&seconds); // NOLINT + if (tm_ptr == nullptr) return false; + *out = *tm_ptr; + return true; +#else + return localtime_r(&seconds, out) != nullptr; +#endif +} + +// Converts the given epoch time in milliseconds to a date string in the ISO +// 8601 format, without the timezone information. +std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { + struct tm time_struct; + if (!PortableLocaltime(static_cast(ms / 1000), &time_struct)) + return ""; + // YYYY-MM-DDThh:mm:ss + return StreamableToString(time_struct.tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct.tm_mday) + "T" + + String::FormatIntWidth2(time_struct.tm_hour) + ":" + + String::FormatIntWidth2(time_struct.tm_min) + ":" + + String::FormatIntWidth2(time_struct.tm_sec); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << ""); + if (next_segment != nullptr) { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +void XmlUnitTestResultPrinter::OutputXmlAttribute( + std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value) { + const std::vector& allowed_names = + GetReservedOutputAttributesForElement(element_name); + + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Attribute " << name << " is not allowed for element <" << element_name + << ">."; + + *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; +} + +// Prints an XML representation of a TestInfo object. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_suite_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + const std::string kTestsuite = "testcase"; + + if (test_info.is_in_another_shard()) { + return; + } + + *stream << " \n"; + return; + } + + OutputXmlAttribute(stream, kTestsuite, "status", + test_info.should_run() ? "run" : "notrun"); + OutputXmlAttribute(stream, kTestsuite, "result", + test_info.should_run() + ? (result.Skipped() ? "skipped" : "completed") + : "suppressed"); + OutputXmlAttribute(stream, kTestsuite, "time", + FormatTimeInMillisAsSeconds(result.elapsed_time())); + OutputXmlAttribute( + stream, kTestsuite, "timestamp", + FormatEpochTimeInMillisAsIso8601(result.start_timestamp())); + OutputXmlAttribute(stream, kTestsuite, "classname", test_suite_name); + + int failures = 0; + for (int i = 0; i < result.total_part_count(); ++i) { + const TestPartResult& part = result.GetTestPartResult(i); + if (part.failed()) { + if (++failures == 1) { + *stream << ">\n"; + } + const std::string location = + internal::FormatCompilerIndependentFileLocation(part.file_name(), + part.line_number()); + const std::string summary = location + "\n" + part.summary(); + *stream << " "; + const std::string detail = location + "\n" + part.message(); + OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); + *stream << "\n"; + } + } + + if (failures == 0 && result.test_property_count() == 0) { + *stream << " />\n"; + } else { + if (failures == 0) { + *stream << ">\n"; + } + OutputXmlTestProperties(stream, result); + *stream << " \n"; + } +} + +// Prints an XML representation of a TestSuite object +void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream, + const TestSuite& test_suite) { + const std::string kTestsuite = "testsuite"; + *stream << " <" << kTestsuite; + OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name()); + OutputXmlAttribute(stream, kTestsuite, "tests", + StreamableToString(test_suite.reportable_test_count())); + if (!GTEST_FLAG(list_tests)) { + OutputXmlAttribute(stream, kTestsuite, "failures", + StreamableToString(test_suite.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuite, "disabled", + StreamableToString(test_suite.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuite, "errors", "0"); + OutputXmlAttribute(stream, kTestsuite, "time", + FormatTimeInMillisAsSeconds(test_suite.elapsed_time())); + OutputXmlAttribute( + stream, kTestsuite, "timestamp", + FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp())); + *stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result()); + } + *stream << ">\n"; + for (int i = 0; i < test_suite.total_test_count(); ++i) { + if (test_suite.GetTestInfo(i)->is_reportable()) + OutputXmlTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i)); + } + *stream << " \n"; +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, + const UnitTest& unit_test) { + const std::string kTestsuites = "testsuites"; + + *stream << "\n"; + *stream << "<" << kTestsuites; + + OutputXmlAttribute(stream, kTestsuites, "tests", + StreamableToString(unit_test.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuites, "failures", + StreamableToString(unit_test.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuites, "disabled", + StreamableToString(unit_test.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuites, "errors", "0"); + OutputXmlAttribute(stream, kTestsuites, "time", + FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); + OutputXmlAttribute( + stream, kTestsuites, "timestamp", + FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); + + if (GTEST_FLAG(shuffle)) { + OutputXmlAttribute(stream, kTestsuites, "random_seed", + StreamableToString(unit_test.random_seed())); + } + *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); + + OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); + *stream << ">\n"; + + for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { + if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) + PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i)); + } + *stream << "\n"; +} + +void XmlUnitTestResultPrinter::PrintXmlTestsList( + std::ostream* stream, const std::vector& test_suites) { + const std::string kTestsuites = "testsuites"; + + *stream << "\n"; + *stream << "<" << kTestsuites; + + int total_tests = 0; + for (auto test_suite : test_suites) { + total_tests += test_suite->total_test_count(); + } + OutputXmlAttribute(stream, kTestsuites, "tests", + StreamableToString(total_tests)); + OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); + *stream << ">\n"; + + for (auto test_suite : test_suites) { + PrintXmlTestSuite(stream, *test_suite); + } + *stream << "\n"; +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +void XmlUnitTestResultPrinter::OutputXmlTestProperties( + std::ostream* stream, const TestResult& result) { + const std::string kProperties = "properties"; + const std::string kProperty = "property"; + + if (result.test_property_count() <= 0) { + return; + } + + *stream << "<" << kProperties << ">\n"; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + *stream << "<" << kProperty; + *stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\""; + *stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\""; + *stream << "/>\n"; + } + *stream << "\n"; +} + +// End XmlUnitTestResultPrinter + +// This class generates an JSON output file. +class JsonUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit JsonUnitTestResultPrinter(const char* output_file); + + void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; + + // Prints an JSON summary of all unit tests. + static void PrintJsonTestList(::std::ostream* stream, + const std::vector& test_suites); + + private: + // Returns an JSON-escaped copy of the input string str. + static std::string EscapeJson(const std::string& str); + + //// Verifies that the given attribute belongs to the given element and + //// streams the attribute as JSON. + static void OutputJsonKey(std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value, + const std::string& indent, + bool comma = true); + static void OutputJsonKey(std::ostream* stream, + const std::string& element_name, + const std::string& name, + int value, + const std::string& indent, + bool comma = true); + + // Streams a JSON representation of a TestInfo object. + static void OutputJsonTestInfo(::std::ostream* stream, + const char* test_suite_name, + const TestInfo& test_info); + + // Prints a JSON representation of a TestSuite object + static void PrintJsonTestSuite(::std::ostream* stream, + const TestSuite& test_suite); + + // Prints a JSON summary of unit_test to output stream out. + static void PrintJsonUnitTest(::std::ostream* stream, + const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as + // a JSON dictionary. + static std::string TestPropertiesAsJson(const TestResult& result, + const std::string& indent); + + // The output file. + const std::string output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(JsonUnitTestResultPrinter); +}; + +// Creates a new JsonUnitTestResultPrinter. +JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.empty()) { + GTEST_LOG_(FATAL) << "JSON output file may not be null"; + } +} + +void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* jsonout = OpenFileForWriting(output_file_); + std::stringstream stream; + PrintJsonUnitTest(&stream, unit_test); + fprintf(jsonout, "%s", StringStreamToString(&stream).c_str()); + fclose(jsonout); +} + +// Returns an JSON-escaped copy of the input string str. +std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) { + Message m; + + for (size_t i = 0; i < str.size(); ++i) { + const char ch = str[i]; + switch (ch) { + case '\\': + case '"': + case '/': + m << '\\' << ch; + break; + case '\b': + m << "\\b"; + break; + case '\t': + m << "\\t"; + break; + case '\n': + m << "\\n"; + break; + case '\f': + m << "\\f"; + break; + case '\r': + m << "\\r"; + break; + default: + if (ch < ' ') { + m << "\\u00" << String::FormatByte(static_cast(ch)); + } else { + m << ch; + } + break; + } + } + + return m.GetString(); +} + +// The following routines generate an JSON representation of a UnitTest +// object. + +// Formats the given time in milliseconds as seconds. +static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) { + ::std::stringstream ss; + ss << (static_cast(ms) * 1e-3) << "s"; + return ss.str(); +} + +// Converts the given epoch time in milliseconds to a date string in the +// RFC3339 format, without the timezone information. +static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) { + struct tm time_struct; + if (!PortableLocaltime(static_cast(ms / 1000), &time_struct)) + return ""; + // YYYY-MM-DDThh:mm:ss + return StreamableToString(time_struct.tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct.tm_mday) + "T" + + String::FormatIntWidth2(time_struct.tm_hour) + ":" + + String::FormatIntWidth2(time_struct.tm_min) + ":" + + String::FormatIntWidth2(time_struct.tm_sec) + "Z"; +} + +static inline std::string Indent(size_t width) { + return std::string(width, ' '); +} + +void JsonUnitTestResultPrinter::OutputJsonKey( + std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value, + const std::string& indent, + bool comma) { + const std::vector& allowed_names = + GetReservedOutputAttributesForElement(element_name); + + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Key \"" << name << "\" is not allowed for value \"" << element_name + << "\"."; + + *stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\""; + if (comma) + *stream << ",\n"; +} + +void JsonUnitTestResultPrinter::OutputJsonKey( + std::ostream* stream, + const std::string& element_name, + const std::string& name, + int value, + const std::string& indent, + bool comma) { + const std::vector& allowed_names = + GetReservedOutputAttributesForElement(element_name); + + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Key \"" << name << "\" is not allowed for value \"" << element_name + << "\"."; + + *stream << indent << "\"" << name << "\": " << StreamableToString(value); + if (comma) + *stream << ",\n"; +} + +// Prints a JSON representation of a TestInfo object. +void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream, + const char* test_suite_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + const std::string kTestsuite = "testcase"; + const std::string kIndent = Indent(10); + + *stream << Indent(8) << "{\n"; + OutputJsonKey(stream, kTestsuite, "name", test_info.name(), kIndent); + + if (test_info.value_param() != nullptr) { + OutputJsonKey(stream, kTestsuite, "value_param", test_info.value_param(), + kIndent); + } + if (test_info.type_param() != nullptr) { + OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(), + kIndent); + } + if (GTEST_FLAG(list_tests)) { + OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent); + OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false); + *stream << "\n" << Indent(8) << "}"; + return; + } + + OutputJsonKey(stream, kTestsuite, "status", + test_info.should_run() ? "RUN" : "NOTRUN", kIndent); + OutputJsonKey(stream, kTestsuite, "result", + test_info.should_run() + ? (result.Skipped() ? "SKIPPED" : "COMPLETED") + : "SUPPRESSED", + kIndent); + OutputJsonKey(stream, kTestsuite, "timestamp", + FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()), + kIndent); + OutputJsonKey(stream, kTestsuite, "time", + FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent); + OutputJsonKey(stream, kTestsuite, "classname", test_suite_name, kIndent, + false); + *stream << TestPropertiesAsJson(result, kIndent); + + int failures = 0; + for (int i = 0; i < result.total_part_count(); ++i) { + const TestPartResult& part = result.GetTestPartResult(i); + if (part.failed()) { + *stream << ",\n"; + if (++failures == 1) { + *stream << kIndent << "\"" << "failures" << "\": [\n"; + } + const std::string location = + internal::FormatCompilerIndependentFileLocation(part.file_name(), + part.line_number()); + const std::string message = EscapeJson(location + "\n" + part.message()); + *stream << kIndent << " {\n" + << kIndent << " \"failure\": \"" << message << "\",\n" + << kIndent << " \"type\": \"\"\n" + << kIndent << " }"; + } + } + + if (failures > 0) + *stream << "\n" << kIndent << "]"; + *stream << "\n" << Indent(8) << "}"; +} + +// Prints an JSON representation of a TestSuite object +void JsonUnitTestResultPrinter::PrintJsonTestSuite( + std::ostream* stream, const TestSuite& test_suite) { + const std::string kTestsuite = "testsuite"; + const std::string kIndent = Indent(6); + + *stream << Indent(4) << "{\n"; + OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent); + OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(), + kIndent); + if (!GTEST_FLAG(list_tests)) { + OutputJsonKey(stream, kTestsuite, "failures", + test_suite.failed_test_count(), kIndent); + OutputJsonKey(stream, kTestsuite, "disabled", + test_suite.reportable_disabled_test_count(), kIndent); + OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent); + OutputJsonKey( + stream, kTestsuite, "timestamp", + FormatEpochTimeInMillisAsRFC3339(test_suite.start_timestamp()), + kIndent); + OutputJsonKey(stream, kTestsuite, "time", + FormatTimeInMillisAsDuration(test_suite.elapsed_time()), + kIndent, false); + *stream << TestPropertiesAsJson(test_suite.ad_hoc_test_result(), kIndent) + << ",\n"; + } + + *stream << kIndent << "\"" << kTestsuite << "\": [\n"; + + bool comma = false; + for (int i = 0; i < test_suite.total_test_count(); ++i) { + if (test_suite.GetTestInfo(i)->is_reportable()) { + if (comma) { + *stream << ",\n"; + } else { + comma = true; + } + OutputJsonTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i)); + } + } + *stream << "\n" << kIndent << "]\n" << Indent(4) << "}"; +} + +// Prints a JSON summary of unit_test to output stream out. +void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream, + const UnitTest& unit_test) { + const std::string kTestsuites = "testsuites"; + const std::string kIndent = Indent(2); + *stream << "{\n"; + + OutputJsonKey(stream, kTestsuites, "tests", unit_test.reportable_test_count(), + kIndent); + OutputJsonKey(stream, kTestsuites, "failures", unit_test.failed_test_count(), + kIndent); + OutputJsonKey(stream, kTestsuites, "disabled", + unit_test.reportable_disabled_test_count(), kIndent); + OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent); + if (GTEST_FLAG(shuffle)) { + OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(), + kIndent); + } + OutputJsonKey(stream, kTestsuites, "timestamp", + FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()), + kIndent); + OutputJsonKey(stream, kTestsuites, "time", + FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent, + false); + + *stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent) + << ",\n"; + + OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent); + *stream << kIndent << "\"" << kTestsuites << "\": [\n"; + + bool comma = false; + for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { + if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) { + if (comma) { + *stream << ",\n"; + } else { + comma = true; + } + PrintJsonTestSuite(stream, *unit_test.GetTestSuite(i)); + } + } + + *stream << "\n" << kIndent << "]\n" << "}\n"; +} + +void JsonUnitTestResultPrinter::PrintJsonTestList( + std::ostream* stream, const std::vector& test_suites) { + const std::string kTestsuites = "testsuites"; + const std::string kIndent = Indent(2); + *stream << "{\n"; + int total_tests = 0; + for (auto test_suite : test_suites) { + total_tests += test_suite->total_test_count(); + } + OutputJsonKey(stream, kTestsuites, "tests", total_tests, kIndent); + + OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent); + *stream << kIndent << "\"" << kTestsuites << "\": [\n"; + + for (size_t i = 0; i < test_suites.size(); ++i) { + if (i != 0) { + *stream << ",\n"; + } + PrintJsonTestSuite(stream, *test_suites[i]); + } + + *stream << "\n" + << kIndent << "]\n" + << "}\n"; +} +// Produces a string representing the test properties in a result as +// a JSON dictionary. +std::string JsonUnitTestResultPrinter::TestPropertiesAsJson( + const TestResult& result, const std::string& indent) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << ",\n" << indent << "\"" << property.key() << "\": " + << "\"" << EscapeJson(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End JsonUnitTestResultPrinter + +#if GTEST_CAN_STREAM_RESULTS_ + +// Checks if str contains '=', '&', '%' or '\n' characters. If yes, +// replaces them by "%xx" where xx is their hexadecimal value. For +// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) +// in both time and space -- important as the input str may contain an +// arbitrarily long test failure message and stack trace. +std::string StreamingListener::UrlEncode(const char* str) { + std::string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) { + switch (ch) { + case '%': + case '=': + case '&': + case '\n': + result.append("%" + String::FormatByte(static_cast(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; +} + +void StreamingListener::SocketWriter::MakeConnection() { + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = nullptr; + + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } + + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != nullptr; + cur_addr = cur_addr->ai_next) { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { + close(sockfd_); + sockfd_ = -1; + } + } + } + + freeaddrinfo(servinfo); // all done with this structure + + if (sockfd_ == -1) { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } +} + +// End of class Streaming Listener +#endif // GTEST_CAN_STREAM_RESULTS__ + +// class OsStackTraceGetter + +const char* const OsStackTraceGetterInterface::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count) + GTEST_LOCK_EXCLUDED_(mutex_) { +#if GTEST_HAS_ABSL + std::string result; + + if (max_depth <= 0) { + return result; + } + + max_depth = std::min(max_depth, kMaxStackTraceDepth); + + std::vector raw_stack(max_depth); + // Skips the frames requested by the caller, plus this function. + const int raw_stack_size = + absl::GetStackTrace(&raw_stack[0], max_depth, skip_count + 1); + + void* caller_frame = nullptr; + { + MutexLock lock(&mutex_); + caller_frame = caller_frame_; + } + + for (int i = 0; i < raw_stack_size; ++i) { + if (raw_stack[i] == caller_frame && + !GTEST_FLAG(show_internal_stack_frames)) { + // Add a marker to the trace and stop adding frames. + absl::StrAppend(&result, kElidedFramesMarker, "\n"); + break; + } + + char tmp[1024]; + const char* symbol = "(unknown)"; + if (absl::Symbolize(raw_stack[i], tmp, sizeof(tmp))) { + symbol = tmp; + } + + char line[1024]; + snprintf(line, sizeof(line), " %p: %s\n", raw_stack[i], symbol); + result += line; + } + + return result; + +#else // !GTEST_HAS_ABSL + static_cast(max_depth); + static_cast(skip_count); + return ""; +#endif // GTEST_HAS_ABSL +} + +void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { +#if GTEST_HAS_ABSL + void* caller_frame = nullptr; + if (absl::GetStackTrace(&caller_frame, 1, 3) <= 0) { + caller_frame = nullptr; + } + + MutexLock lock(&mutex_); + caller_frame_ = caller_frame; +#endif // GTEST_HAS_ABSL +} + +// A helper class that creates the premature-exit file in its +// constructor and deletes the file in its destructor. +class ScopedPrematureExitFile { + public: + explicit ScopedPrematureExitFile(const char* premature_exit_filepath) + : premature_exit_filepath_(premature_exit_filepath ? + premature_exit_filepath : "") { + // If a path to the premature-exit file is specified... + if (!premature_exit_filepath_.empty()) { + // create the file with a single "0" character in it. I/O + // errors are ignored as there's nothing better we can do and we + // don't want to fail the test because of this. + FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); + fwrite("0", 1, 1, pfile); + fclose(pfile); + } + } + + ~ScopedPrematureExitFile() { + if (!premature_exit_filepath_.empty()) { + int retval = remove(premature_exit_filepath_.c_str()); + if (retval) { + GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \"" + << premature_exit_filepath_ << "\" with error " + << retval; + } + } + } + + private: + const std::string premature_exit_filepath_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); +}; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(nullptr), + default_xml_generator_(nullptr) {} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = nullptr; + else if (listener == default_xml_generator_) + default_xml_generator_ = nullptr; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != nullptr) Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != nullptr) Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest* UnitTest::GetInstance() { + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // defined(__BORLANDC__) +} + +// Gets the number of successful test suites. +int UnitTest::successful_test_suite_count() const { + return impl()->successful_test_suite_count(); +} + +// Gets the number of failed test suites. +int UnitTest::failed_test_suite_count() const { + return impl()->failed_test_suite_count(); +} + +// Gets the number of all test suites. +int UnitTest::total_test_suite_count() const { + return impl()->total_test_suite_count(); +} + +// Gets the number of all test suites that contain at least one test +// that should run. +int UnitTest::test_suite_to_run_count() const { + return impl()->test_suite_to_run_count(); +} + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_suite_count(); +} +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_suite_count(); +} +int UnitTest::total_test_case_count() const { + return impl()->total_test_suite_count(); +} +int UnitTest::test_case_to_run_count() const { + return impl()->test_suite_to_run_count(); +} +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of skipped tests. +int UnitTest::skipped_test_count() const { + return impl()->skipped_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTest::reportable_disabled_test_count() const { + return impl()->reportable_disabled_test_count(); +} + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTest::reportable_test_count() const { + return impl()->reportable_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the time of the test program start, in ms from the start of the +// UNIX epoch. +internal::TimeInMillis UnitTest::start_timestamp() const { + return impl()->start_timestamp(); +} + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true if and only if the unit test passed (i.e. all test suites +// passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true if and only if the unit test failed (i.e. some test suite +// failed or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test suite among all the test suites. i can range from 0 to +// total_test_suite_count() - 1. If i is not in that range, returns NULL. +const TestSuite* UnitTest::GetTestSuite(int i) const { + return impl()->GetTestSuite(i); +} + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + +// Returns the TestResult containing information on test failures and +// properties logged outside of individual test suites. +const TestResult& UnitTest::ad_hoc_test_result() const { + return *impl()->ad_hoc_test_result(); +} + +// Gets the i-th test suite among all the test suites. i can range from 0 to +// total_test_suite_count() - 1. If i is not in that range, returns NULL. +TestSuite* UnitTest::GetMutableTestSuite(int i) { + return impl()->GetMutableSuiteCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == nullptr) { + return nullptr; + } + + impl_->environments().push_back(env); + return env; +} + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +void UnitTest::AddTestPartResult( + TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (size_t i = impl_->gtest_trace_stack().size(); i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != nullptr && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = TestPartResult( + result_type, file_name, line_number, msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess && + result_type != TestPartResult::kSkip) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#elif (!defined(__native_client__)) && \ + ((defined(__clang__) || defined(__GNUC__)) && \ + (defined(__x86_64__) || defined(__i386__))) + // with clang/gcc we can achieve the same effect on x86 by invoking int3 + asm("int3"); +#else + // Dereference nullptr through a volatile pointer to prevent the compiler + // from removing. We use this rather than abort() or __builtin_trap() for + // portability: some debuggers don't correctly trap abort(). + *static_cast(nullptr) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw internal::GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Adds a TestProperty to the current TestResult object when invoked from +// inside a test, to current TestSuite's ad_hoc_test_result_ when invoked +// from SetUpTestSuite or TearDownTestSuite, or to the global property set +// when invoked elsewhere. If the result already contains a property with +// the same key, the value will be updated. +void UnitTest::RecordProperty(const std::string& key, + const std::string& value) { + impl_->RecordProperty(TestProperty(key, value)); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Google Test implements this protocol for catching that a test + // program exits before returning control to Google Test: + // + // 1. Upon start, Google Test creates a file whose absolute path + // is specified by the environment variable + // TEST_PREMATURE_EXIT_FILE. + // 2. When Google Test has finished its work, it deletes the file. + // + // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before + // running a Google-Test-based test program and check the existence + // of the file at the end of the test execution to see if it has + // exited prematurely. + + // If we are in the child process of a death test, don't + // create/delete the premature exit file, as doing so is unnecessary + // and will confuse the parent process. Otherwise, create/delete + // the file upon entering/leaving this function. If the program + // somehow exits before this function has a chance to return, the + // premature-exit file will be left undeleted, causing a test runner + // that understands the premature-exit-file protocol to report the + // test as having failed. + const internal::ScopedPrematureExitFile premature_exit_file( + in_death_test_child_process + ? nullptr + : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); + + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + +#if GTEST_OS_WINDOWS + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) { +# if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +# endif // !GTEST_OS_WINDOWS_MOBILE + +# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +# endif + +# if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +# endif + + // In debug mode, the Windows CRT can crash with an assertion over invalid + // input (e.g. passing an invalid file descriptor). The default handling + // for these assertions is to pop up a dialog and wait for user input. + // Instead ask the CRT to dump such assertions to stderr non-interactively. + if (!IsDebuggerPresent()) { + (void)_CrtSetReportMode(_CRT_ASSERT, + _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); + } + } +#endif // GTEST_OS_WINDOWS + + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") ? 0 : 1; +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestSuite object for the test that's currently running, +// or NULL if no test is running. +const TestSuite* UnitTest::current_test_suite() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_suite(); +} + +// Legacy API is still available but deprecated +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ +const TestCase* UnitTest::current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_suite(); +} +#endif + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +const TestInfo* UnitTest::current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +// Returns ParameterizedTestSuiteRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +internal::ParameterizedTestSuiteRegistry& +UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) { + return impl_->parameterized_test_registry(); +} + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +void UnitTest::PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */) + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), + GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), + parameterized_test_registry_(), + parameterized_tests_registered_(false), + last_death_test_suite_(-1), + current_test_suite_(nullptr), + current_test_info_(nullptr), + ad_hoc_test_result_(), + os_stack_trace_getter_(nullptr), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. + start_timestamp_(0), + elapsed_time_(0), +#if GTEST_HAS_DEATH_TEST + death_test_factory_(new DefaultDeathTestFactory), +#endif + // Will be overridden by the flag before first use. + catch_exceptions_(false) { + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestSuite. + ForEach(test_suites_, internal::Delete); + + // Deletes every Environment. + ForEach(environments_, internal::Delete); + + delete os_stack_trace_getter_; +} + +// Adds a TestProperty to the current TestResult object when invoked in a +// context of a test, to current test suite's ad_hoc_test_result when invoke +// from SetUpTestSuite/TearDownTestSuite, or to the global property set +// otherwise. If the result already contains a property with the same key, +// the value will be updated. +void UnitTestImpl::RecordProperty(const TestProperty& test_property) { + std::string xml_element; + TestResult* test_result; // TestResult appropriate for property recording. + + if (current_test_info_ != nullptr) { + xml_element = "testcase"; + test_result = &(current_test_info_->result_); + } else if (current_test_suite_ != nullptr) { + xml_element = "testsuite"; + test_result = &(current_test_suite_->ad_hoc_test_result_); + } else { + xml_element = "testsuites"; + test_result = &ad_hoc_test_result_; + } + test_result->RecordProperty(xml_element, test_property); +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != nullptr) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const std::string& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format == "json") { + listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \"" + << output_format << "\" ignored."; + } +} + +#if GTEST_CAN_STREAM_RESULTS_ +// Initializes event listeners for streaming test results in string form. +// Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureStreamingOutput() { + const std::string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) { + const size_t pos = target.find(':'); + if (pos != std::string::npos) { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos+1))); + } else { + GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target + << "\" ignored."; + } + } +} +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) + // Register to send notifications about key process state changes. + listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_()); +#endif // defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); +#endif // GTEST_CAN_STREAM_RESULTS_ + +#if GTEST_HAS_ABSL + if (GTEST_FLAG(install_failure_signal_handler)) { + absl::FailureSignalHandlerOptions options; + absl::InstallFailureSignalHandler(options); + } +#endif // GTEST_HAS_ABSL + } +} + +// A predicate that checks the name of a TestSuite against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestSuiteNameIs is copyable. +class TestSuiteNameIs { + public: + // Constructor. + explicit TestSuiteNameIs(const std::string& name) : name_(name) {} + + // Returns true if and only if the name of test_suite matches name_. + bool operator()(const TestSuite* test_suite) const { + return test_suite != nullptr && + strcmp(test_suite->name(), name_.c_str()) == 0; + } + + private: + std::string name_; +}; + +// Finds and returns a TestSuite with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_suite_name: name of the test suite +// type_param: the name of the test suite's type parameter, or NULL if +// this is not a typed or a type-parameterized test suite. +// set_up_tc: pointer to the function that sets up the test suite +// tear_down_tc: pointer to the function that tears down the test suite +TestSuite* UnitTestImpl::GetTestSuite( + const char* test_suite_name, const char* type_param, + internal::SetUpTestSuiteFunc set_up_tc, + internal::TearDownTestSuiteFunc tear_down_tc) { + // Can we find a TestSuite with the given name? + const auto test_suite = + std::find_if(test_suites_.rbegin(), test_suites_.rend(), + TestSuiteNameIs(test_suite_name)); + + if (test_suite != test_suites_.rend()) return *test_suite; + + // No. Let's create one. + auto* const new_test_suite = + new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc); + + // Is this a death test suite? + if (internal::UnitTestOptions::MatchesFilter(test_suite_name, + kDeathTestSuiteFilter)) { + // Yes. Inserts the test suite after the last death test suite + // defined so far. This only works when the test suites haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_suite_; + test_suites_.insert(test_suites_.begin() + last_death_test_suite_, + new_test_suite); + } else { + // No. Appends to the end of the list. + test_suites_.push_back(new_test_suite); + } + + test_suite_indices_.push_back(static_cast(test_suite_indices_.size())); + return new_test_suite; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns true if all tests are successful. If any exception is +// thrown during a test, the test is considered to be failed, but the +// rest of the tests will still be run. +// +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +bool UnitTestImpl::RunAllTests() { + // True if and only if Google Test is initialized before RUN_ALL_TESTS() is + // called. + const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized(); + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return true; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True if and only if we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = + (internal_run_death_test_flag_.get() != nullptr); +# if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) + if (in_subprocess_for_death_test) { + GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_(); + } +# endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return true; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True if and only if at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + start_timestamp_ = GetTimeInMillis(); + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool gtest_repeat_forever = repeat < 0; + for (int i = 0; gtest_repeat_forever || i != repeat; i++) { + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test suites and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(static_cast(random_seed_)); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test suite if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure or skip triggered + // during global set-up. + if (Test::IsSkipped()) { + // Emit diagnostics when global set-up calls skip, as it will not be + // emitted by default. + TestResult& test_result = + *internal::GetUnitTestImpl()->current_test_result(); + for (int j = 0; j < test_result.total_part_count(); ++j) { + const TestPartResult& test_part_result = + test_result.GetTestPartResult(j); + if (test_part_result.type() == TestPartResult::kSkip) { + const std::string& result = test_part_result.message(); + printf("%s\n", result.c_str()); + } + } + fflush(stdout); + } else if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_suite_count(); + test_index++) { + GetMutableSuiteCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + if (!gtest_is_initialized_before_run_all_tests) { + ColoredPrintf( + COLOR_RED, + "\nIMPORTANT NOTICE - DO NOT IGNORE:\n" + "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_ + "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_ + " will start to enforce the valid usage. " + "Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT +#if GTEST_FOR_GOOGLE_ + ColoredPrintf(COLOR_RED, + "For more details, see http://wiki/Main/ValidGUnitMain.\n"); +#endif // GTEST_FOR_GOOGLE_ + } + + return !failed; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != nullptr) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == nullptr) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == nullptr) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true if and only if the test should be run on this shard. The test id +// is some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestSuite and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md +// . Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (auto* test_suite : test_suites_) { + const std::string& test_suite_name = test_suite->name(); + test_suite->set_should_run(false); + + for (size_t j = 0; j < test_suite->test_info_list().size(); j++) { + TestInfo* const test_info = test_suite->test_info_list()[j]; + const std::string test_name(test_info->name()); + // A test is disabled if test suite name or test name matches + // kDisableTestFilter. + const bool is_disabled = internal::UnitTestOptions::MatchesFilter( + test_suite_name, kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter( + test_name, kDisableTestFilter); + test_info->is_disabled_ = is_disabled; + + const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest( + test_suite_name, test_name); + test_info->matches_filter_ = matches_filter; + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_in_another_shard = + shard_tests != IGNORE_SHARDING_PROTOCOL && + !ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests); + test_info->is_in_another_shard_ = is_in_another_shard; + const bool is_selected = is_runnable && !is_in_another_shard; + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->should_run_ = is_selected; + test_suite->set_should_run(test_suite->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the given C-string on a single line by replacing all '\n' +// characters with string "\\n". If the output takes more than +// max_length characters, only prints the first max_length characters +// and "...". +static void PrintOnOneLine(const char* str, int max_length) { + if (str != nullptr) { + for (int i = 0; *str != '\0'; ++str) { + if (i >= max_length) { + printf("..."); + break; + } + if (*str == '\n') { + printf("\\n"); + i += 2; + } else { + printf("%c", *str); + ++i; + } + } + } +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + // Print at most this many characters for each type/value parameter. + const int kMaxParamLength = 250; + + for (auto* test_suite : test_suites_) { + bool printed_test_suite_name = false; + + for (size_t j = 0; j < test_suite->test_info_list().size(); j++) { + const TestInfo* const test_info = test_suite->test_info_list()[j]; + if (test_info->matches_filter_) { + if (!printed_test_suite_name) { + printed_test_suite_name = true; + printf("%s.", test_suite->name()); + if (test_suite->type_param() != nullptr) { + printf(" # %s = ", kTypeParamLabel); + // We print the type parameter on a single line to make + // the output easy to parse by a program. + PrintOnOneLine(test_suite->type_param(), kMaxParamLength); + } + printf("\n"); + } + printf(" %s", test_info->name()); + if (test_info->value_param() != nullptr) { + printf(" # %s = ", kValueParamLabel); + // We print the value parameter on a single line to make the + // output easy to parse by a program. + PrintOnOneLine(test_info->value_param(), kMaxParamLength); + } + printf("\n"); + } + } + } + fflush(stdout); + const std::string& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml" || output_format == "json") { + FILE* fileout = OpenFileForWriting( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); + std::stringstream stream; + if (output_format == "xml") { + XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()) + .PrintXmlTestsList(&stream, test_suites_); + } else if (output_format == "json") { + JsonUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()) + .PrintJsonTestList(&stream, test_suites_); + } + fprintf(fileout, "%s", StringStreamToString(&stream).c_str()); + fclose(fileout); + } +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == nullptr) { +#ifdef GTEST_OS_STACK_TRACE_GETTER_ + os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_; +#else + os_stack_trace_getter_ = new OsStackTraceGetter; +#endif // GTEST_OS_STACK_TRACE_GETTER_ + } + + return os_stack_trace_getter_; +} + +// Returns the most specific TestResult currently running. +TestResult* UnitTestImpl::current_test_result() { + if (current_test_info_ != nullptr) { + return ¤t_test_info_->result_; + } + if (current_test_suite_ != nullptr) { + return ¤t_test_suite_->ad_hoc_test_result_; + } + return &ad_hoc_test_result_; +} + +// Shuffles all test suites, and the tests within each test suite, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test suites. + ShuffleRange(random(), 0, last_death_test_suite_ + 1, &test_suite_indices_); + + // Shuffles the non-death test suites. + ShuffleRange(random(), last_death_test_suite_ + 1, + static_cast(test_suites_.size()), &test_suite_indices_); + + // Shuffles the tests inside each test suite. + for (auto& test_suite : test_suites_) { + test_suite->ShuffleTests(random()); + } +} + +// Restores the test suites and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_suites_.size(); i++) { + // Unshuffles the tests in each test suite. + test_suites_[i]->UnshuffleTests(); + // Resets the index of each test suite. + test_suite_indices_[i] = static_cast(i); + } +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to +// suppress unreachable code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +static const char* ParseFlagValue(const char* str, const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == nullptr || flag == nullptr) return nullptr; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return nullptr; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +static bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +template +static bool ParseStringFlag(const char* str, const char* flag, String* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == nullptr) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", std::string(str, p).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate a JSON or XML report in the given directory or with the given\n" +" file name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\n" +# if GTEST_CAN_STREAM_RESULTS_ +" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" +" Stream test results to the given server.\n" +# endif // GTEST_CAN_STREAM_RESULTS_ +"\n" +"Assertion Behavior:\n" +# if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +# endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions for use by an external\n" +" test framework.\n" +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" +" Do not report exceptions as test failures. Instead, allow them\n" +" to crash the program or throw a pop-up (on Windows).\n" +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +static bool ParseGoogleTestFlag(const char* const arg) { + return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)); +} + +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +static void LoadFlagsFromFile(const std::string& path) { + FILE* flagfile = posix::FOpen(path.c_str(), "r"); + if (!flagfile) { + GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile) + << "\""; + } + std::string contents(ReadEntireFile(flagfile)); + posix::FClose(flagfile); + std::vector lines; + SplitString(contents, '\n', &lines); + for (size_t i = 0; i < lines.size(); ++i) { + if (lines[i].empty()) + continue; + if (!ParseGoogleTestFlag(lines[i].c_str())) + g_help_flag = true; + } +} +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + bool remove_flag = false; + if (ParseGoogleTestFlag(arg)) { + remove_flag = true; +#if GTEST_USE_OWN_FLAGFILE_FLAG_ + } else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) { + LoadFlagsFromFile(GTEST_FLAG(flagfile)); + remove_flag = true; +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + + if (remove_flag) { + // Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); + + // Fix the value of *_NSGetArgc() on macOS, but if and only if + // *_NSGetArgv() == argv + // Only applicable to char** version of argv +#if GTEST_OS_MAC +#ifndef GTEST_OS_IOS + if (*_NSGetArgv() == argv) { + *_NSGetArgc() = *argc; + } +#endif +#endif +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleTestImpl(int* argc, CharType** argv) { + // We don't want to run the initialization code twice. + if (GTestIsInitialized()) return; + + if (*argc <= 0) return; + + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } + +#if GTEST_HAS_ABSL + absl::InitializeSymbolizer(g_argvs[0].c_str()); +#endif // GTEST_HAS_ABSL + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { +#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + internal::InitGoogleTestImpl(argc, argv); +#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { +#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + internal::InitGoogleTestImpl(argc, argv); +#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) +} + +// This overloaded version can be used on Arduino/embedded platforms where +// there is no argc/argv. +void InitGoogleTest() { + // Since Arduino doesn't have a command line, fake out the argc/argv arguments + int argc = 1; + const auto arg0 = "dummy"; + char* argv0 = const_cast(arg0); + char** argv = &argv0; + +#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(&argc, argv); +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + internal::InitGoogleTestImpl(&argc, argv); +#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) +} + +std::string TempDir() { +#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) + return GTEST_CUSTOM_TEMPDIR_FUNCTION_(); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + return "\\temp\\"; +#elif GTEST_OS_WINDOWS + const char* temp_dir = internal::posix::GetEnv("TEMP"); + if (temp_dir == nullptr || temp_dir[0] == '\0') + return "\\temp\\"; + else if (temp_dir[strlen(temp_dir) - 1] == '\\') + return temp_dir; + else + return std::string(temp_dir) + "\\"; +#elif GTEST_OS_LINUX_ANDROID + return "/sdcard/"; +#else + return "/tmp/"; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +void ScopedTrace::PushTrace(const char* file, int line, std::string message) { + internal::TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message.swap(message); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +ScopedTrace::~ScopedTrace() + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + UnitTest::GetInstance()->PopGTestTrace(); +} + +} // namespace testing diff --git a/3rdparty/gtest/src/gtest_main.cc b/3rdparty/gtest/src/gtest_main.cc new file mode 100644 index 0000000..f6e1dd9 --- /dev/null +++ b/3rdparty/gtest/src/gtest_main.cc @@ -0,0 +1,47 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include "gtest/gtest.h" + +#ifdef ARDUINO +void setup() { + testing::InitGoogleTest(); +} + +void loop() { RUN_ALL_TESTS(); } + +#else + +GTEST_API_ int main(int argc, char **argv) { + printf("Running main() from %s\n", __FILE__); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/3rdparty/gtest/test/BUILD.bazel b/3rdparty/gtest/test/BUILD.bazel new file mode 100644 index 0000000..156d5d4 --- /dev/null +++ b/3rdparty/gtest/test/BUILD.bazel @@ -0,0 +1,521 @@ +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Author: misterg@google.com (Gennadiy Civil) +# +# Bazel BUILD for The Google C++ Testing Framework (Google Test) + +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") +load("@rules_python//python:defs.bzl", "py_library", "py_test") + +licenses(["notice"]) + +#on windows exclude gtest-tuple.h +cc_test( + name = "gtest_all_test", + size = "small", + srcs = glob( + include = [ + "gtest-*.cc", + "googletest-*.cc", + "*.h", + "googletest/include/gtest/**/*.h", + ], + exclude = [ + "gtest-unittest-api_test.cc", + "googletest/src/gtest-all.cc", + "gtest_all_test.cc", + "gtest-death-test_ex_test.cc", + "gtest-listener_test.cc", + "gtest-unittest-api_test.cc", + "googletest-param-test-test.cc", + "googletest-catch-exceptions-test_.cc", + "googletest-color-test_.cc", + "googletest-env-var-test_.cc", + "googletest-filter-unittest_.cc", + "googletest-break-on-failure-unittest_.cc", + "googletest-listener-test.cc", + "googletest-output-test_.cc", + "googletest-list-tests-unittest_.cc", + "googletest-shuffle-test_.cc", + "googletest-uninitialized-test_.cc", + "googletest-death-test_ex_test.cc", + "googletest-param-test-test", + "googletest-throw-on-failure-test_.cc", + "googletest-param-test-invalid-name1-test_.cc", + "googletest-param-test-invalid-name2-test_.cc", + ], + ) + select({ + "//:windows": [], + "//conditions:default": [], + }), + copts = select({ + "//:windows": ["-DGTEST_USE_OWN_TR1_TUPLE=0"], + "//conditions:default": ["-DGTEST_USE_OWN_TR1_TUPLE=1"], + }), + includes = [ + "googletest", + "googletest/include", + "googletest/include/internal", + "googletest/test", + ], + linkopts = select({ + "//:windows": [], + "//conditions:default": ["-pthread"], + }), + deps = ["//:gtest_main"], +) + +# Tests death tests. +cc_test( + name = "googletest-death-test-test", + size = "medium", + srcs = ["googletest-death-test-test.cc"], + deps = ["//:gtest_main"], +) + +cc_test( + name = "gtest_test_macro_stack_footprint_test", + size = "small", + srcs = ["gtest_test_macro_stack_footprint_test.cc"], + deps = ["//:gtest"], +) + +#These googletest tests have their own main() +cc_test( + name = "googletest-listener-test", + size = "small", + srcs = ["googletest-listener-test.cc"], + deps = ["//:gtest_main"], +) + +cc_test( + name = "gtest-unittest-api_test", + size = "small", + srcs = [ + "gtest-unittest-api_test.cc", + ], + deps = [ + "//:gtest", + ], +) + +cc_test( + name = "googletest-param-test-test", + size = "small", + srcs = [ + "googletest-param-test-test.cc", + "googletest-param-test-test.h", + "googletest-param-test2-test.cc", + ], + deps = ["//:gtest"], +) + +cc_test( + name = "gtest_unittest", + size = "small", + srcs = ["gtest_unittest.cc"], + args = ["--heap_check=strict"], + shard_count = 2, + deps = ["//:gtest_main"], +) + +# Py tests + +py_library( + name = "gtest_test_utils", + testonly = 1, + srcs = ["gtest_test_utils.py"], +) + +cc_binary( + name = "gtest_help_test_", + testonly = 1, + srcs = ["gtest_help_test_.cc"], + deps = ["//:gtest_main"], +) + +py_test( + name = "gtest_help_test", + size = "small", + srcs = ["gtest_help_test.py"], + data = [":gtest_help_test_"], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "googletest-output-test_", + testonly = 1, + srcs = ["googletest-output-test_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-output-test", + size = "small", + srcs = ["googletest-output-test.py"], + args = select({ + "//:has_absl": [], + "//conditions:default": ["--no_stacktrace_support"], + }), + data = [ + "googletest-output-test-golden-lin.txt", + ":googletest-output-test_", + ], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "googletest-color-test_", + testonly = 1, + srcs = ["googletest-color-test_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-color-test", + size = "small", + srcs = ["googletest-color-test.py"], + data = [":googletest-color-test_"], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "googletest-env-var-test_", + testonly = 1, + srcs = ["googletest-env-var-test_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-env-var-test", + size = "medium", + srcs = ["googletest-env-var-test.py"], + data = [":googletest-env-var-test_"], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "googletest-filter-unittest_", + testonly = 1, + srcs = ["googletest-filter-unittest_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-filter-unittest", + size = "medium", + srcs = ["googletest-filter-unittest.py"], + data = [":googletest-filter-unittest_"], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "googletest-break-on-failure-unittest_", + testonly = 1, + srcs = ["googletest-break-on-failure-unittest_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-break-on-failure-unittest", + size = "small", + srcs = ["googletest-break-on-failure-unittest.py"], + data = [":googletest-break-on-failure-unittest_"], + deps = [":gtest_test_utils"], +) + +cc_test( + name = "gtest_assert_by_exception_test", + size = "small", + srcs = ["gtest_assert_by_exception_test.cc"], + deps = ["//:gtest"], +) + +cc_binary( + name = "googletest-throw-on-failure-test_", + testonly = 1, + srcs = ["googletest-throw-on-failure-test_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-throw-on-failure-test", + size = "small", + srcs = ["googletest-throw-on-failure-test.py"], + data = [":googletest-throw-on-failure-test_"], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "googletest-list-tests-unittest_", + testonly = 1, + srcs = ["googletest-list-tests-unittest_.cc"], + deps = ["//:gtest"], +) + +cc_test( + name = "gtest_skip_test", + size = "small", + srcs = ["gtest_skip_test.cc"], + deps = ["//:gtest_main"], +) + +cc_test( + name = "gtest_skip_in_environment_setup_test", + size = "small", + srcs = ["gtest_skip_in_environment_setup_test.cc"], + deps = ["//:gtest_main"], +) + +py_test( + name = "gtest_skip_environment_check_output_test", + size = "small", + srcs = ["gtest_skip_environment_check_output_test.py"], + data = [ + ":gtest_skip_in_environment_setup_test", + ], + deps = [":gtest_test_utils"], +) + +py_test( + name = "googletest-list-tests-unittest", + size = "small", + srcs = ["googletest-list-tests-unittest.py"], + data = [":googletest-list-tests-unittest_"], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "googletest-shuffle-test_", + srcs = ["googletest-shuffle-test_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-shuffle-test", + size = "small", + srcs = ["googletest-shuffle-test.py"], + data = [":googletest-shuffle-test_"], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "googletest-catch-exceptions-no-ex-test_", + testonly = 1, + srcs = ["googletest-catch-exceptions-test_.cc"], + deps = ["//:gtest_main"], +) + +cc_binary( + name = "googletest-catch-exceptions-ex-test_", + testonly = 1, + srcs = ["googletest-catch-exceptions-test_.cc"], + copts = ["-fexceptions"], + deps = ["//:gtest_main"], +) + +py_test( + name = "googletest-catch-exceptions-test", + size = "small", + srcs = ["googletest-catch-exceptions-test.py"], + data = [ + ":googletest-catch-exceptions-ex-test_", + ":googletest-catch-exceptions-no-ex-test_", + ], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "gtest_xml_output_unittest_", + testonly = 1, + srcs = ["gtest_xml_output_unittest_.cc"], + deps = ["//:gtest"], +) + +cc_test( + name = "gtest_no_test_unittest", + size = "small", + srcs = ["gtest_no_test_unittest.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "gtest_xml_output_unittest", + size = "small", + srcs = [ + "gtest_xml_output_unittest.py", + "gtest_xml_test_utils.py", + ], + args = select({ + "//:has_absl": [], + "//conditions:default": ["--no_stacktrace_support"], + }), + data = [ + # We invoke gtest_no_test_unittest to verify the XML output + # when the test program contains no test definition. + ":gtest_no_test_unittest", + ":gtest_xml_output_unittest_", + ], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "gtest_xml_outfile1_test_", + testonly = 1, + srcs = ["gtest_xml_outfile1_test_.cc"], + deps = ["//:gtest_main"], +) + +cc_binary( + name = "gtest_xml_outfile2_test_", + testonly = 1, + srcs = ["gtest_xml_outfile2_test_.cc"], + deps = ["//:gtest_main"], +) + +py_test( + name = "gtest_xml_outfiles_test", + size = "small", + srcs = [ + "gtest_xml_outfiles_test.py", + "gtest_xml_test_utils.py", + ], + data = [ + ":gtest_xml_outfile1_test_", + ":gtest_xml_outfile2_test_", + ], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "googletest-uninitialized-test_", + testonly = 1, + srcs = ["googletest-uninitialized-test_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-uninitialized-test", + size = "medium", + srcs = ["googletest-uninitialized-test.py"], + data = ["googletest-uninitialized-test_"], + deps = [":gtest_test_utils"], +) + +cc_binary( + name = "gtest_testbridge_test_", + testonly = 1, + srcs = ["gtest_testbridge_test_.cc"], + deps = ["//:gtest_main"], +) + +# Tests that filtering via testbridge works +py_test( + name = "gtest_testbridge_test", + size = "small", + srcs = ["gtest_testbridge_test.py"], + data = [":gtest_testbridge_test_"], + deps = [":gtest_test_utils"], +) + +py_test( + name = "googletest-json-outfiles-test", + size = "small", + srcs = [ + "googletest-json-outfiles-test.py", + "gtest_json_test_utils.py", + ], + data = [ + ":gtest_xml_outfile1_test_", + ":gtest_xml_outfile2_test_", + ], + deps = [":gtest_test_utils"], +) + +py_test( + name = "googletest-json-output-unittest", + size = "medium", + srcs = [ + "googletest-json-output-unittest.py", + "gtest_json_test_utils.py", + ], + args = select({ + "//:has_absl": [], + "//conditions:default": ["--no_stacktrace_support"], + }), + data = [ + # We invoke gtest_no_test_unittest to verify the JSON output + # when the test program contains no test definition. + ":gtest_no_test_unittest", + ":gtest_xml_output_unittest_", + ], + deps = [":gtest_test_utils"], +) + +# Verifies interaction of death tests and exceptions. +cc_test( + name = "googletest-death-test_ex_catch_test", + size = "medium", + srcs = ["googletest-death-test_ex_test.cc"], + copts = ["-fexceptions"], + defines = ["GTEST_ENABLE_CATCH_EXCEPTIONS_=1"], + deps = ["//:gtest"], +) + +cc_binary( + name = "googletest-param-test-invalid-name1-test_", + testonly = 1, + srcs = ["googletest-param-test-invalid-name1-test_.cc"], + deps = ["//:gtest"], +) + +cc_binary( + name = "googletest-param-test-invalid-name2-test_", + testonly = 1, + srcs = ["googletest-param-test-invalid-name2-test_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-param-test-invalid-name1-test", + size = "small", + srcs = ["googletest-param-test-invalid-name1-test.py"], + data = [":googletest-param-test-invalid-name1-test_"], + deps = [":gtest_test_utils"], +) + +py_test( + name = "googletest-param-test-invalid-name2-test", + size = "small", + srcs = ["googletest-param-test-invalid-name2-test.py"], + data = [":googletest-param-test-invalid-name2-test_"], + deps = [":gtest_test_utils"], +) diff --git a/3rdparty/gtest/test/googletest-break-on-failure-unittest.py b/3rdparty/gtest/test/googletest-break-on-failure-unittest.py new file mode 100644 index 0000000..a5dfbc6 --- /dev/null +++ b/3rdparty/gtest/test/googletest-break-on-failure-unittest.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test for Google Test's break-on-failure mode. + +A user can ask Google Test to seg-fault when an assertion fails, using +either the GTEST_BREAK_ON_FAILURE environment variable or the +--gtest_break_on_failure flag. This script tests such functionality +by invoking googletest-break-on-failure-unittest_ (a program written with +Google Test) with different environments and command line flags. +""" + +import os +import gtest_test_utils + +# Constants. + +IS_WINDOWS = os.name == 'nt' + +# The environment variable for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE' + +# The command line flag for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' + +# The environment variable for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' + +# The environment variable for enabling/disabling the catch-exceptions mode. +CATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS' + +# Path to the googletest-break-on-failure-unittest_ program. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'googletest-break-on-failure-unittest_') + + +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) + + +def Run(command): + """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.""" + + p = gtest_test_utils.Subprocess(command, env=environ) + if p.terminated_by_signal: + return 1 + else: + return 0 + + +# The tests. + + +class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable or + the --gtest_break_on_failure flag to turn assertion failures into + segmentation faults. + """ + + def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault): + """Runs googletest-break-on-failure-unittest_ and verifies that it does + (or does not) have a seg-fault. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + expect_seg_fault: 1 if the program is expected to generate a seg-fault; + 0 otherwise. + """ + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = '--%s=0' % BREAK_ON_FAILURE_FLAG + else: + flag = '--%s' % BREAK_ON_FAILURE_FLAG + + command = [EXE_PATH] + if flag: + command.append(flag) + + if expect_seg_fault: + should_or_not = 'should' + else: + should_or_not = 'should not' + + has_seg_fault = Run(command) + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' % + (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command), + should_or_not)) + self.assert_(has_seg_fault == expect_seg_fault, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, + flag_value=None, + expect_seg_fault=0) + + def testEnvVar(self): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value=None, + expect_seg_fault=1) + + def testFlag(self): + """Tests using the --gtest_break_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + + def testFlagOverridesEnvVar(self): + """Tests that the flag overrides the environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='0', + flag_value='1', + expect_seg_fault=1) + self.RunAndVerify(env_var_value='1', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + + def testBreakOnFailureOverridesThrowOnFailure(self): + """Tests that gtest_break_on_failure overrides gtest_throw_on_failure.""" + + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None) + + if IS_WINDOWS: + def testCatchExceptionsDoesNotInterfere(self): + """Tests that gtest_catch_exceptions doesn't interfere.""" + + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-break-on-failure-unittest_.cc b/3rdparty/gtest/test/googletest-break-on-failure-unittest_.cc new file mode 100644 index 0000000..f84957a --- /dev/null +++ b/3rdparty/gtest/test/googletest-break-on-failure-unittest_.cc @@ -0,0 +1,86 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Unit test for Google Test's break-on-failure mode. +// +// A user can ask Google Test to seg-fault when an assertion fails, using +// either the GTEST_BREAK_ON_FAILURE environment variable or the +// --gtest_break_on_failure flag. This file is used for testing such +// functionality. +// +// This program will be invoked from a Python unit test. It is +// expected to fail. Don't run it directly. + +#include "gtest/gtest.h" + +#if GTEST_OS_WINDOWS +# include +# include +#endif + +namespace { + +// A test that's expected to fail. +TEST(Foo, Bar) { + EXPECT_EQ(2, 3); +} + +#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE +// On Windows Mobile global exception handlers are not supported. +LONG WINAPI ExitWithExceptionCode( + struct _EXCEPTION_POINTERS* exception_pointers) { + exit(exception_pointers->ExceptionRecord->ExceptionCode); +} +#endif + +} // namespace + +int main(int argc, char **argv) { +#if GTEST_OS_WINDOWS + // Suppresses display of the Windows error dialog upon encountering + // a general protection fault (segment violation). + SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); + +# if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE + + // The default unhandled exception filter does not always exit + // with the exception code as exit code - for example it exits with + // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT + // if the application is compiled in debug mode. Thus we use our own + // filter which always exits with the exception code for unhandled + // exceptions. + SetUnhandledExceptionFilter(ExitWithExceptionCode); + +# endif +#endif // GTEST_OS_WINDOWS + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/googletest-catch-exceptions-test.py b/3rdparty/gtest/test/googletest-catch-exceptions-test.py new file mode 100644 index 0000000..94a5b33 --- /dev/null +++ b/3rdparty/gtest/test/googletest-catch-exceptions-test.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python +# +# Copyright 2010 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests Google Test's exception catching behavior. + +This script invokes googletest-catch-exceptions-test_ and +googletest-catch-exceptions-ex-test_ (programs written with +Google Test) and verifies their output. +""" + +import gtest_test_utils + +# Constants. +FLAG_PREFIX = '--gtest_' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0' +FILTER_FLAG = FLAG_PREFIX + 'filter' + +# Path to the googletest-catch-exceptions-ex-test_ binary, compiled with +# exceptions enabled. +EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'googletest-catch-exceptions-ex-test_') + +# Path to the googletest-catch-exceptions-test_ binary, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'googletest-catch-exceptions-no-ex-test_') + +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) + +TEST_LIST = gtest_test_utils.Subprocess( + [EXE_PATH, LIST_TESTS_FLAG], env=environ).output + +SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST + +if SUPPORTS_SEH_EXCEPTIONS: + BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output + +EX_BINARY_OUTPUT = gtest_test_utils.Subprocess( + [EX_EXE_PATH], env=environ).output + + +# The tests. +if SUPPORTS_SEH_EXCEPTIONS: + # pylint:disable-msg=C6302 + class CatchSehExceptionsTest(gtest_test_utils.TestCase): + """Tests exception-catching behavior.""" + + + def TestSehExceptions(self, test_output): + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s constructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s destructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUpTestSuite()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDownTestSuite()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUp()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDown()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in the test body' + in test_output) + + def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): + self.TestSehExceptions(EX_BINARY_OUTPUT) + + def testCatchesSehExceptionsWithCxxExceptionsDisabled(self): + self.TestSehExceptions(BINARY_OUTPUT) + + +class CatchCxxExceptionsTest(gtest_test_utils.TestCase): + """Tests C++ exception-catching behavior. + + Tests in this test case verify that: + * C++ exceptions are caught and logged as C++ (not SEH) exceptions + * Exception thrown affect the remainder of the test work flow in the + expected manner. + """ + + def testCatchesCxxExceptionsInFixtureConstructor(self): + self.assertTrue( + 'C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s constructor' in EX_BINARY_OUTPUT, + EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInConstructorTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in + EX_BINARY_OUTPUT): + + def testCatchesCxxExceptionsInFixtureDestructor(self): + self.assertTrue( + 'C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s destructor' in EX_BINARY_OUTPUT, + EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInDestructorTest::TearDownTestSuite() ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUpTestCase(self): + self.assertTrue( + 'C++ exception with description "Standard C++ exception"' + ' thrown in SetUpTestSuite()' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInConstructorTest::TearDownTestSuite() ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInSetUpTestSuiteTest constructor ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInSetUpTestSuiteTest destructor ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInSetUpTestSuiteTest::SetUp() ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInSetUpTestSuiteTest::TearDown() ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInSetUpTestSuiteTest test body ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTearDownTestCase(self): + self.assertTrue( + 'C++ exception with description "Standard C++ exception"' + ' thrown in TearDownTestSuite()' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUp(self): + self.assertTrue( + 'C++ exception with description "Standard C++ exception"' + ' thrown in SetUp()' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInSetUpTest::TearDownTestSuite() ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInSetUpTest destructor ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInSetUpTest::TearDown() ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInSetUpTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + def testCatchesCxxExceptionsInTearDown(self): + self.assertTrue( + 'C++ exception with description "Standard C++ exception"' + ' thrown in TearDown()' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInTearDownTest::TearDownTestSuite() ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInTearDownTest destructor ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTestBody(self): + self.assertTrue( + 'C++ exception with description "Standard C++ exception"' + ' thrown in the test body' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInTestBodyTest::TearDownTestSuite() ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInTestBodyTest destructor ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + self.assertTrue( + 'CxxExceptionInTestBodyTest::TearDown() ' + 'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT) + + def testCatchesNonStdCxxExceptions(self): + self.assertTrue( + 'Unknown C++ exception thrown in the test body' in EX_BINARY_OUTPUT, + EX_BINARY_OUTPUT) + + def testUnhandledCxxExceptionsAbortTheProgram(self): + # Filters out SEH exception tests on Windows. Unhandled SEH exceptions + # cause tests to show pop-up windows there. + FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' + # By default, Google Test doesn't catch the exceptions. + uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( + [EX_EXE_PATH, + NO_CATCH_EXCEPTIONS_FLAG, + FITLER_OUT_SEH_TESTS_FLAG], + env=environ).output + + self.assert_('Unhandled C++ exception terminating the program' + in uncaught_exceptions_ex_binary_output) + self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-catch-exceptions-test_.cc b/3rdparty/gtest/test/googletest-catch-exceptions-test_.cc new file mode 100644 index 0000000..8c127d4 --- /dev/null +++ b/3rdparty/gtest/test/googletest-catch-exceptions-test_.cc @@ -0,0 +1,293 @@ +// Copyright 2010, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests for Google Test itself. Tests in this file throw C++ or SEH +// exceptions, and the output is verified by +// googletest-catch-exceptions-test.py. + +#include // NOLINT +#include // For exit(). + +#include "gtest/gtest.h" + +#if GTEST_HAS_SEH +# include +#endif + +#if GTEST_HAS_EXCEPTIONS +# include // For set_terminate(). +# include +#endif + +using testing::Test; + +#if GTEST_HAS_SEH + +class SehExceptionInConstructorTest : public Test { + public: + SehExceptionInConstructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInConstructorTest, ThrowsExceptionInConstructor) {} + +class SehExceptionInDestructorTest : public Test { + public: + ~SehExceptionInDestructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInDestructorTest, ThrowsExceptionInDestructor) {} + +class SehExceptionInSetUpTestSuiteTest : public Test { + public: + static void SetUpTestSuite() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTestSuiteTest, ThrowsExceptionInSetUpTestSuite) {} + +class SehExceptionInTearDownTestSuiteTest : public Test { + public: + static void TearDownTestSuite() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTestSuiteTest, + ThrowsExceptionInTearDownTestSuite) {} + +class SehExceptionInSetUpTest : public Test { + protected: + virtual void SetUp() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTest, ThrowsExceptionInSetUp) {} + +class SehExceptionInTearDownTest : public Test { + protected: + virtual void TearDown() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +TEST(SehExceptionTest, ThrowsSehException) { + RaiseException(42, 0, 0, NULL); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +class CxxExceptionInConstructorTest : public Test { + public: + CxxExceptionInConstructorTest() { + // Without this macro VC++ complains about unreachable code at the end of + // the constructor. + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } + + static void TearDownTestSuite() { + printf("%s", + "CxxExceptionInConstructorTest::TearDownTestSuite() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInConstructorTest() override { + ADD_FAILURE() << "CxxExceptionInConstructorTest destructor " + << "called unexpectedly."; + } + + void SetUp() override { + ADD_FAILURE() << "CxxExceptionInConstructorTest::SetUp() " + << "called unexpectedly."; + } + + void TearDown() override { + ADD_FAILURE() << "CxxExceptionInConstructorTest::TearDown() " + << "called unexpectedly."; + } +}; + +TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) { + ADD_FAILURE() << "CxxExceptionInConstructorTest test body " + << "called unexpectedly."; +} + +class CxxExceptionInSetUpTestSuiteTest : public Test { + public: + CxxExceptionInSetUpTestSuiteTest() { + printf("%s", + "CxxExceptionInSetUpTestSuiteTest constructor " + "called as expected.\n"); + } + + static void SetUpTestSuite() { + throw std::runtime_error("Standard C++ exception"); + } + + static void TearDownTestSuite() { + printf("%s", + "CxxExceptionInSetUpTestSuiteTest::TearDownTestSuite() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTestSuiteTest() override { + printf("%s", + "CxxExceptionInSetUpTestSuiteTest destructor " + "called as expected.\n"); + } + + void SetUp() override { + printf("%s", + "CxxExceptionInSetUpTestSuiteTest::SetUp() " + "called as expected.\n"); + } + + void TearDown() override { + printf("%s", + "CxxExceptionInSetUpTestSuiteTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTestSuiteTest, ThrowsExceptionInSetUpTestSuite) { + printf("%s", + "CxxExceptionInSetUpTestSuiteTest test body " + "called as expected.\n"); +} + +class CxxExceptionInTearDownTestSuiteTest : public Test { + public: + static void TearDownTestSuite() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTestSuiteTest, + ThrowsExceptionInTearDownTestSuite) {} + +class CxxExceptionInSetUpTest : public Test { + public: + static void TearDownTestSuite() { + printf("%s", + "CxxExceptionInSetUpTest::TearDownTestSuite() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTest() override { + printf("%s", + "CxxExceptionInSetUpTest destructor " + "called as expected.\n"); + } + + void SetUp() override { throw std::runtime_error("Standard C++ exception"); } + + void TearDown() override { + printf("%s", + "CxxExceptionInSetUpTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTest, ThrowsExceptionInSetUp) { + ADD_FAILURE() << "CxxExceptionInSetUpTest test body " + << "called unexpectedly."; +} + +class CxxExceptionInTearDownTest : public Test { + public: + static void TearDownTestSuite() { + printf("%s", + "CxxExceptionInTearDownTest::TearDownTestSuite() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTearDownTest() override { + printf("%s", + "CxxExceptionInTearDownTest destructor " + "called as expected.\n"); + } + + void TearDown() override { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +class CxxExceptionInTestBodyTest : public Test { + public: + static void TearDownTestSuite() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDownTestSuite() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTestBodyTest() override { + printf("%s", + "CxxExceptionInTestBodyTest destructor " + "called as expected.\n"); + } + + void TearDown() override { + printf("%s", + "CxxExceptionInTestBodyTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInTestBodyTest, ThrowsStdCxxException) { + throw std::runtime_error("Standard C++ exception"); +} + +TEST(CxxExceptionTest, ThrowsNonStdCxxException) { + throw "C-string"; +} + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(nullptr); + exit(3); +} + +#endif // GTEST_HAS_EXCEPTIONS + +int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/googletest-color-test.py b/3rdparty/gtest/test/googletest-color-test.py new file mode 100644 index 0000000..f3b7c99 --- /dev/null +++ b/3rdparty/gtest/test/googletest-color-test.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Verifies that Google Test correctly determines whether to use colors.""" + +import os +import gtest_test_utils + +IS_WINDOWS = os.name == 'nt' + +COLOR_ENV_VAR = 'GTEST_COLOR' +COLOR_FLAG = 'gtest_color' +COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-color-test_') + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def UsesColor(term, color_env_var, color_flag): + """Runs googletest-color-test_ and returns its exit code.""" + + SetEnvVar('TERM', term) + SetEnvVar(COLOR_ENV_VAR, color_env_var) + + if color_flag is None: + args = [] + else: + args = ['--%s=%s' % (COLOR_FLAG, color_flag)] + p = gtest_test_utils.Subprocess([COMMAND] + args) + return not p.exited or p.exit_code + + +class GTestColorTest(gtest_test_utils.TestCase): + def testNoEnvVarNoFlag(self): + """Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" + + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', None, None)) + self.assert_(not UsesColor('emacs', None, None)) + self.assert_(not UsesColor('xterm-mono', None, None)) + self.assert_(not UsesColor('unknown', None, None)) + self.assert_(not UsesColor(None, None, None)) + self.assert_(UsesColor('linux', None, None)) + self.assert_(UsesColor('cygwin', None, None)) + self.assert_(UsesColor('xterm', None, None)) + self.assert_(UsesColor('xterm-color', None, None)) + self.assert_(UsesColor('xterm-256color', None, None)) + + def testFlagOnly(self): + """Tests the case when there's --gtest_color but not GTEST_COLOR.""" + + self.assert_(not UsesColor('dumb', None, 'no')) + self.assert_(not UsesColor('xterm-color', None, 'no')) + if not IS_WINDOWS: + self.assert_(not UsesColor('emacs', None, 'auto')) + self.assert_(UsesColor('xterm', None, 'auto')) + self.assert_(UsesColor('dumb', None, 'yes')) + self.assert_(UsesColor('xterm', None, 'yes')) + + def testEnvVarOnly(self): + """Tests the case when there's GTEST_COLOR but not --gtest_color.""" + + self.assert_(not UsesColor('dumb', 'no', None)) + self.assert_(not UsesColor('xterm-color', 'no', None)) + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', 'auto', None)) + self.assert_(UsesColor('xterm-color', 'auto', None)) + self.assert_(UsesColor('dumb', 'yes', None)) + self.assert_(UsesColor('xterm-color', 'yes', None)) + + def testEnvVarAndFlag(self): + """Tests the case when there are both GTEST_COLOR and --gtest_color.""" + + self.assert_(not UsesColor('xterm-color', 'no', 'no')) + self.assert_(UsesColor('dumb', 'no', 'yes')) + self.assert_(UsesColor('xterm-color', 'no', 'auto')) + + def testAliasesOfYesAndNo(self): + """Tests using aliases in specifying --gtest_color.""" + + self.assert_(UsesColor('dumb', None, 'true')) + self.assert_(UsesColor('dumb', None, 'YES')) + self.assert_(UsesColor('dumb', None, 'T')) + self.assert_(UsesColor('dumb', None, '1')) + + self.assert_(not UsesColor('xterm', None, 'f')) + self.assert_(not UsesColor('xterm', None, 'false')) + self.assert_(not UsesColor('xterm', None, '0')) + self.assert_(not UsesColor('xterm', None, 'unknown')) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-color-test_.cc b/3rdparty/gtest/test/googletest-color-test_.cc new file mode 100644 index 0000000..220a3a0 --- /dev/null +++ b/3rdparty/gtest/test/googletest-color-test_.cc @@ -0,0 +1,62 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// A helper program for testing how Google Test determines whether to use +// colors in the output. It prints "YES" and returns 1 if Google Test +// decides to use colors, and prints "NO" and returns 0 otherwise. + +#include + +#include "gtest/gtest.h" +#include "src/gtest-internal-inl.h" + +using testing::internal::ShouldUseColor; + +// The purpose of this is to ensure that the UnitTest singleton is +// created before main() is entered, and thus that ShouldUseColor() +// works the same way as in a real Google-Test-based test. We don't actual +// run the TEST itself. +TEST(GTestColorTest, Dummy) { +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (ShouldUseColor(true)) { + // Google Test decides to use colors in the output (assuming it + // goes to a TTY). + printf("YES\n"); + return 1; + } else { + // Google Test decides not to use colors in the output. + printf("NO\n"); + return 0; + } +} diff --git a/3rdparty/gtest/test/googletest-death-test-test.cc b/3rdparty/gtest/test/googletest-death-test-test.cc new file mode 100644 index 0000000..cba906c --- /dev/null +++ b/3rdparty/gtest/test/googletest-death-test-test.cc @@ -0,0 +1,1516 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests for death tests. + +#include "gtest/gtest-death-test.h" + +#include "gtest/gtest.h" +#include "gtest/internal/gtest-filepath.h" + +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_WINDOWS +# include // For O_BINARY +# include // For chdir(). +# include +# else +# include +# include // For waitpid. +# endif // GTEST_OS_WINDOWS + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include "gtest/gtest-spi.h" +# include "src/gtest-internal-inl.h" + +namespace posix = ::testing::internal::posix; + +using testing::ContainsRegex; +using testing::Matcher; +using testing::Message; +using testing::internal::DeathTest; +using testing::internal::DeathTestFactory; +using testing::internal::FilePath; +using testing::internal::GetLastErrnoDescription; +using testing::internal::GetUnitTestImpl; +using testing::internal::InDeathTestChild; +using testing::internal::ParseNaturalNumber; + +namespace testing { +namespace internal { + +// A helper class whose objects replace the death test factory for a +// single UnitTest object during their lifetimes. +class ReplaceDeathTestFactory { + public: + explicit ReplaceDeathTestFactory(DeathTestFactory* new_factory) + : unit_test_impl_(GetUnitTestImpl()) { + old_factory_ = unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(new_factory); + } + + ~ReplaceDeathTestFactory() { + unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(old_factory_); + } + private: + // Prevents copying ReplaceDeathTestFactory objects. + ReplaceDeathTestFactory(const ReplaceDeathTestFactory&); + void operator=(const ReplaceDeathTestFactory&); + + UnitTestImpl* unit_test_impl_; + DeathTestFactory* old_factory_; +}; + +} // namespace internal +} // namespace testing + +namespace { + +void DieWithMessage(const ::std::string& message) { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); // Make sure the text is printed before the process exits. + + // We call _exit() instead of exit(), as the former is a direct + // system call and thus safer in the presence of threads. exit() + // will invoke user-defined exit-hooks, which may do dangerous + // things that conflict with death tests. + // + // Some compilers can recognize that _exit() never returns and issue the + // 'unreachable code' warning for code following this function, unless + // fooled by a fake condition. + if (AlwaysTrue()) + _exit(1); +} + +void DieInside(const ::std::string& function) { + DieWithMessage("death inside " + function + "()."); +} + +// Tests that death tests work. + +class TestForDeathTest : public testing::Test { + protected: + TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {} + + ~TestForDeathTest() override { posix::ChDir(original_dir_.c_str()); } + + // A static member function that's expected to die. + static void StaticMemberFunction() { DieInside("StaticMemberFunction"); } + + // A method of the test fixture that may die. + void MemberFunction() { + if (should_die_) + DieInside("MemberFunction"); + } + + // True if and only if MemberFunction() should die. + bool should_die_; + const FilePath original_dir_; +}; + +// A class with a member function that may die. +class MayDie { + public: + explicit MayDie(bool should_die) : should_die_(should_die) {} + + // A member function that may die. + void MemberFunction() const { + if (should_die_) + DieInside("MayDie::MemberFunction"); + } + + private: + // True if and only if MemberFunction() should die. + bool should_die_; +}; + +// A global function that's expected to die. +void GlobalFunction() { DieInside("GlobalFunction"); } + +// A non-void function that's expected to die. +int NonVoidFunction() { + DieInside("NonVoidFunction"); + return 1; +} + +// A unary function that may die. +void DieIf(bool should_die) { + if (should_die) + DieInside("DieIf"); +} + +// A binary function that may die. +bool DieIfLessThan(int x, int y) { + if (x < y) { + DieInside("DieIfLessThan"); + } + return true; +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +void DeathTestSubroutine() { + EXPECT_DEATH(GlobalFunction(), "death.*GlobalFunction"); + ASSERT_DEATH(GlobalFunction(), "death.*GlobalFunction"); +} + +// Death in dbg, not opt. +int DieInDebugElse12(int* sideeffect) { + if (sideeffect) *sideeffect = 12; + +# ifndef NDEBUG + + DieInside("DieInDebugElse12"); + +# endif // NDEBUG + + return 12; +} + +# if GTEST_OS_WINDOWS + +// Death in dbg due to Windows CRT assertion failure, not opt. +int DieInCRTDebugElse12(int* sideeffect) { + if (sideeffect) *sideeffect = 12; + + // Create an invalid fd by closing a valid one + int fdpipe[2]; + EXPECT_EQ(_pipe(fdpipe, 256, O_BINARY), 0); + EXPECT_EQ(_close(fdpipe[0]), 0); + EXPECT_EQ(_close(fdpipe[1]), 0); + + // _dup() should crash in debug mode + EXPECT_EQ(_dup(fdpipe[0]), -1); + + return 12; +} + +#endif // GTEST_OS_WINDOWS + +# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + // On Windows, the process's exit code is the same as its exit status, + // so the predicate just compares the its input with its parameter. + EXPECT_TRUE(testing::ExitedWithCode(0)(0)); + EXPECT_TRUE(testing::ExitedWithCode(1)(1)); + EXPECT_TRUE(testing::ExitedWithCode(42)(42)); + EXPECT_FALSE(testing::ExitedWithCode(0)(1)); + EXPECT_FALSE(testing::ExitedWithCode(1)(0)); +} + +# else + +// Returns the exit status of a process that calls _exit(2) with a +// given exit code. This is a helper function for the +// ExitStatusPredicateTest test suite. +static int NormalExitStatus(int exit_code) { + pid_t child_pid = fork(); + if (child_pid == 0) { + _exit(exit_code); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Returns the exit status of a process that raises a given signal. +// If the signal does not cause the process to die, then it returns +// instead the exit status of a process that exits normally with exit +// code 1. This is a helper function for the ExitStatusPredicateTest +// test suite. +static int KilledExitStatus(int signum) { + pid_t child_pid = fork(); + if (child_pid == 0) { + raise(signum); + _exit(1); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + const int status0 = NormalExitStatus(0); + const int status1 = NormalExitStatus(1); + const int status42 = NormalExitStatus(42); + const testing::ExitedWithCode pred0(0); + const testing::ExitedWithCode pred1(1); + const testing::ExitedWithCode pred42(42); + EXPECT_PRED1(pred0, status0); + EXPECT_PRED1(pred1, status1); + EXPECT_PRED1(pred42, status42); + EXPECT_FALSE(pred0(status1)); + EXPECT_FALSE(pred42(status0)); + EXPECT_FALSE(pred1(status42)); +} + +// Tests the KilledBySignal predicate. +TEST(ExitStatusPredicateTest, KilledBySignal) { + const int status_segv = KilledExitStatus(SIGSEGV); + const int status_kill = KilledExitStatus(SIGKILL); + const testing::KilledBySignal pred_segv(SIGSEGV); + const testing::KilledBySignal pred_kill(SIGKILL); + EXPECT_PRED1(pred_segv, status_segv); + EXPECT_PRED1(pred_kill, status_kill); + EXPECT_FALSE(pred_segv(status_kill)); + EXPECT_FALSE(pred_kill(status_segv)); +} + +# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA + +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +TEST_F(TestForDeathTest, SingleStatement) { + if (AlwaysFalse()) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH(return, ""); + + if (AlwaysTrue()) + EXPECT_DEATH(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; + + if (AlwaysFalse()) + ASSERT_DEATH(return, "") << "did not die"; + + if (AlwaysFalse()) + ; + else + EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3; +} + +# if GTEST_USES_PCRE + +void DieWithEmbeddedNul() { + fprintf(stderr, "Hello%cmy null world.\n", '\0'); + fflush(stderr); + _exit(1); +} + +// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error +// message has a NUL character in it. +TEST_F(TestForDeathTest, EmbeddedNulInMessage) { + EXPECT_DEATH(DieWithEmbeddedNul(), "my null world"); + ASSERT_DEATH(DieWithEmbeddedNul(), "my null world"); +} + +# endif // GTEST_USES_PCRE + +// Tests that death test macros expand to code which interacts well with switch +// statements. +TEST_F(TestForDeathTest, SwitchStatement) { + // Microsoft compiler usually complains about switch statements without + // case labels. We suppress that warning for this test. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065) + + switch (0) + default: + ASSERT_DEATH(_exit(1), "") << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH(_exit(1), "") << "exit in switch case"; + + GTEST_DISABLE_MSC_WARNINGS_POP_() +} + +// Tests that a static member function can be used in a "fast" style +// death test. +TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +// Tests that a method of the test fixture can be used in a "fast" +// style death test. +TEST_F(TestForDeathTest, MemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +void ChangeToRootDir() { posix::ChDir(GTEST_PATH_SEP_); } + +// Tests that death tests work even if the current directory has been +// changed. +TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "fast"; + + ChangeToRootDir(); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + ChangeToRootDir(); + ASSERT_DEATH(_exit(1), ""); +} + +# if GTEST_OS_LINUX +void SigprofAction(int, siginfo_t*, void*) { /* no op */ } + +// Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms). +void SetSigprofActionAndTimer() { + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 1; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, nullptr)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_sigaction = SigprofAction; + signal_action.sa_flags = SA_RESTART | SA_SIGINFO; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, nullptr)); +} + +// Disables ITIMER_PROF timer and ignores SIGPROF signal. +void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) { + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, nullptr)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_handler = SIG_IGN; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, old_signal_action)); +} + +// Tests that death tests work when SIGPROF handler and timer are set. +TEST_F(TestForDeathTest, FastSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "fast"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} + +TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} +# endif // GTEST_OS_LINUX + +// Repeats a representative sample of death tests in the "threadsafe" style: + +TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + for (int i = 0; i < 3; ++i) + EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i; +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + ChangeToRootDir(); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + ChangeToRootDir(); + ASSERT_DEATH(_exit(1), ""); +} + +TEST_F(TestForDeathTest, MixedStyles) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH(_exit(1), ""); + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(_exit(1), ""); +} + +# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD + +bool pthread_flag; + +void SetPthreadFlag() { + pthread_flag = true; +} + +TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { + if (!testing::GTEST_FLAG(death_test_use_fork)) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + pthread_flag = false; + ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, nullptr, nullptr)); + ASSERT_DEATH(_exit(1), ""); + ASSERT_FALSE(pthread_flag); + } +} + +# endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD + +// Tests that a method of another class can be used in a death test. +TEST_F(TestForDeathTest, MethodOfAnotherClass) { + const MayDie x(true); + ASSERT_DEATH(x.MemberFunction(), "MayDie\\:\\:MemberFunction"); +} + +// Tests that a global function can be used in a death test. +TEST_F(TestForDeathTest, GlobalFunction) { + EXPECT_DEATH(GlobalFunction(), "GlobalFunction"); +} + +// Tests that any value convertible to an RE works as a second +// argument to EXPECT_DEATH. +TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { + static const char regex_c_str[] = "GlobalFunction"; + EXPECT_DEATH(GlobalFunction(), regex_c_str); + + const testing::internal::RE regex(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex); + +# if !GTEST_USES_PCRE + + const ::std::string regex_std_str(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex_std_str); + + // This one is tricky; a temporary pointer into another temporary. Reference + // lifetime extension of the pointer is not sufficient. + EXPECT_DEATH(GlobalFunction(), ::std::string(regex_c_str).c_str()); + +# endif // !GTEST_USES_PCRE +} + +// Tests that a non-void function can be used in a death test. +TEST_F(TestForDeathTest, NonVoidFunction) { + ASSERT_DEATH(NonVoidFunction(), "NonVoidFunction"); +} + +// Tests that functions that take parameter(s) can be used in a death test. +TEST_F(TestForDeathTest, FunctionWithParameter) { + EXPECT_DEATH(DieIf(true), "DieIf\\(\\)"); + EXPECT_DEATH(DieIfLessThan(2, 3), "DieIfLessThan"); +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +TEST_F(TestForDeathTest, OutsideFixture) { + DeathTestSubroutine(); +} + +// Tests that death tests can be done inside a loop. +TEST_F(TestForDeathTest, InsideLoop) { + for (int i = 0; i < 5; i++) { + EXPECT_DEATH(DieIfLessThan(-1, i), "DieIfLessThan") << "where i == " << i; + } +} + +// Tests that a compound statement can be used in a death test. +TEST_F(TestForDeathTest, CompoundStatement) { + EXPECT_DEATH({ // NOLINT + const int x = 2; + const int y = x + 1; + DieIfLessThan(x, y); + }, + "DieIfLessThan"); +} + +// Tests that code that doesn't die causes a death test to fail. +TEST_F(TestForDeathTest, DoesNotDie) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(DieIf(false), "DieIf"), + "failed to die"); +} + +// Tests that a death test fails when the error message isn't expected. +TEST_F(TestForDeathTest, ErrorMessageMismatch) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(DieIf(true), "DieIfLessThan") << "End of death test message."; + }, "died but not with expected error"); +} + +// On exit, *aborted will be true if and only if the EXPECT_DEATH() +// statement aborted the function. +void ExpectDeathTestHelper(bool* aborted) { + *aborted = true; + EXPECT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + *aborted = false; +} + +// Tests that EXPECT_DEATH doesn't abort the test on failure. +TEST_F(TestForDeathTest, EXPECT_DEATH) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDeathTestHelper(&aborted), + "failed to die"); + EXPECT_FALSE(aborted); +} + +// Tests that ASSERT_DEATH does abort the test on failure. +TEST_F(TestForDeathTest, ASSERT_DEATH) { + static bool aborted; + EXPECT_FATAL_FAILURE({ // NOLINT + aborted = true; + ASSERT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + aborted = false; + }, "failed to die"); + EXPECT_TRUE(aborted); +} + +// Tests that EXPECT_DEATH evaluates the arguments exactly once. +TEST_F(TestForDeathTest, SingleEvaluation) { + int x = 3; + EXPECT_DEATH(DieIf((++x) == 4), "DieIf"); + + const char* regex = "DieIf"; + const char* regex_save = regex; + EXPECT_DEATH(DieIfLessThan(3, 4), regex++); + EXPECT_EQ(regex_save + 1, regex); +} + +// Tests that run-away death tests are reported as failures. +TEST_F(TestForDeathTest, RunawayIsFailure) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast(0), "Foo"), + "failed to die."); +} + +// Tests that death tests report executing 'return' in the statement as +// failure. +TEST_F(TestForDeathTest, ReturnIsFailure) { + EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"), + "illegal return in test statement."); +} + +// Tests that EXPECT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, TestExpectDebugDeath) { + int sideeffect = 0; + + // Put the regex in a local variable to make sure we don't get an "unused" + // warning in opt mode. + const char* regex = "death.*DieInDebugElse12"; + + EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), regex) + << "Must accept a streamed message"; + +# ifdef NDEBUG + + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); + +# else + + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); + +# endif +} + +# if GTEST_OS_WINDOWS + +// Tests that EXPECT_DEBUG_DEATH works as expected when in debug mode +// the Windows CRT crashes the process with an assertion failure. +// 1. Asserts on death. +// 2. Has no side effect (doesn't pop up a window or wait for user input). +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, CRTDebugDeath) { + int sideeffect = 0; + + // Put the regex in a local variable to make sure we don't get an "unused" + // warning in opt mode. + const char* regex = "dup.* : Assertion failed"; + + EXPECT_DEBUG_DEATH(DieInCRTDebugElse12(&sideeffect), regex) + << "Must accept a streamed message"; + +# ifdef NDEBUG + + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); + +# else + + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); + +# endif +} + +# endif // GTEST_OS_WINDOWS + +// Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, TestAssertDebugDeath) { + int sideeffect = 0; + + ASSERT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + << "Must accept a streamed message"; + +# ifdef NDEBUG + + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); + +# else + + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); + +# endif +} + +# ifndef NDEBUG + +void ExpectDebugDeathHelper(bool* aborted) { + *aborted = true; + EXPECT_DEBUG_DEATH(return, "") << "This is expected to fail."; + *aborted = false; +} + +# if GTEST_OS_WINDOWS +TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { + printf("This test should be considered failing if it shows " + "any pop-up dialogs.\n"); + fflush(stdout); + + EXPECT_DEATH({ + testing::GTEST_FLAG(catch_exceptions) = false; + abort(); + }, ""); +} +# endif // GTEST_OS_WINDOWS + +// Tests that EXPECT_DEBUG_DEATH in debug mode does not abort +// the function. +TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDebugDeathHelper(&aborted), ""); + EXPECT_FALSE(aborted); +} + +void AssertDebugDeathHelper(bool* aborted) { + *aborted = true; + GTEST_LOG_(INFO) << "Before ASSERT_DEBUG_DEATH"; + ASSERT_DEBUG_DEATH(GTEST_LOG_(INFO) << "In ASSERT_DEBUG_DEATH"; return, "") + << "This is expected to fail."; + GTEST_LOG_(INFO) << "After ASSERT_DEBUG_DEATH"; + *aborted = false; +} + +// Tests that ASSERT_DEBUG_DEATH in debug mode aborts the function on +// failure. +TEST_F(TestForDeathTest, AssertDebugDeathAborts) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts2) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts3) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts4) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts5) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts6) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts7) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts8) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts9) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts10) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +# endif // _NDEBUG + +// Tests the *_EXIT family of macros, using a variety of predicates. +static void TestExitMacros() { + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); + +# if GTEST_OS_WINDOWS + + // Of all signals effects on the process exit code, only those of SIGABRT + // are documented on Windows. + // See https://msdn.microsoft.com/en-us/query-bi/m/dwwzkt4c. + EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "") << "b_ar"; + +# elif !GTEST_OS_FUCHSIA + + // Fuchsia has no unix signals. + EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; + ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") + << "This failure is expected, too."; + }, "This failure is expected, too."); + +# endif // GTEST_OS_WINDOWS + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") + << "This failure is expected."; + }, "This failure is expected."); +} + +TEST_F(TestForDeathTest, ExitMacros) { + TestExitMacros(); +} + +TEST_F(TestForDeathTest, ExitMacrosUsingFork) { + testing::GTEST_FLAG(death_test_use_fork) = true; + TestExitMacros(); +} + +TEST_F(TestForDeathTest, InvalidStyle) { + testing::GTEST_FLAG(death_test_style) = "rococo"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(_exit(0), "") << "This failure is expected."; + }, "This failure is expected."); +} + +TEST_F(TestForDeathTest, DeathTestFailedOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("death\n"), + "expected message"), + "Actual msg:\n" + "[ DEATH ] death\n"); +} + +TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH({ + fprintf(stderr, "returning\n"); + fflush(stderr); + return; + }, ""), + " Result: illegal return in test statement.\n" + " Error msg:\n" + "[ DEATH ] returning\n"); +} + +TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"), + testing::ExitedWithCode(3), + "expected message"), + " Result: died but not with expected exit code:\n" + " Exited with exit status 1\n" + "Actual msg:\n" + "[ DEATH ] exiting with rc 1\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nxyz\nline 3\n"), + "Actual msg:\n" + "[ DEATH ] line 1\n" + "[ DEATH ] line 2\n" + "[ DEATH ] line 3\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nline 2\nline 3\n"); +} + +// A DeathTestFactory that returns MockDeathTests. +class MockDeathTestFactory : public DeathTestFactory { + public: + MockDeathTestFactory(); + bool Create(const char* statement, + testing::Matcher matcher, const char* file, + int line, DeathTest** test) override; + + // Sets the parameters for subsequent calls to Create. + void SetParameters(bool create, DeathTest::TestRole role, + int status, bool passed); + + // Accessors. + int AssumeRoleCalls() const { return assume_role_calls_; } + int WaitCalls() const { return wait_calls_; } + size_t PassedCalls() const { return passed_args_.size(); } + bool PassedArgument(int n) const { + return passed_args_[static_cast(n)]; + } + size_t AbortCalls() const { return abort_args_.size(); } + DeathTest::AbortReason AbortArgument(int n) const { + return abort_args_[static_cast(n)]; + } + bool TestDeleted() const { return test_deleted_; } + + private: + friend class MockDeathTest; + // If true, Create will return a MockDeathTest; otherwise it returns + // NULL. + bool create_; + // The value a MockDeathTest will return from its AssumeRole method. + DeathTest::TestRole role_; + // The value a MockDeathTest will return from its Wait method. + int status_; + // The value a MockDeathTest will return from its Passed method. + bool passed_; + + // Number of times AssumeRole was called. + int assume_role_calls_; + // Number of times Wait was called. + int wait_calls_; + // The arguments to the calls to Passed since the last call to + // SetParameters. + std::vector passed_args_; + // The arguments to the calls to Abort since the last call to + // SetParameters. + std::vector abort_args_; + // True if the last MockDeathTest returned by Create has been + // deleted. + bool test_deleted_; +}; + + +// A DeathTest implementation useful in testing. It returns values set +// at its creation from its various inherited DeathTest methods, and +// reports calls to those methods to its parent MockDeathTestFactory +// object. +class MockDeathTest : public DeathTest { + public: + MockDeathTest(MockDeathTestFactory *parent, + TestRole role, int status, bool passed) : + parent_(parent), role_(role), status_(status), passed_(passed) { + } + ~MockDeathTest() override { parent_->test_deleted_ = true; } + TestRole AssumeRole() override { + ++parent_->assume_role_calls_; + return role_; + } + int Wait() override { + ++parent_->wait_calls_; + return status_; + } + bool Passed(bool exit_status_ok) override { + parent_->passed_args_.push_back(exit_status_ok); + return passed_; + } + void Abort(AbortReason reason) override { + parent_->abort_args_.push_back(reason); + } + + private: + MockDeathTestFactory* const parent_; + const TestRole role_; + const int status_; + const bool passed_; +}; + + +// MockDeathTestFactory constructor. +MockDeathTestFactory::MockDeathTestFactory() + : create_(true), + role_(DeathTest::OVERSEE_TEST), + status_(0), + passed_(true), + assume_role_calls_(0), + wait_calls_(0), + passed_args_(), + abort_args_() { +} + + +// Sets the parameters for subsequent calls to Create. +void MockDeathTestFactory::SetParameters(bool create, + DeathTest::TestRole role, + int status, bool passed) { + create_ = create; + role_ = role; + status_ = status; + passed_ = passed; + + assume_role_calls_ = 0; + wait_calls_ = 0; + passed_args_.clear(); + abort_args_.clear(); +} + + +// Sets test to NULL (if create_ is false) or to the address of a new +// MockDeathTest object with parameters taken from the last call +// to SetParameters (if create_ is true). Always returns true. +bool MockDeathTestFactory::Create( + const char* /*statement*/, testing::Matcher /*matcher*/, + const char* /*file*/, int /*line*/, DeathTest** test) { + test_deleted_ = false; + if (create_) { + *test = new MockDeathTest(this, role_, status_, passed_); + } else { + *test = nullptr; + } + return true; +} + +// A test fixture for testing the logic of the GTEST_DEATH_TEST_ macro. +// It installs a MockDeathTestFactory that is used for the duration +// of the test case. +class MacroLogicDeathTest : public testing::Test { + protected: + static testing::internal::ReplaceDeathTestFactory* replacer_; + static MockDeathTestFactory* factory_; + + static void SetUpTestSuite() { + factory_ = new MockDeathTestFactory; + replacer_ = new testing::internal::ReplaceDeathTestFactory(factory_); + } + + static void TearDownTestSuite() { + delete replacer_; + replacer_ = nullptr; + delete factory_; + factory_ = nullptr; + } + + // Runs a death test that breaks the rules by returning. Such a death + // test cannot be run directly from a test routine that uses a + // MockDeathTest, or the remainder of the routine will not be executed. + static void RunReturningDeathTest(bool* flag) { + ASSERT_DEATH({ // NOLINT + *flag = true; + return; + }, ""); + } +}; + +testing::internal::ReplaceDeathTestFactory* MacroLogicDeathTest::replacer_ = + nullptr; +MockDeathTestFactory* MacroLogicDeathTest::factory_ = nullptr; + +// Test that nothing happens when the factory doesn't return a DeathTest: +TEST_F(MacroLogicDeathTest, NothingHappens) { + bool flag = false; + factory_->SetParameters(false, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(0, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0U, factory_->PassedCalls()); + EXPECT_EQ(0U, factory_->AbortCalls()); + EXPECT_FALSE(factory_->TestDeleted()); +} + +// Test that the parent process doesn't run the death test code, +// and that the Passed method returns false when the (simulated) +// child process exits with status 0: +TEST_F(MacroLogicDeathTest, ChildExitsSuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1U, factory_->PassedCalls()); + EXPECT_FALSE(factory_->PassedArgument(0)); + EXPECT_EQ(0U, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the Passed method was given the argument "true" when +// the (simulated) child process exits with status 1: +TEST_F(MacroLogicDeathTest, ChildExitsUnsuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 1, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1U, factory_->PassedCalls()); + EXPECT_TRUE(factory_->PassedArgument(0)); + EXPECT_EQ(0U, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process executes the death test +// code, and is aborted with the correct AbortReason if it +// executes a return statement. +TEST_F(MacroLogicDeathTest, ChildPerformsReturn) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + RunReturningDeathTest(&flag); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0U, factory_->PassedCalls()); + EXPECT_EQ(1U, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(0)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process is aborted with the +// correct AbortReason if it does not die. +TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0U, factory_->PassedCalls()); + // This time there are two calls to Abort: one since the test didn't + // die, and another from the ReturnSentinel when it's destroyed. The + // sentinel normally isn't destroyed if a test doesn't die, since + // _exit(2) is called in that case by ForkingDeathTest, but not by + // our MockDeathTest. + ASSERT_EQ(2U, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE, + factory_->AbortArgument(0)); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(1)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that a successful death test does not register a successful +// test part. +TEST(SuccessRegistrationDeathTest, NoSuccessPart) { + EXPECT_DEATH(_exit(1), ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +TEST(StreamingAssertionsDeathTest, DeathTest) { + EXPECT_DEATH(_exit(1), "") << "unexpected failure"; + ASSERT_DEATH(_exit(1), "") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(_exit(0), "") << "expected failure"; + }, "expected failure"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DEATH(_exit(0), "") << "expected failure"; + }, "expected failure"); +} + +// Tests that GetLastErrnoDescription returns an empty string when the +// last error is 0 and non-empty string when it is non-zero. +TEST(GetLastErrnoDescription, GetLastErrnoDescriptionWorks) { + errno = ENOENT; + EXPECT_STRNE("", GetLastErrnoDescription().c_str()); + errno = 0; + EXPECT_STREQ("", GetLastErrnoDescription().c_str()); +} + +# if GTEST_OS_WINDOWS +TEST(AutoHandleTest, AutoHandleWorks) { + HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + + // Tests that the AutoHandle is correctly initialized with a handle. + testing::internal::AutoHandle auto_handle(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that Reset assigns INVALID_HANDLE_VALUE. + // Note that this cannot verify whether the original handle is closed. + auto_handle.Reset(); + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle.Get()); + + // Tests that Reset assigns the new handle. + // Note that this cannot verify whether the original handle is closed. + handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + auto_handle.Reset(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that AutoHandle contains INVALID_HANDLE_VALUE by default. + testing::internal::AutoHandle auto_handle2; + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get()); +} +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_WINDOWS +typedef unsigned __int64 BiggestParsable; +typedef signed __int64 BiggestSignedParsable; +# else +typedef unsigned long long BiggestParsable; +typedef signed long long BiggestSignedParsable; +# endif // GTEST_OS_WINDOWS + +// We cannot use std::numeric_limits::max() as it clashes with the +// max() macro defined by . +const BiggestParsable kBiggestParsableMax = ULLONG_MAX; +const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; + +TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { + BiggestParsable result = 0; + + // Rejects non-numbers. + EXPECT_FALSE(ParseNaturalNumber("non-number string", &result)); + + // Rejects numbers with whitespace prefix. + EXPECT_FALSE(ParseNaturalNumber(" 123", &result)); + + // Rejects negative numbers. + EXPECT_FALSE(ParseNaturalNumber("-123", &result)); + + // Rejects numbers starting with a plus sign. + EXPECT_FALSE(ParseNaturalNumber("+123", &result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { + BiggestParsable result = 0; + + EXPECT_FALSE(ParseNaturalNumber("99999999999999999999999", &result)); + + signed char char_result = 0; + EXPECT_FALSE(ParseNaturalNumber("200", &char_result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { + BiggestParsable result = 0; + + result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &result)); + EXPECT_EQ(123U, result); + + // Check 0 as an edge case. + result = 1; + ASSERT_TRUE(ParseNaturalNumber("0", &result)); + EXPECT_EQ(0U, result); + + result = 1; + ASSERT_TRUE(ParseNaturalNumber("00000", &result)); + EXPECT_EQ(0U, result); +} + +TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { + Message msg; + msg << kBiggestParsableMax; + + BiggestParsable result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg.GetString(), &result)); + EXPECT_EQ(kBiggestParsableMax, result); + + Message msg2; + msg2 << kBiggestSignedParsableMax; + + BiggestSignedParsable signed_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg2.GetString(), &signed_result)); + EXPECT_EQ(kBiggestSignedParsableMax, signed_result); + + Message msg3; + msg3 << INT_MAX; + + int int_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg3.GetString(), &int_result)); + EXPECT_EQ(INT_MAX, int_result); + + Message msg4; + msg4 << UINT_MAX; + + unsigned int uint_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg4.GetString(), &uint_result)); + EXPECT_EQ(UINT_MAX, uint_result); +} + +TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { + short short_result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &short_result)); + EXPECT_EQ(123, short_result); + + signed char char_result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &char_result)); + EXPECT_EQ(123, char_result); +} + +# if GTEST_OS_WINDOWS +TEST(EnvironmentTest, HandleFitsIntoSizeT) { + ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t)); +} +# endif // GTEST_OS_WINDOWS + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger +// failures when death tests are available on the system. +TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { + EXPECT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestExpectMacro"), + "death inside CondDeathTestExpectMacro"); + ASSERT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestAssertMacro"), + "death inside CondDeathTestAssertMacro"); + + // Empty statement will not crash, which must trigger a failure. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), ""); + EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), ""); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +void DieWithMessage(const char* message) { + fputs(message, stderr); + fflush(stderr); // Make sure the text is printed before the process exits. + _exit(1); +} + +TEST(MatcherDeathTest, DoesNotBreakBareRegexMatching) { + // googletest tests this, of course; here we ensure that including googlemock + // has not broken it. + EXPECT_DEATH(DieWithMessage("O, I die, Horatio."), "I d[aeiou]e"); +} + +TEST(MatcherDeathTest, MonomorphicMatcherMatches) { + EXPECT_DEATH(DieWithMessage("Behind O, I am slain!"), + Matcher(ContainsRegex("I am slain"))); +} + +TEST(MatcherDeathTest, MonomorphicMatcherDoesNotMatch) { + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH( + DieWithMessage("Behind O, I am slain!"), + Matcher(ContainsRegex("Ow, I am slain"))), + "Expected: contains regular expression \"Ow, I am slain\""); +} + +TEST(MatcherDeathTest, PolymorphicMatcherMatches) { + EXPECT_DEATH(DieWithMessage("The rest is silence."), + ContainsRegex("rest is silence")); +} + +TEST(MatcherDeathTest, PolymorphicMatcherDoesNotMatch) { + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("The rest is silence."), + ContainsRegex("rest is science")), + "Expected: contains regular expression \"rest is science\""); +} + +} // namespace + +#else // !GTEST_HAS_DEATH_TEST follows + +namespace { + +using testing::internal::CaptureStderr; +using testing::internal::GetCapturedStderr; + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still +// defined but do not trigger failures when death tests are not available on +// the system. +TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { + // Empty statement will not crash, but that should not trigger a failure + // when death tests are not supported. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, ""); + std::string output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + // The streamed message should not be printed as there is no test failure. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, ""); // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); +} + +void FuncWithAssert(int* n) { + ASSERT_DEATH_IF_SUPPORTED(return;, ""); + (*n)++; +} + +// Tests that ASSERT_DEATH_IF_SUPPORTED does not return from the current +// function (as ASSERT_DEATH does) if death tests are not supported. +TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { + int n = 0; + FuncWithAssert(&n); + EXPECT_EQ(1, n); +} + +} // namespace + +#endif // !GTEST_HAS_DEATH_TEST + +namespace { + +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +// +// The syntax should work whether death tests are available or not. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { + if (AlwaysFalse()) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH_IF_SUPPORTED(return, ""); + + if (AlwaysTrue()) + EXPECT_DEATH_IF_SUPPORTED(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die"; + + if (AlwaysFalse()) + ; // NOLINT + else + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3; +} + +// Tests that conditional death test macros expand to code which interacts +// well with switch statements. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { + // Microsoft compiler usually complains about switch statements without + // case labels. We suppress that warning for this test. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065) + + switch (0) + default: + ASSERT_DEATH_IF_SUPPORTED(_exit(1), "") + << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; + + GTEST_DISABLE_MSC_WARNINGS_POP_() +} + +// Tests that a test case whose name ends with "DeathTest" works fine +// on Windows. +TEST(NotADeathTest, Test) { + SUCCEED(); +} + +} // namespace diff --git a/3rdparty/gtest/test/googletest-death-test_ex_test.cc b/3rdparty/gtest/test/googletest-death-test_ex_test.cc new file mode 100644 index 0000000..7ea5b94 --- /dev/null +++ b/3rdparty/gtest/test/googletest-death-test_ex_test.cc @@ -0,0 +1,92 @@ +// Copyright 2010, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests that verify interaction of exceptions and death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_HAS_SEH +# include // For RaiseException(). +# endif + +# include "gtest/gtest-spi.h" + +# if GTEST_HAS_EXCEPTIONS + +# include // For std::exception. + +// Tests that death tests report thrown exceptions as failures and that the +// exceptions do not escape death test macros. +TEST(CxxExceptionDeathTest, ExceptionIsFailure) { + try { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw 1, ""), "threw an exception"); + } catch (...) { // NOLINT + FAIL() << "An exception escaped a death test macro invocation " + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); + } +} + +class TestException : public std::exception { + public: + const char* what() const throw() override { return "exceptional message"; } +}; + +TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) { + // Verifies that the exception message is quoted in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + "exceptional message"); + // Verifies that the location is mentioned in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + __FILE__); +} +# endif // GTEST_HAS_EXCEPTIONS + +# if GTEST_HAS_SEH +// Tests that enabling interception of SEH exceptions with the +// catch_exceptions flag does not interfere with SEH exceptions being +// treated as death by death tests. +TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) { + EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "") + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); +} +# endif + +#endif // GTEST_HAS_DEATH_TEST + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0; + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/googletest-env-var-test.py b/3rdparty/gtest/test/googletest-env-var-test.py new file mode 100644 index 0000000..2f0e406 --- /dev/null +++ b/3rdparty/gtest/test/googletest-env-var-test.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Verifies that Google Test correctly parses environment variables.""" + +import os +import gtest_test_utils + + +IS_WINDOWS = os.name == 'nt' +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' + +COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-env-var-test_') + +environ = os.environ.copy() + + +def AssertEq(expected, actual): + if expected != actual: + print('Expected: %s' % (expected,)) + print(' Actual: %s' % (actual,)) + raise AssertionError + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def GetFlag(flag): + """Runs googletest-env-var-test_ and returns its output.""" + + args = [COMMAND] + if flag is not None: + args += [flag] + return gtest_test_utils.Subprocess(args, env=environ).output + + +def TestFlag(flag, test_val, default_val): + """Verifies that the given flag is affected by the corresponding env var.""" + + env_var = 'GTEST_' + flag.upper() + SetEnvVar(env_var, test_val) + AssertEq(test_val, GetFlag(flag)) + SetEnvVar(env_var, None) + AssertEq(default_val, GetFlag(flag)) + + +class GTestEnvVarTest(gtest_test_utils.TestCase): + + def testEnvVarAffectsFlag(self): + """Tests that environment variable should affect the corresponding flag.""" + + TestFlag('break_on_failure', '1', '0') + TestFlag('color', 'yes', 'auto') + TestFlag('filter', 'FooTest.Bar', '*') + SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test + TestFlag('output', 'xml:tmp/foo.xml', '') + TestFlag('print_time', '0', '1') + TestFlag('repeat', '999', '1') + TestFlag('throw_on_failure', '1', '0') + TestFlag('death_test_style', 'threadsafe', 'fast') + TestFlag('catch_exceptions', '0', '1') + + if IS_LINUX: + TestFlag('death_test_use_fork', '1', '0') + TestFlag('stack_trace_depth', '0', '100') + + + def testXmlOutputFile(self): + """Tests that $XML_OUTPUT_FILE affects the output flag.""" + + SetEnvVar('GTEST_OUTPUT', None) + SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml') + AssertEq('xml:tmp/bar.xml', GetFlag('output')) + + def testXmlOutputFileOverride(self): + """Tests that $XML_OUTPUT_FILE is overridden by $GTEST_OUTPUT.""" + + SetEnvVar('GTEST_OUTPUT', 'xml:tmp/foo.xml') + SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml') + AssertEq('xml:tmp/foo.xml', GetFlag('output')) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-env-var-test_.cc b/3rdparty/gtest/test/googletest-env-var-test_.cc new file mode 100644 index 0000000..fd2aa82 --- /dev/null +++ b/3rdparty/gtest/test/googletest-env-var-test_.cc @@ -0,0 +1,122 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// A helper program for testing that Google Test parses the environment +// variables correctly. + +#include + +#include "gtest/gtest.h" +#include "src/gtest-internal-inl.h" + +using ::std::cout; + +namespace testing { + +// The purpose of this is to make the test more realistic by ensuring +// that the UnitTest singleton is created before main() is entered. +// We don't actual run the TEST itself. +TEST(GTestEnvVarTest, Dummy) { +} + +void PrintFlag(const char* flag) { + if (strcmp(flag, "break_on_failure") == 0) { + cout << GTEST_FLAG(break_on_failure); + return; + } + + if (strcmp(flag, "catch_exceptions") == 0) { + cout << GTEST_FLAG(catch_exceptions); + return; + } + + if (strcmp(flag, "color") == 0) { + cout << GTEST_FLAG(color); + return; + } + + if (strcmp(flag, "death_test_style") == 0) { + cout << GTEST_FLAG(death_test_style); + return; + } + + if (strcmp(flag, "death_test_use_fork") == 0) { + cout << GTEST_FLAG(death_test_use_fork); + return; + } + + if (strcmp(flag, "filter") == 0) { + cout << GTEST_FLAG(filter); + return; + } + + if (strcmp(flag, "output") == 0) { + cout << GTEST_FLAG(output); + return; + } + + if (strcmp(flag, "print_time") == 0) { + cout << GTEST_FLAG(print_time); + return; + } + + if (strcmp(flag, "repeat") == 0) { + cout << GTEST_FLAG(repeat); + return; + } + + if (strcmp(flag, "stack_trace_depth") == 0) { + cout << GTEST_FLAG(stack_trace_depth); + return; + } + + if (strcmp(flag, "throw_on_failure") == 0) { + cout << GTEST_FLAG(throw_on_failure); + return; + } + + cout << "Invalid flag name " << flag + << ". Valid names are break_on_failure, color, filter, etc.\n"; + exit(1); +} + +} // namespace testing + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (argc != 2) { + cout << "Usage: googletest-env-var-test_ NAME_OF_FLAG\n"; + return 1; + } + + testing::PrintFlag(argv[1]); + return 0; +} diff --git a/3rdparty/gtest/test/googletest-filepath-test.cc b/3rdparty/gtest/test/googletest-filepath-test.cc new file mode 100644 index 0000000..aafad36 --- /dev/null +++ b/3rdparty/gtest/test/googletest-filepath-test.cc @@ -0,0 +1,649 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Google Test filepath utilities +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest-internal.h. +// Do not #include this file anywhere else! + +#include "gtest/internal/gtest-filepath.h" +#include "gtest/gtest.h" +#include "src/gtest-internal-inl.h" + +#if GTEST_OS_WINDOWS_MOBILE +# include // NOLINT +#elif GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS_MOBILE + +namespace testing { +namespace internal { +namespace { + +#if GTEST_OS_WINDOWS_MOBILE + +// Windows CE doesn't have the remove C function. +int remove(const char* path) { + LPCWSTR wpath = String::AnsiToUtf16(path); + int ret = DeleteFile(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} +// Windows CE doesn't have the _rmdir C function. +int _rmdir(const char* path) { + FilePath filepath(path); + LPCWSTR wpath = String::AnsiToUtf16( + filepath.RemoveTrailingPathSeparator().c_str()); + int ret = RemoveDirectory(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} + +#else + +TEST(GetCurrentDirTest, ReturnsCurrentDir) { + const FilePath original_dir = FilePath::GetCurrentDir(); + EXPECT_FALSE(original_dir.IsEmpty()); + + posix::ChDir(GTEST_PATH_SEP_); + const FilePath cwd = FilePath::GetCurrentDir(); + posix::ChDir(original_dir.c_str()); + +# if GTEST_OS_WINDOWS || GTEST_OS_OS2 + + // Skips the ":". + const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); + ASSERT_TRUE(cwd_without_drive != NULL); + EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1); + +# else + + EXPECT_EQ(GTEST_PATH_SEP_, cwd.string()); + +# endif +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { + EXPECT_TRUE(FilePath("").IsEmpty()); +} + +TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { + EXPECT_FALSE(FilePath("a").IsEmpty()); + EXPECT_FALSE(FilePath(".").IsEmpty()); + EXPECT_FALSE(FilePath("a/b").IsEmpty()); + EXPECT_FALSE(FilePath("a\\b\\").IsEmpty()); +} + +// RemoveDirectoryName "" -> "" +TEST(RemoveDirectoryNameTest, WhenEmptyName) { + EXPECT_EQ("", FilePath("").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "afile" -> "afile" +TEST(RemoveDirectoryNameTest, ButNoDirectory) { + EXPECT_EQ("afile", + FilePath("afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "/afile" -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) { + EXPECT_EQ("afile", + FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/" -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) { + EXPECT_EQ("", + FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileName) { + EXPECT_EQ("afile", + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/subdir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { + EXPECT_EQ("afile", + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") + .RemoveDirectoryName().string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that RemoveDirectoryName() works with the alternate separator +// on Windows. + +// RemoveDirectoryName("/afile") -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", FilePath("/afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/") -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) { + EXPECT_EQ("", FilePath("adir/").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/afile") -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", FilePath("adir/afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/subdir/afile") -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", + FilePath("adir/subdir/afile").RemoveDirectoryName().string()); +} + +#endif + +// RemoveFileName "" -> "./" +TEST(RemoveFileNameTest, EmptyName) { +#if GTEST_OS_WINDOWS_MOBILE + // On Windows CE, we use the root as the current directory. + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); +#else + EXPECT_EQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); +#endif +} + +// RemoveFileName "adir/" -> "adir/" +TEST(RemoveFileNameTest, ButNoFile) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().string()); +} + +// RemoveFileName "adir/afile" -> "adir/" +TEST(RemoveFileNameTest, GivesDirName) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveFileName().string()); +} + +// RemoveFileName "adir/subdir/afile" -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirName) { + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") + .RemoveFileName().string()); +} + +// RemoveFileName "/afile" -> "/" +TEST(RemoveFileNameTest, GivesRootDir) { + EXPECT_EQ(GTEST_PATH_SEP_, + FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that RemoveFileName() works with the alternate separator on +// Windows. + +// RemoveFileName("adir/") -> "adir/" +TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/").RemoveFileName().string()); +} + +// RemoveFileName("adir/afile") -> "adir/" +TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/afile").RemoveFileName().string()); +} + +// RemoveFileName("adir/subdir/afile") -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir/subdir/afile").RemoveFileName().string()); +} + +// RemoveFileName("/afile") -> "\" +TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("/afile").RemoveFileName().string()); +} + +#endif + +TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 0, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 12, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar"), 0, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar"), 12, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 0, "xml"); + EXPECT_EQ("bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 14, "xml"); + EXPECT_EQ("bar_14.xml", actual.string()); +} + +TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, Path1BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("bar.xml")); + EXPECT_EQ("bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, Path2BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("")); + EXPECT_EQ("foo" GTEST_PATH_SEP_, actual.string()); +} + +TEST(ConcatPathsTest, BothPathBeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("")); + EXPECT_EQ("", actual.string()); +} + +TEST(ConcatPathsTest, Path1ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"), + FilePath("foobar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml", + actual.string()); +} + +TEST(ConcatPathsTest, Path2ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths( + FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar" GTEST_PATH_SEP_ "bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml", + actual.string()); +} + +TEST(ConcatPathsTest, Path2EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar" GTEST_PATH_SEP_)); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.string()); +} + +// RemoveTrailingPathSeparator "" -> "" +TEST(RemoveTrailingPathSeparatorTest, EmptyString) { + EXPECT_EQ("", FilePath("").RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) { + EXPECT_EQ("foo", FilePath("foo").RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo/" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { + EXPECT_EQ("foo", + FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().string()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_EQ("foo", FilePath("foo/").RemoveTrailingPathSeparator().string()); +#endif +} + +// RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_) + .RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo/bar" -> "foo/bar" +TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar") + .RemoveTrailingPathSeparator().string()); +} + +TEST(DirectoryTest, RootDirectoryExists) { +#if GTEST_OS_WINDOWS // We are on Windows. + char current_drive[_MAX_PATH]; // NOLINT + current_drive[0] = static_cast(_getdrive() + 'A' - 1); + current_drive[1] = ':'; + current_drive[2] = '\\'; + current_drive[3] = '\0'; + EXPECT_TRUE(FilePath(current_drive).DirectoryExists()); +#else + EXPECT_TRUE(FilePath("/").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +#if GTEST_OS_WINDOWS +TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { + const int saved_drive_ = _getdrive(); + // Find a drive that doesn't exist. Start with 'Z' to avoid common ones. + for (char drive = 'Z'; drive >= 'A'; drive--) + if (_chdrive(drive - 'A' + 1) == -1) { + char non_drive[_MAX_PATH]; // NOLINT + non_drive[0] = drive; + non_drive[1] = ':'; + non_drive[2] = '\\'; + non_drive[3] = '\0'; + EXPECT_FALSE(FilePath(non_drive).DirectoryExists()); + break; + } + _chdrive(saved_drive_); +} +#endif // GTEST_OS_WINDOWS + +#if !GTEST_OS_WINDOWS_MOBILE +// Windows CE _does_ consider an empty directory to exist. +TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { + EXPECT_FALSE(FilePath("").DirectoryExists()); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +TEST(DirectoryTest, CurrentDirectoryExists) { +#if GTEST_OS_WINDOWS // We are on Windows. +# ifndef _WIN32_CE // Windows CE doesn't have a current directory. + + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath(".\\").DirectoryExists()); + +# endif // _WIN32_CE +#else + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath("./").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +// "foo/bar" == foo//bar" == "foo///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ + GTEST_PATH_SEP_ "bar").string()); +} + +// "/bar" == //bar" == "///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); +} + +// "foo/" == foo//" == "foo///" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that separators at the end of the string are normalized +// regardless of their combination (e.g. "foo\" =="foo/\" == +// "foo\\/"). +TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) { + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ "/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo//" GTEST_PATH_SEP_).string()); +} + +#endif + +TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { + FilePath default_path; + FilePath non_default_path("path"); + non_default_path = default_path; + EXPECT_EQ("", non_default_path.string()); + EXPECT_EQ("", default_path.string()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) { + FilePath non_default_path("path"); + FilePath default_path; + default_path = non_default_path; + EXPECT_EQ("path", default_path.string()); + EXPECT_EQ("path", non_default_path.string()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, ConstAssignedToNonConst) { + const FilePath const_default_path("const_path"); + FilePath non_default_path("path"); + non_default_path = const_default_path; + EXPECT_EQ("const_path", non_default_path.string()); +} + +class DirectoryCreationTest : public Test { + protected: + void SetUp() override { + testdata_path_.Set(FilePath( + TempDir() + GetCurrentExecutableName().string() + + "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_)); + testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator()); + + unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 0, "txt")); + unique_file1_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 1, "txt")); + + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); + posix::RmDir(testdata_path_.c_str()); + } + + void TearDown() override { + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); + posix::RmDir(testdata_path_.c_str()); + } + + void CreateTextFile(const char* filename) { + FILE* f = posix::FOpen(filename, "w"); + fprintf(f, "text\n"); + fclose(f); + } + + // Strings representing a directory and a file, with identical paths + // except for the trailing separator character that distinquishes + // a directory named 'test' from a file named 'test'. Example names: + FilePath testdata_path_; // "/tmp/directory_creation/test/" + FilePath testdata_file_; // "/tmp/directory_creation/test" + FilePath unique_file0_; // "/tmp/directory_creation/test/unique.txt" + FilePath unique_file1_; // "/tmp/directory_creation/test/unique_1.txt" +}; + +TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + EXPECT_TRUE(testdata_path_.DirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + // Call 'create' again... should still succeed. + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) { + FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_EQ(unique_file0_.string(), file_path.string()); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there + + testdata_path_.CreateDirectoriesRecursively(); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file still not there + CreateTextFile(file_path.c_str()); + EXPECT_TRUE(file_path.FileOrDirectoryExists()); + + FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_EQ(unique_file1_.string(), file_path2.string()); + EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there + CreateTextFile(file_path2.c_str()); + EXPECT_TRUE(file_path2.FileOrDirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesFail) { + // force a failure by putting a file where we will try to create a directory. + CreateTextFile(testdata_file_.c_str()); + EXPECT_TRUE(testdata_file_.FileOrDirectoryExists()); + EXPECT_FALSE(testdata_file_.DirectoryExists()); + EXPECT_FALSE(testdata_file_.CreateDirectoriesRecursively()); +} + +TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) { + const FilePath test_detail_xml("test_detail.xml"); + EXPECT_FALSE(test_detail_xml.CreateDirectoriesRecursively()); +} + +TEST(FilePathTest, DefaultConstructor) { + FilePath fp; + EXPECT_EQ("", fp.string()); +} + +TEST(FilePathTest, CharAndCopyConstructors) { + const FilePath fp("spicy"); + EXPECT_EQ("spicy", fp.string()); + + const FilePath fp_copy(fp); + EXPECT_EQ("spicy", fp_copy.string()); +} + +TEST(FilePathTest, StringConstructor) { + const FilePath fp(std::string("cider")); + EXPECT_EQ("cider", fp.string()); +} + +TEST(FilePathTest, Set) { + const FilePath apple("apple"); + FilePath mac("mac"); + mac.Set(apple); // Implement Set() since overloading operator= is forbidden. + EXPECT_EQ("apple", mac.string()); + EXPECT_EQ("apple", apple.string()); +} + +TEST(FilePathTest, ToString) { + const FilePath file("drink"); + EXPECT_EQ("drink", file.string()); +} + +TEST(FilePathTest, RemoveExtension) { + EXPECT_EQ("app", FilePath("app.cc").RemoveExtension("cc").string()); + EXPECT_EQ("app", FilePath("app.exe").RemoveExtension("exe").string()); + EXPECT_EQ("APP", FilePath("APP.EXE").RemoveExtension("exe").string()); +} + +TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { + EXPECT_EQ("app", FilePath("app").RemoveExtension("exe").string()); +} + +TEST(FilePathTest, IsDirectory) { + EXPECT_FALSE(FilePath("cola").IsDirectory()); + EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_TRUE(FilePath("koala/").IsDirectory()); +#endif +} + +TEST(FilePathTest, IsAbsolutePath) { + EXPECT_FALSE(FilePath("is" GTEST_PATH_SEP_ "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("").IsAbsolutePath()); +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath()); + EXPECT_TRUE(FilePath("c:/" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); +#else + EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative") + .IsAbsolutePath()); +#endif // GTEST_OS_WINDOWS +} + +TEST(FilePathTest, IsRootDirectory) { +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("a:\\").IsRootDirectory()); + EXPECT_TRUE(FilePath("Z:/").IsRootDirectory()); + EXPECT_TRUE(FilePath("e://").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:a").IsRootDirectory()); + EXPECT_FALSE(FilePath("8:/").IsRootDirectory()); + EXPECT_FALSE(FilePath("c|/").IsRootDirectory()); +#else + EXPECT_TRUE(FilePath("/").IsRootDirectory()); + EXPECT_TRUE(FilePath("//").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("\\").IsRootDirectory()); + EXPECT_FALSE(FilePath("/x").IsRootDirectory()); +#endif +} + +} // namespace +} // namespace internal +} // namespace testing diff --git a/3rdparty/gtest/test/googletest-filter-unittest.py b/3rdparty/gtest/test/googletest-filter-unittest.py new file mode 100644 index 0000000..6b32f2d --- /dev/null +++ b/3rdparty/gtest/test/googletest-filter-unittest.py @@ -0,0 +1,639 @@ +#!/usr/bin/env python +# +# Copyright 2005 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test for Google Test test filters. + +A user can specify which test(s) in a Google Test program to run via either +the GTEST_FILTER environment variable or the --gtest_filter flag. +This script tests such functionality by invoking +googletest-filter-unittest_ (a program written with Google Test) with different +environments and command line flags. + +Note that test sharding may also influence which tests are filtered. Therefore, +we test that here also. +""" + +import os +import re +try: + from sets import Set as set # For Python 2.3 compatibility +except ImportError: + pass +import sys +import gtest_test_utils + +# Constants. + +# Checks if this platform can pass empty environment variables to child +# processes. We set an env variable to an empty string and invoke a python +# script in a subprocess to print whether the variable is STILL in +# os.environ. We then use 'eval' to parse the child's output so that an +# exception is thrown if the input is anything other than 'True' nor 'False'. +CAN_PASS_EMPTY_ENV = False +if sys.executable: + os.environ['EMPTY_VAR'] = '' + child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print(\'EMPTY_VAR\' in os.environ)']) + CAN_PASS_EMPTY_ENV = eval(child.output) + + +# Check if this platform can unset environment variables in child processes. +# We set an env variable to a non-empty string, unset it, and invoke +# a python script in a subprocess to print whether the variable +# is NO LONGER in os.environ. +# We use 'eval' to parse the child's output so that an exception +# is thrown if the input is neither 'True' nor 'False'. +CAN_UNSET_ENV = False +if sys.executable: + os.environ['UNSET_VAR'] = 'X' + del os.environ['UNSET_VAR'] + child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print(\'UNSET_VAR\' not in os.environ)' + ]) + CAN_UNSET_ENV = eval(child.output) + + +# Checks if we should test with an empty filter. This doesn't +# make sense on platforms that cannot pass empty env variables (Win32) +# and on platforms that cannot unset variables (since we cannot tell +# the difference between "" and NULL -- Borland and Solaris < 5.10) +CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV) + + +# The environment variable for specifying the test filters. +FILTER_ENV_VAR = 'GTEST_FILTER' + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' +SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' + +# The command line flag for specifying the test filters. +FILTER_FLAG = 'gtest_filter' + +# The command line flag for including disabled tests. +ALSO_RUN_DISABLED_TESTS_FLAG = 'gtest_also_run_disabled_tests' + +# Command to run the googletest-filter-unittest_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-filter-unittest_') + +# Regex for determining whether parameterized tests are enabled in the binary. +PARAM_TEST_REGEX = re.compile(r'/ParamTest') + +# Regex for parsing test case names from Google Test's output. +TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)') + +# Regex for parsing test names from Google Test's output. +TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)') + +# The command line flag to tell Google Test to output the list of tests it +# will run. +LIST_TESTS_FLAG = '--gtest_list_tests' + +# Indicates whether Google Test supports death tests. +SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess( + [COMMAND, LIST_TESTS_FLAG]).output + +# Full names of all tests in googletest-filter-unittests_. +PARAM_TESTS = [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestX/1', + 'SeqQ/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestY/1', + ] + +DISABLED_TESTS = [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ] + +if SUPPORTS_DEATH_TESTS: + DEATH_TESTS = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + ] +else: + DEATH_TESTS = [] + +# All the non-disabled tests. +ACTIVE_TESTS = [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', + ] + DEATH_TESTS + PARAM_TESTS + +param_tests_present = None + +# Utilities. + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def RunAndReturnOutput(args = None): + """Runs the test program and returns its output.""" + + return gtest_test_utils.Subprocess([COMMAND] + (args or []), + env=environ).output + + +def RunAndExtractTestList(args = None): + """Runs the test program and returns its exit code and a list of tests run.""" + + p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ) + tests_run = [] + test_case = '' + test = '' + for line in p.output.split('\n'): + match = TEST_CASE_REGEX.match(line) + if match is not None: + test_case = match.group(1) + else: + match = TEST_REGEX.match(line) + if match is not None: + test = match.group(1) + tests_run.append(test_case + '.' + test) + return (tests_run, p.exit_code) + + +def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs): + """Runs the given function and arguments in a modified environment.""" + try: + original_env = environ.copy() + environ.update(extra_env) + return function(*args, **kwargs) + finally: + environ.clear() + environ.update(original_env) + + +def RunWithSharding(total_shards, shard_index, command): + """Runs a test program shard and returns exit code and a list of tests run.""" + + extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index), + TOTAL_SHARDS_ENV_VAR: str(total_shards)} + return InvokeWithModifiedEnv(extra_env, RunAndExtractTestList, command) + +# The unit test. + + +class GTestFilterUnitTest(gtest_test_utils.TestCase): + """Tests the env variable or the command line flag to filter tests.""" + + # Utilities. + + def AssertSetEqual(self, lhs, rhs): + """Asserts that two sets are equal.""" + + for elem in lhs: + self.assert_(elem in rhs, '%s in %s' % (elem, rhs)) + + for elem in rhs: + self.assert_(elem in lhs, '%s in %s' % (elem, lhs)) + + def AssertPartitionIsValid(self, set_var, list_of_sets): + """Asserts that list_of_sets is a valid partition of set_var.""" + + full_partition = [] + for slice_var in list_of_sets: + full_partition.extend(slice_var) + self.assertEqual(len(set_var), len(full_partition)) + self.assertEqual(set(set_var), set(full_partition)) + + def AdjustForParameterizedTests(self, tests_to_run): + """Adjust tests_to_run in case value parameterized tests are disabled.""" + + global param_tests_present + if not param_tests_present: + return list(set(tests_to_run) - set(PARAM_TESTS)) + else: + return tests_to_run + + def RunAndVerify(self, gtest_filter, tests_to_run): + """Checks that the binary runs correct set of tests for a given filter.""" + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # First, tests using the environment variable. + + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). + # pylint: disable-msg=C6403 + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + tests_run = RunAndExtractTestList()[0] + SetEnvVar(FILTER_ENV_VAR, None) + self.AssertSetEqual(tests_run, tests_to_run) + # pylint: enable-msg=C6403 + + # Next, tests using the command line flag. + + if gtest_filter is None: + args = [] + else: + args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)] + + tests_run = RunAndExtractTestList(args)[0] + self.AssertSetEqual(tests_run, tests_to_run) + + def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run, + args=None, check_exit_0=False): + """Checks that binary runs correct tests for the given filter and shard. + + Runs all shards of googletest-filter-unittest_ with the given filter, and + verifies that the right set of tests were run. The union of tests run + on each shard should be identical to tests_to_run, without duplicates. + If check_exit_0, . + + Args: + gtest_filter: A filter to apply to the tests. + total_shards: A total number of shards to split test run into. + tests_to_run: A set of tests expected to run. + args : Arguments to pass to the to the test binary. + check_exit_0: When set to a true value, make sure that all shards + return 0. + """ + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). + # pylint: disable-msg=C6403 + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + partition = [] + for i in range(0, total_shards): + (tests_run, exit_code) = RunWithSharding(total_shards, i, args) + if check_exit_0: + self.assertEqual(0, exit_code) + partition.append(tests_run) + + self.AssertPartitionIsValid(tests_to_run, partition) + SetEnvVar(FILTER_ENV_VAR, None) + # pylint: enable-msg=C6403 + + def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): + """Checks that the binary runs correct set of tests for the given filter. + + Runs googletest-filter-unittest_ with the given filter, and enables + disabled tests. Verifies that the right set of tests were run. + + Args: + gtest_filter: A filter to apply to the tests. + tests_to_run: A set of tests expected to run. + """ + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # Construct the command line. + args = ['--%s' % ALSO_RUN_DISABLED_TESTS_FLAG] + if gtest_filter is not None: + args.append('--%s=%s' % (FILTER_FLAG, gtest_filter)) + + tests_run = RunAndExtractTestList(args)[0] + self.AssertSetEqual(tests_run, tests_to_run) + + def setUp(self): + """Sets up test case. + + Determines whether value-parameterized tests are enabled in the binary and + sets the flags accordingly. + """ + + global param_tests_present + if param_tests_present is None: + param_tests_present = PARAM_TEST_REGEX.search( + RunAndReturnOutput()) is not None + + def testDefaultBehavior(self): + """Tests the behavior of not specifying the filter.""" + + self.RunAndVerify(None, ACTIVE_TESTS) + + def testDefaultBehaviorWithShards(self): + """Tests the behavior without the filter, with sharding enabled.""" + + self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS), ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) + 1, ACTIVE_TESTS) + + def testEmptyFilter(self): + """Tests an empty filter.""" + + self.RunAndVerify('', []) + self.RunAndVerifyWithSharding('', 1, []) + self.RunAndVerifyWithSharding('', 2, []) + + def testBadFilter(self): + """Tests a filter that matches nothing.""" + + self.RunAndVerify('BadFilter', []) + self.RunAndVerifyAllowingDisabled('BadFilter', []) + + def testFullName(self): + """Tests filtering by full name.""" + + self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyWithSharding('FooTest.Xyz', 5, ['FooTest.Xyz']) + + def testUniversalFilters(self): + """Tests filters that match everything.""" + + self.RunAndVerify('*', ACTIVE_TESTS) + self.RunAndVerify('*.*', ACTIVE_TESTS) + self.RunAndVerifyWithSharding('*.*', len(ACTIVE_TESTS) - 3, ACTIVE_TESTS) + self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS) + self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS) + + def testFilterByTestCase(self): + """Tests filtering by test case name.""" + + self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz']) + + BAZ_TESTS = ['BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB'] + self.RunAndVerify('BazTest.*', BAZ_TESTS) + self.RunAndVerifyAllowingDisabled('BazTest.*', + BAZ_TESTS + ['BazTest.DISABLED_TestC']) + + def testFilterByTest(self): + """Tests filtering by test name.""" + + self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne']) + + def testFilterDisabledTests(self): + """Select only the disabled tests to run.""" + + self.RunAndVerify('DISABLED_FoobarTest.Test1', []) + self.RunAndVerifyAllowingDisabled('DISABLED_FoobarTest.Test1', + ['DISABLED_FoobarTest.Test1']) + + self.RunAndVerify('*DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*DISABLED_*', DISABLED_TESTS) + + self.RunAndVerify('*.DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*.DISABLED_*', [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.DISABLED_Test2', + ]) + + self.RunAndVerify('DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('DISABLED_*', [ + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ]) + + def testWildcardInTestCaseName(self): + """Tests using wildcard in the test case name.""" + + self.RunAndVerify('*a*.*', [ + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS) + + def testWildcardInTestName(self): + """Tests using wildcard in the test name.""" + + self.RunAndVerify('*.*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testFilterWithoutDot(self): + """Tests a filter that has no '.' in it.""" + + self.RunAndVerify('*z*', [ + 'FooTest.Xyz', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', + ]) + + def testTwoPatterns(self): + """Tests filters that consist of two patterns.""" + + self.RunAndVerify('Foo*.*:*A*', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BazTest.TestA', + ]) + + # An empty pattern + a non-empty one + self.RunAndVerify(':*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testThreePatterns(self): + """Tests filters that consist of three patterns.""" + + self.RunAndVerify('*oo*:*A*:*One', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + + 'BazTest.TestOne', + 'BazTest.TestA', + ]) + + # The 2nd pattern is empty. + self.RunAndVerify('*oo*::*One', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + + 'BazTest.TestOne', + ]) + + # The last 2 patterns are empty. + self.RunAndVerify('*oo*::', [ + 'FooTest.Abc', + 'FooTest.Xyz', + ]) + + def testNegativeFilters(self): + self.RunAndVerify('*-BazTest.TestOne', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestA', + 'BazTest.TestB', + ] + DEATH_TESTS + PARAM_TESTS) + + self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + ] + DEATH_TESTS + PARAM_TESTS) + + self.RunAndVerify('BarTest.*-BarTest.TestOne', [ + 'BarTest.TestTwo', + 'BarTest.TestThree', + ]) + + # Tests without leading '*'. + self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:BazTest.*', [ + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + ] + DEATH_TESTS + PARAM_TESTS) + + # Value parameterized tests. + self.RunAndVerify('*/*', PARAM_TESTS) + + # Value parameterized tests filtering by the sequence name. + self.RunAndVerify('SeqP/*', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ]) + + # Value parameterized tests filtering by the test name. + self.RunAndVerify('*/0', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestY/0', + ]) + + def testFlagOverridesEnvVar(self): + """Tests that the filter flag overrides the filtering env. variable.""" + + SetEnvVar(FILTER_ENV_VAR, 'Foo*') + args = ['--%s=%s' % (FILTER_FLAG, '*One')] + tests_run = RunAndExtractTestList(args)[0] + SetEnvVar(FILTER_ENV_VAR, None) + + self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne']) + + def testShardStatusFileIsCreated(self): + """Tests that the shard file is created if specified in the environment.""" + + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + try: + InvokeWithModifiedEnv(extra_env, RunAndReturnOutput) + finally: + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + + def testShardStatusFileIsCreatedWithListTests(self): + """Tests that the shard file is created with the "list_tests" flag.""" + + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file2') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + try: + output = InvokeWithModifiedEnv(extra_env, + RunAndReturnOutput, + [LIST_TESTS_FLAG]) + finally: + # This assertion ensures that Google Test enumerated the tests as + # opposed to running them. + self.assert_('[==========]' not in output, + 'Unexpected output during test enumeration.\n' + 'Please ensure that LIST_TESTS_FLAG is assigned the\n' + 'correct flag value for listing Google Test tests.') + + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + + if SUPPORTS_DEATH_TESTS: + def testShardingWorksWithDeathTests(self): + """Tests integration with death tests and sharding.""" + + gtest_filter = 'HasDeathTest.*:SeqP/*' + expected_tests = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ] + + for flag in ['--gtest_death_test_style=threadsafe', + '--gtest_death_test_style=fast']: + self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests, + check_exit_0=True, args=[flag]) + self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests, + check_exit_0=True, args=[flag]) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-filter-unittest_.cc b/3rdparty/gtest/test/googletest-filter-unittest_.cc new file mode 100644 index 0000000..d30ec9c --- /dev/null +++ b/3rdparty/gtest/test/googletest-filter-unittest_.cc @@ -0,0 +1,137 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Unit test for Google Test test filters. +// +// A user can specify which test(s) in a Google Test program to run via +// either the GTEST_FILTER environment variable or the --gtest_filter +// flag. This is used for testing such functionality. +// +// The program will be invoked from a Python unit test. Don't run it +// directly. + +#include "gtest/gtest.h" + +namespace { + +// Test case FooTest. + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Abc) { +} + +TEST_F(FooTest, Xyz) { + FAIL() << "Expected failure."; +} + +// Test case BarTest. + +TEST(BarTest, TestOne) { +} + +TEST(BarTest, TestTwo) { +} + +TEST(BarTest, TestThree) { +} + +TEST(BarTest, DISABLED_TestFour) { + FAIL() << "Expected failure."; +} + +TEST(BarTest, DISABLED_TestFive) { + FAIL() << "Expected failure."; +} + +// Test case BazTest. + +TEST(BazTest, TestOne) { + FAIL() << "Expected failure."; +} + +TEST(BazTest, TestA) { +} + +TEST(BazTest, TestB) { +} + +TEST(BazTest, DISABLED_TestC) { + FAIL() << "Expected failure."; +} + +// Test case HasDeathTest + +TEST(HasDeathTest, Test1) { + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); +} + +// We need at least two death tests to make sure that the all death tests +// aren't on the first shard. +TEST(HasDeathTest, Test2) { + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); +} + +// Test case FoobarTest + +TEST(DISABLED_FoobarTest, Test1) { + FAIL() << "Expected failure."; +} + +TEST(DISABLED_FoobarTest, DISABLED_Test2) { + FAIL() << "Expected failure."; +} + +// Test case FoobarbazTest + +TEST(DISABLED_FoobarbazTest, TestA) { + FAIL() << "Expected failure."; +} + +class ParamTest : public testing::TestWithParam { +}; + +TEST_P(ParamTest, TestX) { +} + +TEST_P(ParamTest, TestY) { +} + +INSTANTIATE_TEST_SUITE_P(SeqP, ParamTest, testing::Values(1, 2)); +INSTANTIATE_TEST_SUITE_P(SeqQ, ParamTest, testing::Values(5, 6)); + +} // namespace + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/googletest-json-outfiles-test.py b/3rdparty/gtest/test/googletest-json-outfiles-test.py new file mode 100644 index 0000000..8ef47b8 --- /dev/null +++ b/3rdparty/gtest/test/googletest-json-outfiles-test.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# Copyright 2018, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test for the gtest_json_output module.""" + +import json +import os +import gtest_json_test_utils +import gtest_test_utils + +GTEST_OUTPUT_SUBDIR = 'json_outfiles' +GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_' +GTEST_OUTPUT_2_TEST = 'gtest_xml_outfile2_test_' + +EXPECTED_1 = { + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'name': + u'AllTests', + u'testsuites': [{ + u'name': + u'PropertyOne', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'TestSomeProperties', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'PropertyOne', + u'SetUpProp': u'1', + u'TestSomeProperty': u'1', + u'TearDownProp': u'1', + }], + }], +} + +EXPECTED_2 = { + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'name': + u'AllTests', + u'testsuites': [{ + u'name': + u'PropertyTwo', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'TestSomeProperties', + u'status': u'RUN', + u'result': u'COMPLETED', + u'timestamp': u'*', + u'time': u'*', + u'classname': u'PropertyTwo', + u'SetUpProp': u'2', + u'TestSomeProperty': u'2', + u'TearDownProp': u'2', + }], + }], +} + + +class GTestJsonOutFilesTest(gtest_test_utils.TestCase): + """Unit test for Google Test's JSON output functionality.""" + + def setUp(self): + # We want the trailing '/' that the last "" provides in os.path.join, for + # telling Google Test to create an output directory instead of a single file + # for xml output. + self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_OUTPUT_SUBDIR, '') + self.DeleteFilesAndDir() + + def tearDown(self): + self.DeleteFilesAndDir() + + def DeleteFilesAndDir(self): + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + '.json')) + except os.error: + pass + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + '.json')) + except os.error: + pass + try: + os.rmdir(self.output_dir_) + except os.error: + pass + + def testOutfile1(self): + self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_1) + + def testOutfile2(self): + self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_2) + + def _TestOutFile(self, test_name, expected): + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name) + command = [gtest_prog_path, '--gtest_output=json:%s' % self.output_dir_] + p = gtest_test_utils.Subprocess(command, + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + + output_file_name1 = test_name + '.json' + output_file1 = os.path.join(self.output_dir_, output_file_name1) + output_file_name2 = 'lt-' + output_file_name1 + output_file2 = os.path.join(self.output_dir_, output_file_name2) + self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2), + output_file1) + + if os.path.isfile(output_file1): + with open(output_file1) as f: + actual = json.load(f) + else: + with open(output_file2) as f: + actual = json.load(f) + self.assertEqual(expected, gtest_json_test_utils.normalize(actual)) + + +if __name__ == '__main__': + os.environ['GTEST_STACK_TRACE_DEPTH'] = '0' + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-json-output-unittest.py b/3rdparty/gtest/test/googletest-json-output-unittest.py new file mode 100644 index 0000000..15861f7 --- /dev/null +++ b/3rdparty/gtest/test/googletest-json-output-unittest.py @@ -0,0 +1,778 @@ +#!/usr/bin/env python +# Copyright 2018, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test for the gtest_json_output module.""" + +import datetime +import errno +import json +import os +import re +import sys + +import gtest_json_test_utils +import gtest_test_utils + +GTEST_FILTER_FLAG = '--gtest_filter' +GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' +GTEST_OUTPUT_FLAG = '--gtest_output' +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.json' +GTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_' + +# The flag indicating stacktraces are not supported +NO_STACKTRACE_SUPPORT_FLAG = '--no_stacktrace_support' + +SUPPORTS_STACK_TRACES = NO_STACKTRACE_SUPPORT_FLAG not in sys.argv + +if SUPPORTS_STACK_TRACES: + STACK_TRACE_TEMPLATE = '\nStack trace:\n*' +else: + STACK_TRACE_TEMPLATE = '' + +EXPECTED_NON_EMPTY = { + u'tests': + 24, + u'failures': + 4, + u'disabled': + 2, + u'errors': + 0, + u'timestamp': + u'*', + u'time': + u'*', + u'ad_hoc_property': + u'42', + u'name': + u'AllTests', + u'testsuites': [{ + u'name': + u'SuccessfulTest', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'Succeeds', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'SuccessfulTest' + }] + }, { + u'name': + u'FailedTest', + u'tests': + 1, + u'failures': + 1, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': + u'Fails', + u'status': + u'RUN', + u'result': + u'COMPLETED', + u'time': + u'*', + u'timestamp': + u'*', + u'classname': + u'FailedTest', + u'failures': [{ + u'failure': u'gtest_xml_output_unittest_.cc:*\n' + u'Expected equality of these values:\n' + u' 1\n 2' + STACK_TRACE_TEMPLATE, + u'type': u'' + }] + }] + }, { + u'name': + u'DisabledTest', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 1, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'DISABLED_test_not_run', + u'status': u'NOTRUN', + u'result': u'SUPPRESSED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'DisabledTest' + }] + }, { + u'name': + u'SkippedTest', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'Skipped', + u'status': u'RUN', + u'result': u'SKIPPED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'SkippedTest' + }] + }, { + u'name': + u'MixedResultTest', + u'tests': + 3, + u'failures': + 1, + u'disabled': + 1, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'Succeeds', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'MixedResultTest' + }, { + u'name': + u'Fails', + u'status': + u'RUN', + u'result': + u'COMPLETED', + u'time': + u'*', + u'timestamp': + u'*', + u'classname': + u'MixedResultTest', + u'failures': [{ + u'failure': u'gtest_xml_output_unittest_.cc:*\n' + u'Expected equality of these values:\n' + u' 1\n 2' + STACK_TRACE_TEMPLATE, + u'type': u'' + }, { + u'failure': u'gtest_xml_output_unittest_.cc:*\n' + u'Expected equality of these values:\n' + u' 2\n 3' + STACK_TRACE_TEMPLATE, + u'type': u'' + }] + }, { + u'name': u'DISABLED_test', + u'status': u'NOTRUN', + u'result': u'SUPPRESSED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'MixedResultTest' + }] + }, { + u'name': + u'XmlQuotingTest', + u'tests': + 1, + u'failures': + 1, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': + u'OutputsCData', + u'status': + u'RUN', + u'result': + u'COMPLETED', + u'time': + u'*', + u'timestamp': + u'*', + u'classname': + u'XmlQuotingTest', + u'failures': [{ + u'failure': u'gtest_xml_output_unittest_.cc:*\n' + u'Failed\nXML output: ' + u'' + + STACK_TRACE_TEMPLATE, + u'type': u'' + }] + }] + }, { + u'name': + u'InvalidCharactersTest', + u'tests': + 1, + u'failures': + 1, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': + u'InvalidCharactersInMessage', + u'status': + u'RUN', + u'result': + u'COMPLETED', + u'time': + u'*', + u'timestamp': + u'*', + u'classname': + u'InvalidCharactersTest', + u'failures': [{ + u'failure': u'gtest_xml_output_unittest_.cc:*\n' + u'Failed\nInvalid characters in brackets' + u' [\x01\x02]' + STACK_TRACE_TEMPLATE, + u'type': u'' + }] + }] + }, { + u'name': + u'PropertyRecordingTest', + u'tests': + 4, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'SetUpTestSuite': + u'yes', + u'TearDownTestSuite': + u'aye', + u'testsuite': [{ + u'name': u'OneProperty', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'PropertyRecordingTest', + u'key_1': u'1' + }, { + u'name': u'IntValuedProperty', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'PropertyRecordingTest', + u'key_int': u'1' + }, { + u'name': u'ThreeProperties', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'PropertyRecordingTest', + u'key_1': u'1', + u'key_2': u'2', + u'key_3': u'3' + }, { + u'name': u'TwoValuesForOneKeyUsesLastValue', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'PropertyRecordingTest', + u'key_1': u'2' + }] + }, { + u'name': + u'NoFixtureTest', + u'tests': + 3, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'RecordProperty', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'NoFixtureTest', + u'key': u'1' + }, { + u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'NoFixtureTest', + u'key_for_utility_int': u'1' + }, { + u'name': u'ExternalUtilityThatCallsRecordStringValuedProperty', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'NoFixtureTest', + u'key_for_utility_string': u'1' + }] + }, { + u'name': + u'TypedTest/0', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'HasTypeParamAttribute', + u'type_param': u'int', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'TypedTest/0' + }] + }, { + u'name': + u'TypedTest/1', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'HasTypeParamAttribute', + u'type_param': u'long', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'TypedTest/1' + }] + }, { + u'name': + u'Single/TypeParameterizedTestSuite/0', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'HasTypeParamAttribute', + u'type_param': u'int', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'Single/TypeParameterizedTestSuite/0' + }] + }, { + u'name': + u'Single/TypeParameterizedTestSuite/1', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'HasTypeParamAttribute', + u'type_param': u'long', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'Single/TypeParameterizedTestSuite/1' + }] + }, { + u'name': + u'Single/ValueParamTest', + u'tests': + 4, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'HasValueParamAttribute/0', + u'value_param': u'33', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'Single/ValueParamTest' + }, { + u'name': u'HasValueParamAttribute/1', + u'value_param': u'42', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'Single/ValueParamTest' + }, { + u'name': u'AnotherTestThatHasValueParamAttribute/0', + u'value_param': u'33', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'Single/ValueParamTest' + }, { + u'name': u'AnotherTestThatHasValueParamAttribute/1', + u'value_param': u'42', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'Single/ValueParamTest' + }] + }] +} + +EXPECTED_FILTERED = { + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'name': + u'AllTests', + u'ad_hoc_property': + u'42', + u'testsuites': [{ + u'name': + u'SuccessfulTest', + u'tests': + 1, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': u'Succeeds', + u'status': u'RUN', + u'result': u'COMPLETED', + u'time': u'*', + u'timestamp': u'*', + u'classname': u'SuccessfulTest', + }] + }], +} + +EXPECTED_EMPTY = { + u'tests': 0, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'timestamp': u'*', + u'name': u'AllTests', + u'testsuites': [], +} + +GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) + +SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess( + [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output + + +class GTestJsonOutputUnitTest(gtest_test_utils.TestCase): + """Unit test for Google Test's JSON output functionality. + """ + + # This test currently breaks on platforms that do not support typed and + # type-parameterized tests, so we don't run it under them. + if SUPPORTS_TYPED_TESTS: + + def testNonEmptyJsonOutput(self): + """Verifies JSON output for a Google Test binary with non-empty output. + + Runs a test program that generates a non-empty JSON output, and + tests that the JSON output is expected. + """ + self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY, 1) + + def testEmptyJsonOutput(self): + """Verifies JSON output for a Google Test binary without actual tests. + + Runs a test program that generates an empty JSON output, and + tests that the JSON output is expected. + """ + + self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_EMPTY, 0) + + def testTimestampValue(self): + """Checks whether the timestamp attribute in the JSON output is valid. + + Runs a test program that generates an empty JSON output, and checks if + the timestamp attribute in the testsuites tag is valid. + """ + actual = self._GetJsonOutput('gtest_no_test_unittest', [], 0) + date_time_str = actual['timestamp'] + # datetime.strptime() is only available in Python 2.5+ so we have to + # parse the expected datetime manually. + match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str) + self.assertTrue( + re.match, + 'JSON datettime string %s has incorrect format' % date_time_str) + date_time_from_json = datetime.datetime( + year=int(match.group(1)), month=int(match.group(2)), + day=int(match.group(3)), hour=int(match.group(4)), + minute=int(match.group(5)), second=int(match.group(6))) + + time_delta = abs(datetime.datetime.now() - date_time_from_json) + # timestamp value should be near the current local time + self.assertTrue(time_delta < datetime.timedelta(seconds=600), + 'time_delta is %s' % time_delta) + + def testDefaultOutputFile(self): + """Verifies the default output file name. + + Confirms that Google Test produces an JSON output file with the expected + default name if no name is explicitly specified. + """ + output_file = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_DEFAULT_OUTPUT_FILE) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath( + 'gtest_no_test_unittest') + try: + os.remove(output_file) + except OSError: + e = sys.exc_info()[1] + if e.errno != errno.ENOENT: + raise + + p = gtest_test_utils.Subprocess( + [gtest_prog_path, '%s=json' % GTEST_OUTPUT_FLAG], + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + self.assert_(os.path.isfile(output_file)) + + def testSuppressedJsonOutput(self): + """Verifies that no JSON output is generated. + + Tests that no JSON file is generated if the default JSON listener is + shut down before RUN_ALL_TESTS is invoked. + """ + + json_path = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_PROGRAM_NAME + 'out.json') + if os.path.isfile(json_path): + os.remove(json_path) + + command = [GTEST_PROGRAM_PATH, + '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path), + '--shut_down_xml'] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + # p.signal is available only if p.terminated_by_signal is True. + self.assertFalse( + p.terminated_by_signal, + '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(1, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, 1)) + + self.assert_(not os.path.isfile(json_path)) + + def testFilteredTestJsonOutput(self): + """Verifies JSON output when a filter is applied. + + Runs a test program that executes only some tests and verifies that + non-selected tests do not show up in the JSON output. + """ + + self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED, 0, + extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG]) + + def _GetJsonOutput(self, gtest_prog_name, extra_args, expected_exit_code): + """Returns the JSON output generated by running the program gtest_prog_name. + + Furthermore, the program's exit code must be expected_exit_code. + + Args: + gtest_prog_name: Google Test binary name. + extra_args: extra arguments to binary invocation. + expected_exit_code: program's exit code. + """ + json_path = os.path.join(gtest_test_utils.GetTempDir(), + gtest_prog_name + 'out.json') + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) + + command = ( + [gtest_prog_path, '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path)] + + extra_args + ) + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + self.assert_(False, + '%s was killed by signal %d' % (gtest_prog_name, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(expected_exit_code, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, expected_exit_code)) + with open(json_path) as f: + actual = json.load(f) + return actual + + def _TestJsonOutput(self, gtest_prog_name, expected, + expected_exit_code, extra_args=None): + """Checks the JSON output generated by the Google Test binary. + + Asserts that the JSON document generated by running the program + gtest_prog_name matches expected_json, a string containing another + JSON document. Furthermore, the program's exit code must be + expected_exit_code. + + Args: + gtest_prog_name: Google Test binary name. + expected: expected output. + expected_exit_code: program's exit code. + extra_args: extra arguments to binary invocation. + """ + + actual = self._GetJsonOutput(gtest_prog_name, extra_args or [], + expected_exit_code) + self.assertEqual(expected, gtest_json_test_utils.normalize(actual)) + + +if __name__ == '__main__': + if NO_STACKTRACE_SUPPORT_FLAG in sys.argv: + # unittest.main() can't handle unknown flags + sys.argv.remove(NO_STACKTRACE_SUPPORT_FLAG) + + os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-list-tests-unittest.py b/3rdparty/gtest/test/googletest-list-tests-unittest.py new file mode 100644 index 0000000..81423a3 --- /dev/null +++ b/3rdparty/gtest/test/googletest-list-tests-unittest.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test for Google Test's --gtest_list_tests flag. + +A user can ask Google Test to list all tests by specifying the +--gtest_list_tests flag. This script tests such functionality +by invoking googletest-list-tests-unittest_ (a program written with +Google Test) the command line flags. +""" + +import re +import gtest_test_utils + +# Constants. + +# The command line flag for enabling/disabling listing all tests. +LIST_TESTS_FLAG = 'gtest_list_tests' + +# Path to the googletest-list-tests-unittest_ program. +EXE_PATH = gtest_test_utils.GetTestExecutablePath('googletest-list-tests-unittest_') + +# The expected output when running googletest-list-tests-unittest_ with +# --gtest_list_tests +EXPECTED_OUTPUT_NO_FILTER_RE = re.compile(r"""FooDeathTest\. + Test1 +Foo\. + Bar1 + Bar2 + DISABLED_Bar3 +Abc\. + Xyz + Def +FooBar\. + Baz +FooTest\. + Test1 + DISABLED_Test2 + Test3 +TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. + TestA + TestB +TypedTest/1\. # TypeParam = int\s*\*( __ptr64)? + TestA + TestB +TypedTest/2\. # TypeParam = .*MyArray + TestA + TestB +My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. + TestA + TestB +My/TypeParamTest/1\. # TypeParam = int\s*\*( __ptr64)? + TestA + TestB +My/TypeParamTest/2\. # TypeParam = .*MyArray + TestA + TestB +MyInstantiation/ValueParamTest\. + TestA/0 # GetParam\(\) = one line + TestA/1 # GetParam\(\) = two\\nlines + TestA/2 # GetParam\(\) = a very\\nlo{241}\.\.\. + TestB/0 # GetParam\(\) = one line + TestB/1 # GetParam\(\) = two\\nlines + TestB/2 # GetParam\(\) = a very\\nlo{241}\.\.\. +""") + +# The expected output when running googletest-list-tests-unittest_ with +# --gtest_list_tests and --gtest_filter=Foo*. +EXPECTED_OUTPUT_FILTER_FOO_RE = re.compile(r"""FooDeathTest\. + Test1 +Foo\. + Bar1 + Bar2 + DISABLED_Bar3 +FooBar\. + Baz +FooTest\. + Test1 + DISABLED_Test2 + Test3 +""") + +# Utilities. + + +def Run(args): + """Runs googletest-list-tests-unittest_ and returns the list of tests printed.""" + + return gtest_test_utils.Subprocess([EXE_PATH] + args, + capture_stderr=False).output + + +# The unit test. + + +class GTestListTestsUnitTest(gtest_test_utils.TestCase): + """Tests using the --gtest_list_tests flag to list all tests.""" + + def RunAndVerify(self, flag_value, expected_output_re, other_flag): + """Runs googletest-list-tests-unittest_ and verifies that it prints + the correct tests. + + Args: + flag_value: value of the --gtest_list_tests flag; + None if the flag should not be present. + expected_output_re: regular expression that matches the expected + output after running command; + other_flag: a different flag to be passed to command + along with gtest_list_tests; + None if the flag should not be present. + """ + + if flag_value is None: + flag = '' + flag_expression = 'not set' + elif flag_value == '0': + flag = '--%s=0' % LIST_TESTS_FLAG + flag_expression = '0' + else: + flag = '--%s' % LIST_TESTS_FLAG + flag_expression = '1' + + args = [flag] + + if other_flag is not None: + args += [other_flag] + + output = Run(args) + + if expected_output_re: + self.assert_( + expected_output_re.match(output), + ('when %s is %s, the output of "%s" is "%s",\n' + 'which does not match regex "%s"' % + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output, + expected_output_re.pattern))) + else: + self.assert_( + not EXPECTED_OUTPUT_NO_FILTER_RE.match(output), + ('when %s is %s, the output of "%s" is "%s"'% + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output))) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(flag_value=None, + expected_output_re=None, + other_flag=None) + + def testFlag(self): + """Tests using the --gtest_list_tests flag.""" + + self.RunAndVerify(flag_value='0', + expected_output_re=None, + other_flag=None) + self.RunAndVerify(flag_value='1', + expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, + other_flag=None) + + def testOverrideNonFilterFlags(self): + """Tests that --gtest_list_tests overrides the non-filter flags.""" + + self.RunAndVerify(flag_value='1', + expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, + other_flag='--gtest_break_on_failure') + + def testWithFilterFlags(self): + """Tests that --gtest_list_tests takes into account the + --gtest_filter flag.""" + + self.RunAndVerify(flag_value='1', + expected_output_re=EXPECTED_OUTPUT_FILTER_FOO_RE, + other_flag='--gtest_filter=Foo*') + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-list-tests-unittest_.cc b/3rdparty/gtest/test/googletest-list-tests-unittest_.cc new file mode 100644 index 0000000..493c6f0 --- /dev/null +++ b/3rdparty/gtest/test/googletest-list-tests-unittest_.cc @@ -0,0 +1,156 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Unit test for Google Test's --gtest_list_tests flag. +// +// A user can ask Google Test to list all tests that will run +// so that when using a filter, a user will know what +// tests to look for. The tests will not be run after listing. +// +// This program will be invoked from a Python unit test. +// Don't run it directly. + +#include "gtest/gtest.h" + +// Several different test cases and tests that will be listed. +TEST(Foo, Bar1) { +} + +TEST(Foo, Bar2) { +} + +TEST(Foo, DISABLED_Bar3) { +} + +TEST(Abc, Xyz) { +} + +TEST(Abc, Def) { +} + +TEST(FooBar, Baz) { +} + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Test1) { +} + +TEST_F(FooTest, DISABLED_Test2) { +} + +TEST_F(FooTest, Test3) { +} + +TEST(FooDeathTest, Test1) { +} + +// A group of value-parameterized tests. + +class MyType { + public: + explicit MyType(const std::string& a_value) : value_(a_value) {} + + const std::string& value() const { return value_; } + + private: + std::string value_; +}; + +// Teaches Google Test how to print a MyType. +void PrintTo(const MyType& x, std::ostream* os) { + *os << x.value(); +} + +class ValueParamTest : public testing::TestWithParam { +}; + +TEST_P(ValueParamTest, TestA) { +} + +TEST_P(ValueParamTest, TestB) { +} + +INSTANTIATE_TEST_SUITE_P( + MyInstantiation, ValueParamTest, + testing::Values(MyType("one line"), + MyType("two\nlines"), + MyType("a very\nloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"))); // NOLINT + +// A group of typed tests. + +// A deliberately long type name for testing the line-truncating +// behavior when printing a type parameter. +class VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName { // NOLINT +}; + +template +class TypedTest : public testing::Test { +}; + +template +class MyArray { +}; + +typedef testing::Types > MyTypes; + +TYPED_TEST_SUITE(TypedTest, MyTypes); + +TYPED_TEST(TypedTest, TestA) { +} + +TYPED_TEST(TypedTest, TestB) { +} + +// A group of type-parameterized tests. + +template +class TypeParamTest : public testing::Test { +}; + +TYPED_TEST_SUITE_P(TypeParamTest); + +TYPED_TEST_P(TypeParamTest, TestA) { +} + +TYPED_TEST_P(TypeParamTest, TestB) { +} + +REGISTER_TYPED_TEST_SUITE_P(TypeParamTest, TestA, TestB); + +INSTANTIATE_TYPED_TEST_SUITE_P(My, TypeParamTest, MyTypes); + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/googletest-listener-test.cc b/3rdparty/gtest/test/googletest-listener-test.cc new file mode 100644 index 0000000..10457af --- /dev/null +++ b/3rdparty/gtest/test/googletest-listener-test.cc @@ -0,0 +1,518 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This file verifies Google Test event listeners receive events at the +// right times. + +#include + +#include "gtest/gtest.h" +#include "gtest/internal/custom/gtest.h" + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Environment; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestSuite; +using ::testing::TestEventListener; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +// Used by tests to register their events. +std::vector* g_events = nullptr; + +namespace testing { +namespace internal { + +class EventRecordingListener : public TestEventListener { + public: + explicit EventRecordingListener(const char* name) : name_(name) {} + + protected: + void OnTestProgramStart(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnTestProgramStart")); + } + + void OnTestIterationStart(const UnitTest& /*unit_test*/, + int iteration) override { + Message message; + message << GetFullMethodName("OnTestIterationStart") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart")); + } + + void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd")); + } +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseStart(const TestCase& /*test_case*/) override { + g_events->push_back(GetFullMethodName("OnTestCaseStart")); + } +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + void OnTestStart(const TestInfo& /*test_info*/) override { + g_events->push_back(GetFullMethodName("OnTestStart")); + } + + void OnTestPartResult(const TestPartResult& /*test_part_result*/) override { + g_events->push_back(GetFullMethodName("OnTestPartResult")); + } + + void OnTestEnd(const TestInfo& /*test_info*/) override { + g_events->push_back(GetFullMethodName("OnTestEnd")); + } + +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseEnd(const TestCase& /*test_case*/) override { + g_events->push_back(GetFullMethodName("OnTestCaseEnd")); + } +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart")); + } + + void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd")); + } + + void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int iteration) override { + Message message; + message << GetFullMethodName("OnTestIterationEnd") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + void OnTestProgramEnd(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnTestProgramEnd")); + } + + private: + std::string GetFullMethodName(const char* name) { + return name_ + "." + name; + } + + std::string name_; +}; + +// This listener is using OnTestSuiteStart, OnTestSuiteEnd API +class EventRecordingListener2 : public TestEventListener { + public: + explicit EventRecordingListener2(const char* name) : name_(name) {} + + protected: + void OnTestProgramStart(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnTestProgramStart")); + } + + void OnTestIterationStart(const UnitTest& /*unit_test*/, + int iteration) override { + Message message; + message << GetFullMethodName("OnTestIterationStart") << "(" << iteration + << ")"; + g_events->push_back(message.GetString()); + } + + void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart")); + } + + void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd")); + } + + void OnTestSuiteStart(const TestSuite& /*test_suite*/) override { + g_events->push_back(GetFullMethodName("OnTestSuiteStart")); + } + + void OnTestStart(const TestInfo& /*test_info*/) override { + g_events->push_back(GetFullMethodName("OnTestStart")); + } + + void OnTestPartResult(const TestPartResult& /*test_part_result*/) override { + g_events->push_back(GetFullMethodName("OnTestPartResult")); + } + + void OnTestEnd(const TestInfo& /*test_info*/) override { + g_events->push_back(GetFullMethodName("OnTestEnd")); + } + + void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override { + g_events->push_back(GetFullMethodName("OnTestSuiteEnd")); + } + + void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart")); + } + + void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd")); + } + + void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int iteration) override { + Message message; + message << GetFullMethodName("OnTestIterationEnd") << "(" << iteration + << ")"; + g_events->push_back(message.GetString()); + } + + void OnTestProgramEnd(const UnitTest& /*unit_test*/) override { + g_events->push_back(GetFullMethodName("OnTestProgramEnd")); + } + + private: + std::string GetFullMethodName(const char* name) { return name_ + "." + name; } + + std::string name_; +}; + +class EnvironmentInvocationCatcher : public Environment { + protected: + void SetUp() override { g_events->push_back("Environment::SetUp"); } + + void TearDown() override { g_events->push_back("Environment::TearDown"); } +}; + +class ListenerTest : public Test { + protected: + static void SetUpTestSuite() { + g_events->push_back("ListenerTest::SetUpTestSuite"); + } + + static void TearDownTestSuite() { + g_events->push_back("ListenerTest::TearDownTestSuite"); + } + + void SetUp() override { g_events->push_back("ListenerTest::SetUp"); } + + void TearDown() override { g_events->push_back("ListenerTest::TearDown"); } +}; + +TEST_F(ListenerTest, DoesFoo) { + // Test execution order within a test case is not guaranteed so we are not + // recording the test name. + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +TEST_F(ListenerTest, DoesBar) { + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +} // namespace internal + +} // namespace testing + +using ::testing::internal::EnvironmentInvocationCatcher; +using ::testing::internal::EventRecordingListener; +using ::testing::internal::EventRecordingListener2; + +void VerifyResults(const std::vector& data, + const char* const* expected_data, + size_t expected_data_size) { + const size_t actual_size = data.size(); + // If the following assertion fails, a new entry will be appended to + // data. Hence we save data.size() first. + EXPECT_EQ(expected_data_size, actual_size); + + // Compares the common prefix. + const size_t shorter_size = expected_data_size <= actual_size ? + expected_data_size : actual_size; + size_t i = 0; + for (; i < shorter_size; ++i) { + ASSERT_STREQ(expected_data[i], data[i].c_str()) + << "at position " << i; + } + + // Prints extra elements in the actual data. + for (; i < actual_size; ++i) { + printf(" Actual event #%lu: %s\n", + static_cast(i), data[i].c_str()); + } +} + +int main(int argc, char **argv) { + std::vector events; + g_events = &events; + InitGoogleTest(&argc, argv); + + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("1st")); + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("2nd")); + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener2("3rd")); + + AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); + + GTEST_CHECK_(events.size() == 0) + << "AddGlobalTestEnvironment should not generate any events itself."; + + ::testing::GTEST_FLAG(repeat) = 2; + int ret_val = RUN_ALL_TESTS(); + +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + // The deprecated OnTestSuiteStart/OnTestCaseStart events are included + const char* const expected_events[] = {"1st.OnTestProgramStart", + "2nd.OnTestProgramStart", + "3rd.OnTestProgramStart", + "1st.OnTestIterationStart(0)", + "2nd.OnTestIterationStart(0)", + "3rd.OnTestIterationStart(0)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "3rd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "3rd.OnEnvironmentsSetUpEnd", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "3rd.OnTestSuiteStart", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestSuite", + "1st.OnTestStart", + "2nd.OnTestStart", + "3rd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "3rd.OnTestPartResult", + "ListenerTest::TearDown", + "3rd.OnTestEnd", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "3rd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "3rd.OnTestPartResult", + "ListenerTest::TearDown", + "3rd.OnTestEnd", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestSuite", + "3rd.OnTestSuiteEnd", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "3rd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "3rd.OnEnvironmentsTearDownEnd", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "3rd.OnTestIterationEnd(0)", + "2nd.OnTestIterationEnd(0)", + "1st.OnTestIterationEnd(0)", + "1st.OnTestIterationStart(1)", + "2nd.OnTestIterationStart(1)", + "3rd.OnTestIterationStart(1)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "3rd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "3rd.OnEnvironmentsSetUpEnd", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "3rd.OnTestSuiteStart", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestSuite", + "1st.OnTestStart", + "2nd.OnTestStart", + "3rd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "3rd.OnTestPartResult", + "ListenerTest::TearDown", + "3rd.OnTestEnd", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "3rd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "3rd.OnTestPartResult", + "ListenerTest::TearDown", + "3rd.OnTestEnd", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestSuite", + "3rd.OnTestSuiteEnd", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "3rd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "3rd.OnEnvironmentsTearDownEnd", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "3rd.OnTestIterationEnd(1)", + "2nd.OnTestIterationEnd(1)", + "1st.OnTestIterationEnd(1)", + "3rd.OnTestProgramEnd", + "2nd.OnTestProgramEnd", + "1st.OnTestProgramEnd"}; +#else + const char* const expected_events[] = {"1st.OnTestProgramStart", + "2nd.OnTestProgramStart", + "3rd.OnTestProgramStart", + "1st.OnTestIterationStart(0)", + "2nd.OnTestIterationStart(0)", + "3rd.OnTestIterationStart(0)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "3rd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "3rd.OnEnvironmentsSetUpEnd", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "3rd.OnTestSuiteStart", + "ListenerTest::SetUpTestSuite", + "1st.OnTestStart", + "2nd.OnTestStart", + "3rd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "3rd.OnTestPartResult", + "ListenerTest::TearDown", + "3rd.OnTestEnd", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "3rd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "3rd.OnTestPartResult", + "ListenerTest::TearDown", + "3rd.OnTestEnd", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestSuite", + "3rd.OnTestSuiteEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "3rd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "3rd.OnEnvironmentsTearDownEnd", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "3rd.OnTestIterationEnd(0)", + "2nd.OnTestIterationEnd(0)", + "1st.OnTestIterationEnd(0)", + "1st.OnTestIterationStart(1)", + "2nd.OnTestIterationStart(1)", + "3rd.OnTestIterationStart(1)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "3rd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "3rd.OnEnvironmentsSetUpEnd", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "3rd.OnTestSuiteStart", + "ListenerTest::SetUpTestSuite", + "1st.OnTestStart", + "2nd.OnTestStart", + "3rd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "3rd.OnTestPartResult", + "ListenerTest::TearDown", + "3rd.OnTestEnd", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "3rd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "3rd.OnTestPartResult", + "ListenerTest::TearDown", + "3rd.OnTestEnd", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestSuite", + "3rd.OnTestSuiteEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "3rd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "3rd.OnEnvironmentsTearDownEnd", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "3rd.OnTestIterationEnd(1)", + "2nd.OnTestIterationEnd(1)", + "1st.OnTestIterationEnd(1)", + "3rd.OnTestProgramEnd", + "2nd.OnTestProgramEnd", + "1st.OnTestProgramEnd"}; +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + VerifyResults(events, + expected_events, + sizeof(expected_events)/sizeof(expected_events[0])); + + // We need to check manually for ad hoc test failures that happen after + // RUN_ALL_TESTS finishes. + if (UnitTest::GetInstance()->Failed()) + ret_val = 1; + + return ret_val; +} diff --git a/3rdparty/gtest/test/googletest-message-test.cc b/3rdparty/gtest/test/googletest-message-test.cc new file mode 100644 index 0000000..962d519 --- /dev/null +++ b/3rdparty/gtest/test/googletest-message-test.cc @@ -0,0 +1,158 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests for the Message class. + +#include "gtest/gtest-message.h" + +#include "gtest/gtest.h" + +namespace { + +using ::testing::Message; + +// Tests the testing::Message class + +// Tests the default constructor. +TEST(MessageTest, DefaultConstructor) { + const Message msg; + EXPECT_EQ("", msg.GetString()); +} + +// Tests the copy constructor. +TEST(MessageTest, CopyConstructor) { + const Message msg1("Hello"); + const Message msg2(msg1); + EXPECT_EQ("Hello", msg2.GetString()); +} + +// Tests constructing a Message from a C-string. +TEST(MessageTest, ConstructsFromCString) { + Message msg("Hello"); + EXPECT_EQ("Hello", msg.GetString()); +} + +// Tests streaming a float. +TEST(MessageTest, StreamsFloat) { + const std::string s = (Message() << 1.23456F << " " << 2.34567F).GetString(); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s.c_str()); +} + +// Tests streaming a double. +TEST(MessageTest, StreamsDouble) { + const std::string s = (Message() << 1260570880.4555497 << " " + << 1260572265.1954534).GetString(); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s.c_str()); +} + +// Tests streaming a non-char pointer. +TEST(MessageTest, StreamsPointer) { + int n = 0; + int* p = &n; + EXPECT_NE("(null)", (Message() << p).GetString()); +} + +// Tests streaming a NULL non-char pointer. +TEST(MessageTest, StreamsNullPointer) { + int* p = nullptr; + EXPECT_EQ("(null)", (Message() << p).GetString()); +} + +// Tests streaming a C string. +TEST(MessageTest, StreamsCString) { + EXPECT_EQ("Foo", (Message() << "Foo").GetString()); +} + +// Tests streaming a NULL C string. +TEST(MessageTest, StreamsNullCString) { + char* p = nullptr; + EXPECT_EQ("(null)", (Message() << p).GetString()); +} + +// Tests streaming std::string. +TEST(MessageTest, StreamsString) { + const ::std::string str("Hello"); + EXPECT_EQ("Hello", (Message() << str).GetString()); +} + +// Tests that we can output strings containing embedded NULs. +TEST(MessageTest, StreamsStringWithEmbeddedNUL) { + const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + const ::std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) - 1); + EXPECT_EQ("Here's a NUL\\0 and some more string", + (Message() << string_with_nul).GetString()); +} + +// Tests streaming a NUL char. +TEST(MessageTest, StreamsNULChar) { + EXPECT_EQ("\\0", (Message() << '\0').GetString()); +} + +// Tests streaming int. +TEST(MessageTest, StreamsInt) { + EXPECT_EQ("123", (Message() << 123).GetString()); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to Message. +TEST(MessageTest, StreamsBasicIoManip) { + EXPECT_EQ("Line 1.\nA NUL char \\0 in line 2.", + (Message() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush + << " in line 2.").GetString()); +} + +// Tests Message::GetString() +TEST(MessageTest, GetString) { + Message msg; + msg << 1 << " lamb"; + EXPECT_EQ("1 lamb", msg.GetString()); +} + +// Tests streaming a Message object to an ostream. +TEST(MessageTest, StreamsToOStream) { + Message msg("Hello"); + ::std::stringstream ss; + ss << msg; + EXPECT_EQ("Hello", testing::internal::StringStreamToString(&ss)); +} + +// Tests that a Message object doesn't take up too much stack space. +TEST(MessageTest, DoesNotTakeUpMuchStackSpace) { + EXPECT_LE(sizeof(Message), 16U); +} + +} // namespace diff --git a/3rdparty/gtest/test/googletest-options-test.cc b/3rdparty/gtest/test/googletest-options-test.cc new file mode 100644 index 0000000..f07b316 --- /dev/null +++ b/3rdparty/gtest/test/googletest-options-test.cc @@ -0,0 +1,216 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Google Test UnitTestOptions tests +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest.cc, to avoid changing build or +// make-files on Windows and other platforms. Do not #include this file +// anywhere else! + +#include "gtest/gtest.h" + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +#endif // GTEST_OS_WINDOWS_MOBILE + +#include "src/gtest-internal-inl.h" + +namespace testing { +namespace internal { +namespace { + +// Turns the given relative path into an absolute path. +FilePath GetAbsolutePathOf(const FilePath& relative_path) { + return FilePath::ConcatPaths(FilePath::GetCurrentDir(), relative_path); +} + +// Testing UnitTestOptions::GetOutputFormat/GetOutputFile. + +TEST(XmlOutputTest, GetOutputFormatDefault) { + GTEST_FLAG(output) = ""; + EXPECT_STREQ("", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFormat) { + GTEST_FLAG(output) = "xml:filename"; + EXPECT_STREQ("xml", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFileDefault) { + GTEST_FLAG(output) = ""; + EXPECT_EQ(GetAbsolutePathOf(FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST(XmlOutputTest, GetOutputFileSingleFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_EQ(GetAbsolutePathOf(FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + GetAbsolutePathOf( + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +TEST(OutputFileHelpersTest, GetCurrentExecutableName) { + const std::string exe_str = GetCurrentExecutableName().string(); +#if GTEST_OS_WINDOWS + const bool success = + _strcmpi("googletest-options-test", exe_str.c_str()) == 0 || + _strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_all_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_dll_test", exe_str.c_str()) == 0; +#elif GTEST_OS_OS2 + const bool success = + strcasecmp("googletest-options-test", exe_str.c_str()) == 0 || + strcasecmp("gtest-options-ex_test", exe_str.c_str()) == 0 || + strcasecmp("gtest_all_test", exe_str.c_str()) == 0 || + strcasecmp("gtest_dll_test", exe_str.c_str()) == 0; +#elif GTEST_OS_FUCHSIA + const bool success = exe_str == "app"; +#else + const bool success = + exe_str == "googletest-options-test" || + exe_str == "gtest_all_test" || + exe_str == "lt-gtest_all_test" || + exe_str == "gtest_dll_test"; +#endif // GTEST_OS_WINDOWS + if (!success) + FAIL() << "GetCurrentExecutableName() returns " << exe_str; +} + +#if !GTEST_OS_FUCHSIA + +class XmlOutputChangeDirTest : public Test { + protected: + void SetUp() override { + original_working_dir_ = FilePath::GetCurrentDir(); + posix::ChDir(".."); + // This will make the test fail if run from the root directory. + EXPECT_NE(original_working_dir_.string(), + FilePath::GetCurrentDir().string()); + } + + void TearDown() override { + posix::ChDir(original_working_dir_.string().c_str()); + } + + FilePath original_working_dir_; +}; + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) { + GTEST_FLAG(output) = ""; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) { + GTEST_FLAG(output) = "xml"; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + FilePath::ConcatPaths( + original_working_dir_, + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { +#if GTEST_OS_WINDOWS + GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; + EXPECT_EQ(FilePath("c:\\tmp\\filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +#else + GTEST_FLAG(output) ="xml:/tmp/filename.abc"; + EXPECT_EQ(FilePath("/tmp/filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { +#if GTEST_OS_WINDOWS + const std::string path = "c:\\tmp\\"; +#else + const std::string path = "/tmp/"; +#endif + + GTEST_FLAG(output) = "xml:" + path; + const std::string expected_output_file = + path + GetCurrentExecutableName().string() + ".xml"; + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); + +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +#endif // !GTEST_OS_FUCHSIA + +} // namespace +} // namespace internal +} // namespace testing diff --git a/3rdparty/gtest/test/googletest-output-test-golden-lin.txt b/3rdparty/gtest/test/googletest-output-test-golden-lin.txt new file mode 100644 index 0000000..038de92 --- /dev/null +++ b/3rdparty/gtest/test/googletest-output-test-golden-lin.txt @@ -0,0 +1,1140 @@ +The non-test part of the code is expected to have 2 failures. + +googletest-output-test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 2 + 3 +Stack trace: (omitted) + +[==========] Running 85 tests from 40 test suites. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 1 test from ADeathTest +[ RUN ] ADeathTest.ShouldRunFirst +[ OK ] ADeathTest.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/0, where TypeParam = int +[ RUN ] ATypedDeathTest/0.ShouldRunFirst +[ OK ] ATypedDeathTest/0.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/1, where TypeParam = double +[ RUN ] ATypedDeathTest/1.ShouldRunFirst +[ OK ] ATypedDeathTest/1.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int +[ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double +[ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst +[----------] 2 tests from PassingTest +[ RUN ] PassingTest.PassingTest1 +[ OK ] PassingTest.PassingTest1 +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] 2 tests from NonfatalFailureTest +[ RUN ] NonfatalFailureTest.EscapesStringOperands +googletest-output-test_.cc:#: Failure +Expected equality of these values: + kGoldenString + Which is: "\"Line" + actual + Which is: "actual \"string\"" +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Expected equality of these values: + golden + Which is: "\"Line" + actual + Which is: "actual \"string\"" +Stack trace: (omitted) + +[ FAILED ] NonfatalFailureTest.EscapesStringOperands +[ RUN ] NonfatalFailureTest.DiffForLongStrings +googletest-output-test_.cc:#: Failure +Expected equality of these values: + golden_str + Which is: "\"Line\0 1\"\nLine 2" + "Line 2" +With diff: +@@ -1,2 @@ +-\"Line\0 1\" + Line 2 + +Stack trace: (omitted) + +[ FAILED ] NonfatalFailureTest.DiffForLongStrings +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1 + x + Which is: 2 +Stack trace: (omitted) + +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1 + x + Which is: 2 +Stack trace: (omitted) + +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +googletest-output-test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +Stack trace: (omitted) + +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +googletest-output-test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +Stack trace: (omitted) + +i == 2 +i == 3 +googletest-output-test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +Stack trace: (omitted) + +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[----------] 7 tests from SCOPED_TRACETest +[ RUN ] SCOPED_TRACETest.AcceptedValues +googletest-output-test_.cc:#: Failure +Failed +Just checking that all these values work fine. +Google Test trace: +googletest-output-test_.cc:#: (null) +googletest-output-test_.cc:#: 1337 +googletest-output-test_.cc:#: std::string +googletest-output-test_.cc:#: literal string +Stack trace: (omitted) + +[ FAILED ] SCOPED_TRACETest.AcceptedValues +[ RUN ] SCOPED_TRACETest.ObeysScopes +(expected to fail) +googletest-output-test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +This failure is expected, and should have a trace. +Google Test trace: +googletest-output-test_.cc:#: Expected trace +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +Stack trace: (omitted) + +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ RUN ] SCOPED_TRACETest.WorksInLoop +(expected to fail) +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 2 + n + Which is: 1 +Google Test trace: +googletest-output-test_.cc:#: i = 1 +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1 + n + Which is: 2 +Google Test trace: +googletest-output-test_.cc:#: i = 2 +Stack trace: (omitted) + +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ RUN ] SCOPED_TRACETest.WorksInSubroutine +(expected to fail) +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 2 + n + Which is: 1 +Google Test trace: +googletest-output-test_.cc:#: n = 1 +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1 + n + Which is: 2 +Google Test trace: +googletest-output-test_.cc:#: n = 2 +Stack trace: (omitted) + +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ RUN ] SCOPED_TRACETest.CanBeNested +(expected to fail) +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1 + n + Which is: 2 +Google Test trace: +googletest-output-test_.cc:#: n = 2 +googletest-output-test_.cc:#: +Stack trace: (omitted) + +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ RUN ] SCOPED_TRACETest.CanBeRepeated +(expected to fail) +googletest-output-test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A. +Google Test trace: +googletest-output-test_.cc:#: A +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A and B. +Google Test trace: +googletest-output-test_.cc:#: B +googletest-output-test_.cc:#: A +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and C. +Google Test trace: +googletest-output-test_.cc:#: C +googletest-output-test_.cc:#: B +googletest-output-test_.cc:#: A +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and D. +Google Test trace: +googletest-output-test_.cc:#: D +googletest-output-test_.cc:#: B +googletest-output-test_.cc:#: A +Stack trace: (omitted) + +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ RUN ] SCOPED_TRACETest.WorksConcurrently +(expecting 6 failures) +googletest-output-test_.cc:#: Failure +Failed +Expected failure #1 (in thread B, only trace B alive). +Google Test trace: +googletest-output-test_.cc:#: Trace B +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #2 (in thread A, trace A & B both alive). +Google Test trace: +googletest-output-test_.cc:#: Trace A +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #3 (in thread B, trace A & B both alive). +Google Test trace: +googletest-output-test_.cc:#: Trace B +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #4 (in thread B, only trace A alive). +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #5 (in thread A, only trace A alive). +Google Test trace: +googletest-output-test_.cc:#: Trace A +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #6 (in thread A, no trace alive). +Stack trace: (omitted) + +[ FAILED ] SCOPED_TRACETest.WorksConcurrently +[----------] 1 test from ScopedTraceTest +[ RUN ] ScopedTraceTest.WithExplicitFileAndLine +googletest-output-test_.cc:#: Failure +Failed +Check that the trace is attached to a particular location. +Google Test trace: +explicit_file.cc:123: expected trace message +Stack trace: (omitted) + +[ FAILED ] ScopedTraceTest.WithExplicitFileAndLine +[----------] 1 test from NonFatalFailureInFixtureConstructorTest +[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 5 failures) +googletest-output-test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #2, in SetUp(). +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #3, in the test body. +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #4, in TearDown. +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #5, in the test fixture d'tor. +Stack trace: (omitted) + +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from FatalFailureInFixtureConstructorTest +[ RUN ] FatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 2 failures) +googletest-output-test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #2, in the test fixture d'tor. +Stack trace: (omitted) + +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from NonFatalFailureInSetUpTest +[ RUN ] NonFatalFailureInSetUpTest.FailureInSetUp +(expecting 4 failures) +googletest-output-test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #2, in the test function. +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #3, in TearDown(). +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #4, in the test fixture d'tor. +Stack trace: (omitted) + +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from FatalFailureInSetUpTest +[ RUN ] FatalFailureInSetUpTest.FailureInSetUp +(expecting 3 failures) +googletest-output-test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #2, in TearDown(). +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected failure #3, in the test fixture d'tor. +Stack trace: (omitted) + +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from AddFailureAtTest +[ RUN ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +foo.cc:42: Failure +Failed +Expected nonfatal failure in foo.cc +Stack trace: (omitted) + +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +[----------] 1 test from GtestFailAtTest +[ RUN ] GtestFailAtTest.MessageContainsSpecifiedFileAndLineNumber +foo.cc:42: Failure +Failed +Expected fatal failure in foo.cc +Stack trace: (omitted) + +[ FAILED ] GtestFailAtTest.MessageContainsSpecifiedFileAndLineNumber +[----------] 4 tests from MixedUpTestSuiteTest +[ RUN ] MixedUpTestSuiteTest.FirstTestFromNamespaceFoo +[ OK ] MixedUpTestSuiteTest.FirstTestFromNamespaceFoo +[ RUN ] MixedUpTestSuiteTest.SecondTestFromNamespaceFoo +[ OK ] MixedUpTestSuiteTest.SecondTestFromNamespaceFoo +[ RUN ] MixedUpTestSuiteTest.ThisShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test suite must use the same test fixture +class. However, in test suite MixedUpTestSuiteTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test suites. +Stack trace: (omitted) + +[ FAILED ] MixedUpTestSuiteTest.ThisShouldFail +[ RUN ] MixedUpTestSuiteTest.ThisShouldFailToo +gtest.cc:#: Failure +Failed +All tests in the same test suite must use the same test fixture +class. However, in test suite MixedUpTestSuiteTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test suites. +Stack trace: (omitted) + +[ FAILED ] MixedUpTestSuiteTest.ThisShouldFailToo +[----------] 2 tests from MixedUpTestSuiteWithSameTestNameTest +[ RUN ] MixedUpTestSuiteWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ OK ] MixedUpTestSuiteWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ RUN ] MixedUpTestSuiteWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test suite must use the same test fixture +class. However, in test suite MixedUpTestSuiteWithSameTestNameTest, +you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test suites. +Stack trace: (omitted) + +[ FAILED ] MixedUpTestSuiteWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[----------] 2 tests from TEST_F_before_TEST_in_same_test_case +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test suite must use the same test fixture +class, so mixing TEST_F and TEST in the same test suite is +illegal. In test suite TEST_F_before_TEST_in_same_test_case, +test DefinedUsingTEST_F is defined using TEST_F but +test DefinedUsingTESTAndShouldFail is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +Stack trace: (omitted) + +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[----------] 2 tests from TEST_before_TEST_F_in_same_test_case +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test suite must use the same test fixture +class, so mixing TEST_F and TEST in the same test suite is +illegal. In test suite TEST_before_TEST_F_in_same_test_case, +test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but +test DefinedUsingTEST is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +Stack trace: (omitted) + +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[----------] 8 tests from ExpectNonfatalFailureTest +[ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ RUN ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +Stack trace: (omitted) + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 2 failures +googletest-output-test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 1. +Stack trace: (omitted) + + +googletest-output-test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 2. +Stack trace: (omitted) + + +Stack trace: (omitted) + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +googletest-output-test_.cc:#: Fatal failure: +Failed +Expected fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +Stack trace: (omitted) + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +Stack trace: (omitted) + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[----------] 8 tests from ExpectFatalFailureTest +[ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ RUN ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +Stack trace: (omitted) + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 2 failures +googletest-output-test_.cc:#: Fatal failure: +Failed +Expected fatal failure. +Stack trace: (omitted) + + +googletest-output-test_.cc:#: Fatal failure: +Failed +Expected fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +googletest-output-test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +Stack trace: (omitted) + +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +Stack trace: (omitted) + +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows +[----------] 2 tests from TypedTest/0, where TypeParam = int +[ RUN ] TypedTest/0.Success +[ OK ] TypedTest/0.Success +[ RUN ] TypedTest/0.Failure +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1 + TypeParam() + Which is: 0 +Expected failure +Stack trace: (omitted) + +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[----------] 2 tests from TypedTestWithNames/char0, where TypeParam = char +[ RUN ] TypedTestWithNames/char0.Success +[ OK ] TypedTestWithNames/char0.Success +[ RUN ] TypedTestWithNames/char0.Failure +googletest-output-test_.cc:#: Failure +Failed +Stack trace: (omitted) + +[ FAILED ] TypedTestWithNames/char0.Failure, where TypeParam = char +[----------] 2 tests from TypedTestWithNames/int1, where TypeParam = int +[ RUN ] TypedTestWithNames/int1.Success +[ OK ] TypedTestWithNames/int1.Success +[ RUN ] TypedTestWithNames/int1.Failure +googletest-output-test_.cc:#: Failure +Failed +Stack trace: (omitted) + +[ FAILED ] TypedTestWithNames/int1.Failure, where TypeParam = int +[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char +[ RUN ] Unsigned/TypedTestP/0.Success +[ OK ] Unsigned/TypedTestP/0.Success +[ RUN ] Unsigned/TypedTestP/0.Failure +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1U + Which is: 1 + TypeParam() + Which is: '\0' +Expected failure +Stack trace: (omitted) + +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int +[ RUN ] Unsigned/TypedTestP/1.Success +[ OK ] Unsigned/TypedTestP/1.Success +[ RUN ] Unsigned/TypedTestP/1.Failure +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1U + Which is: 1 + TypeParam() + Which is: 0 +Expected failure +Stack trace: (omitted) + +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[----------] 2 tests from UnsignedCustomName/TypedTestP/unsignedChar0, where TypeParam = unsigned char +[ RUN ] UnsignedCustomName/TypedTestP/unsignedChar0.Success +[ OK ] UnsignedCustomName/TypedTestP/unsignedChar0.Success +[ RUN ] UnsignedCustomName/TypedTestP/unsignedChar0.Failure +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1U + Which is: 1 + TypeParam() + Which is: '\0' +Expected failure +Stack trace: (omitted) + +[ FAILED ] UnsignedCustomName/TypedTestP/unsignedChar0.Failure, where TypeParam = unsigned char +[----------] 2 tests from UnsignedCustomName/TypedTestP/unsignedInt1, where TypeParam = unsigned int +[ RUN ] UnsignedCustomName/TypedTestP/unsignedInt1.Success +[ OK ] UnsignedCustomName/TypedTestP/unsignedInt1.Success +[ RUN ] UnsignedCustomName/TypedTestP/unsignedInt1.Failure +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1U + Which is: 1 + TypeParam() + Which is: 0 +Expected failure +Stack trace: (omitted) + +[ FAILED ] UnsignedCustomName/TypedTestP/unsignedInt1.Failure, where TypeParam = unsigned int +[----------] 4 tests from ExpectFailureTest +[ RUN ] ExpectFailureTest.ExpectFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +googletest-output-test_.cc:#: Success: +Succeeded +Stack trace: (omitted) + + +Stack trace: (omitted) + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +googletest-output-test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +googletest-output-test_.cc:#: Fatal failure: +Failed +Expected fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ RUN ] ExpectFailureTest.ExpectNonFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +googletest-output-test_.cc:#: Success: +Succeeded +Stack trace: (omitted) + + +Stack trace: (omitted) + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +googletest-output-test_.cc:#: Fatal failure: +Failed +Expected fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +googletest-output-test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ RUN ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +googletest-output-test_.cc:#: Success: +Succeeded +Stack trace: (omitted) + + +Stack trace: (omitted) + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +googletest-output-test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +googletest-output-test_.cc:#: Fatal failure: +Failed +Expected fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ RUN ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +googletest-output-test_.cc:#: Success: +Succeeded +Stack trace: (omitted) + + +Stack trace: (omitted) + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +googletest-output-test_.cc:#: Fatal failure: +Failed +Expected fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +googletest-output-test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. +Stack trace: (omitted) + + +Stack trace: (omitted) + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[----------] 2 tests from ExpectFailureWithThreadsTest +[ RUN ] ExpectFailureWithThreadsTest.ExpectFatalFailure +(expecting 2 failures) +googletest-output-test_.cc:#: Failure +Failed +Expected fatal failure. +Stack trace: (omitted) + +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +Stack trace: (omitted) + +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ RUN ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +(expecting 2 failures) +googletest-output-test_.cc:#: Failure +Failed +Expected non-fatal failure. +Stack trace: (omitted) + +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +Stack trace: (omitted) + +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[----------] 1 test from ScopedFakeTestPartResultReporterTest +[ RUN ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +(expecting 2 failures) +googletest-output-test_.cc:#: Failure +Failed +Expected fatal failure. +Stack trace: (omitted) + +googletest-output-test_.cc:#: Failure +Failed +Expected non-fatal failure. +Stack trace: (omitted) + +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[----------] 2 tests from DynamicFixture +DynamicFixture::SetUpTestSuite +[ RUN ] DynamicFixture.DynamicTestPass +DynamicFixture() +DynamicFixture::SetUp +DynamicFixture::TearDown +~DynamicFixture() +[ OK ] DynamicFixture.DynamicTestPass +[ RUN ] DynamicFixture.DynamicTestFail +DynamicFixture() +DynamicFixture::SetUp +googletest-output-test_.cc:#: Failure +Value of: Pass + Actual: false +Expected: true +Stack trace: (omitted) + +DynamicFixture::TearDown +~DynamicFixture() +[ FAILED ] DynamicFixture.DynamicTestFail +DynamicFixture::TearDownTestSuite +[----------] 1 test from DynamicFixtureAnotherName +DynamicFixture::SetUpTestSuite +[ RUN ] DynamicFixtureAnotherName.DynamicTestPass +DynamicFixture() +DynamicFixture::SetUp +DynamicFixture::TearDown +~DynamicFixture() +[ OK ] DynamicFixtureAnotherName.DynamicTestPass +DynamicFixture::TearDownTestSuite +[----------] 2 tests from BadDynamicFixture1 +DynamicFixture::SetUpTestSuite +[ RUN ] BadDynamicFixture1.FixtureBase +DynamicFixture() +DynamicFixture::SetUp +DynamicFixture::TearDown +~DynamicFixture() +[ OK ] BadDynamicFixture1.FixtureBase +[ RUN ] BadDynamicFixture1.TestBase +DynamicFixture() +gtest.cc:#: Failure +Failed +All tests in the same test suite must use the same test fixture +class, so mixing TEST_F and TEST in the same test suite is +illegal. In test suite BadDynamicFixture1, +test FixtureBase is defined using TEST_F but +test TestBase is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +Stack trace: (omitted) + +~DynamicFixture() +[ FAILED ] BadDynamicFixture1.TestBase +DynamicFixture::TearDownTestSuite +[----------] 2 tests from BadDynamicFixture2 +DynamicFixture::SetUpTestSuite +[ RUN ] BadDynamicFixture2.FixtureBase +DynamicFixture() +DynamicFixture::SetUp +DynamicFixture::TearDown +~DynamicFixture() +[ OK ] BadDynamicFixture2.FixtureBase +[ RUN ] BadDynamicFixture2.Derived +DynamicFixture() +gtest.cc:#: Failure +Failed +All tests in the same test suite must use the same test fixture +class. However, in test suite BadDynamicFixture2, +you defined test FixtureBase and test Derived +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test suites. +Stack trace: (omitted) + +~DynamicFixture() +[ FAILED ] BadDynamicFixture2.Derived +DynamicFixture::TearDownTestSuite +[----------] 1 test from PrintingFailingParams/FailingParamTest +[ RUN ] PrintingFailingParams/FailingParamTest.Fails/0 +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1 + GetParam() + Which is: 2 +Stack trace: (omitted) + +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 +[----------] 1 test from EmptyBasenameParamInst +[ RUN ] EmptyBasenameParamInst.Passes/0 +[ OK ] EmptyBasenameParamInst.Passes/0 +[----------] 2 tests from PrintingStrings/ParamTest +[ RUN ] PrintingStrings/ParamTest.Success/a +[ OK ] PrintingStrings/ParamTest.Success/a +[ RUN ] PrintingStrings/ParamTest.Failure/a +googletest-output-test_.cc:#: Failure +Expected equality of these values: + "b" + GetParam() + Which is: "a" +Expected failure +Stack trace: (omitted) + +[ FAILED ] PrintingStrings/ParamTest.Failure/a, where GetParam() = "a" +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +googletest-output-test_.cc:#: Failure +Failed +Expected non-fatal failure. +Stack trace: (omitted) + +FooEnvironment::TearDown() called. +googletest-output-test_.cc:#: Failure +Failed +Expected fatal failure. +Stack trace: (omitted) + +[==========] 85 tests from 40 test suites ran. +[ PASSED ] 31 tests. +[ FAILED ] 54 tests, listed below: +[ FAILED ] NonfatalFailureTest.EscapesStringOperands +[ FAILED ] NonfatalFailureTest.DiffForLongStrings +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[ FAILED ] SCOPED_TRACETest.AcceptedValues +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ FAILED ] SCOPED_TRACETest.WorksConcurrently +[ FAILED ] ScopedTraceTest.WithExplicitFileAndLine +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +[ FAILED ] GtestFailAtTest.MessageContainsSpecifiedFileAndLineNumber +[ FAILED ] MixedUpTestSuiteTest.ThisShouldFail +[ FAILED ] MixedUpTestSuiteTest.ThisShouldFailToo +[ FAILED ] MixedUpTestSuiteWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[ FAILED ] TypedTestWithNames/char0.Failure, where TypeParam = char +[ FAILED ] TypedTestWithNames/int1.Failure, where TypeParam = int +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[ FAILED ] UnsignedCustomName/TypedTestP/unsignedChar0.Failure, where TypeParam = unsigned char +[ FAILED ] UnsignedCustomName/TypedTestP/unsignedInt1.Failure, where TypeParam = unsigned int +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[ FAILED ] DynamicFixture.DynamicTestFail +[ FAILED ] BadDynamicFixture1.TestBase +[ FAILED ] BadDynamicFixture2.Derived +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 +[ FAILED ] PrintingStrings/ParamTest.Failure/a, where GetParam() = "a" + +54 FAILED TESTS + YOU HAVE 1 DISABLED TEST + +Note: Google Test filter = FatalFailureTest.*:LoggingTest.* +[==========] Running 4 tests from 2 test suites. +[----------] Global test environment set-up. +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1 + x + Which is: 2 +Stack trace: (omitted) + +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine (? ms) +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +googletest-output-test_.cc:#: Failure +Expected equality of these values: + 1 + x + Which is: 2 +Stack trace: (omitted) + +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms) +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +googletest-output-test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +Stack trace: (omitted) + +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine (? ms) +[----------] 3 tests from FatalFailureTest (? ms total) + +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +googletest-output-test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +Stack trace: (omitted) + +i == 2 +i == 3 +googletest-output-test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +Stack trace: (omitted) + +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions (? ms) +[----------] 1 test from LoggingTest (? ms total) + +[----------] Global test environment tear-down +[==========] 4 tests from 2 test suites ran. (? ms total) +[ PASSED ] 0 tests. +[ FAILED ] 4 tests, listed below: +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions + + 4 FAILED TESTS +Note: Google Test filter = *DISABLED_* +[==========] Running 1 test from 1 test suite. +[----------] Global test environment set-up. +[----------] 1 test from DisabledTestsWarningTest +[ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[----------] Global test environment tear-down +[==========] 1 test from 1 test suite ran. +[ PASSED ] 1 test. +Note: Google Test filter = PassingTest.* +Note: This is test shard 2 of 2. +[==========] Running 1 test from 1 test suite. +[----------] Global test environment set-up. +[----------] 1 test from PassingTest +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] Global test environment tear-down +[==========] 1 test from 1 test suite ran. +[ PASSED ] 1 test. diff --git a/3rdparty/gtest/test/googletest-output-test.py b/3rdparty/gtest/test/googletest-output-test.py new file mode 100644 index 0000000..c727f17 --- /dev/null +++ b/3rdparty/gtest/test/googletest-output-test.py @@ -0,0 +1,346 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests the text output of Google C++ Testing and Mocking Framework. + +To update the golden file: +googletest_output_test.py --build_dir=BUILD/DIR --gengolden +where BUILD/DIR contains the built googletest-output-test_ file. +googletest_output_test.py --gengolden +googletest_output_test.py +""" + +import difflib +import os +import re +import sys +import gtest_test_utils + + +# The flag for generating the golden file +GENGOLDEN_FLAG = '--gengolden' +CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS' + +# The flag indicating stacktraces are not supported +NO_STACKTRACE_SUPPORT_FLAG = '--no_stacktrace_support' + +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' +IS_WINDOWS = os.name == 'nt' + +GOLDEN_NAME = 'googletest-output-test-golden-lin.txt' + +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('googletest-output-test_') + +# At least one command we exercise must not have the +# 'internal_skip_environment_and_ad_hoc_tests' argument. +COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests']) +COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes']) +COMMAND_WITH_TIME = ({}, [PROGRAM_PATH, + '--gtest_print_time', + 'internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=FatalFailureTest.*:LoggingTest.*']) +COMMAND_WITH_DISABLED = ( + {}, [PROGRAM_PATH, + '--gtest_also_run_disabled_tests', + 'internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=*DISABLED_*']) +COMMAND_WITH_SHARDING = ( + {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, + [PROGRAM_PATH, + 'internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=PassingTest.*']) + +GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) + + +def ToUnixLineEnding(s): + """Changes all Windows/Mac line endings in s to UNIX line endings.""" + + return s.replace('\r\n', '\n').replace('\r', '\n') + + +def RemoveLocations(test_output): + """Removes all file location info from a Google Test program's output. + + Args: + test_output: the output of a Google Test program. + + Returns: + output with all file location info (in the form of + 'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or + 'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by + 'FILE_NAME:#: '. + """ + + return re.sub(r'.*[/\\]((googletest-output-test_|gtest).cc)(\:\d+|\(\d+\))\: ', + r'\1:#: ', test_output) + + +def RemoveStackTraceDetails(output): + """Removes all stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', + 'Stack trace: (omitted)\n\n', output) + + +def RemoveStackTraces(output): + """Removes all traces of stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output) + + +def RemoveTime(output): + """Removes all time information from a Google Test program's output.""" + + return re.sub(r'\(\d+ ms', '(? ms', output) + + +def RemoveTypeInfoDetails(test_output): + """Removes compiler-specific type info from Google Test program's output. + + Args: + test_output: the output of a Google Test program. + + Returns: + output with type information normalized to canonical form. + """ + + # some compilers output the name of type 'unsigned int' as 'unsigned' + return re.sub(r'unsigned int', 'unsigned', test_output) + + +def NormalizeToCurrentPlatform(test_output): + """Normalizes platform specific output details for easier comparison.""" + + if IS_WINDOWS: + # Removes the color information that is not present on Windows. + test_output = re.sub('\x1b\\[(0;3\d)?m', '', test_output) + # Changes failure message headers into the Windows format. + test_output = re.sub(r': Failure\n', r': error: ', test_output) + # Changes file(line_number) to file:line_number. + test_output = re.sub(r'((\w|\.)+)\((\d+)\):', r'\1:\3:', test_output) + + return test_output + + +def RemoveTestCounts(output): + """Removes test counts from a Google Test program's output.""" + + output = re.sub(r'\d+ tests?, listed below', + '? tests, listed below', output) + output = re.sub(r'\d+ FAILED TESTS', + '? FAILED TESTS', output) + output = re.sub(r'\d+ tests? from \d+ test cases?', + '? tests from ? test cases', output) + output = re.sub(r'\d+ tests? from ([a-zA-Z_])', + r'? tests from \1', output) + return re.sub(r'\d+ tests?\.', '? tests.', output) + + +def RemoveMatchingTests(test_output, pattern): + """Removes output of specified tests from a Google Test program's output. + + This function strips not only the beginning and the end of a test but also + all output in between. + + Args: + test_output: A string containing the test output. + pattern: A regex string that matches names of test cases or + tests to remove. + + Returns: + Contents of test_output with tests whose names match pattern removed. + """ + + test_output = re.sub( + r'.*\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % ( + pattern, pattern), + '', + test_output) + return re.sub(r'.*%s.*\n' % pattern, '', test_output) + + +def NormalizeOutput(output): + """Normalizes output (the output of googletest-output-test_.exe).""" + + output = ToUnixLineEnding(output) + output = RemoveLocations(output) + output = RemoveStackTraceDetails(output) + output = RemoveTime(output) + return output + + +def GetShellCommandOutput(env_cmd): + """Runs a command in a sub-process, and returns its output in a string. + + Args: + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. + + Returns: + A string with the command's combined standard and diagnostic output. + """ + + # Spawns cmd in a sub-process, and gets its standard I/O file objects. + # Set and save the environment properly. + environ = os.environ.copy() + environ.update(env_cmd[0]) + p = gtest_test_utils.Subprocess(env_cmd[1], env=environ) + + return p.output + + +def GetCommandOutput(env_cmd): + """Runs a command and returns its output with all file location + info stripped off. + + Args: + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. + """ + + # Disables exception pop-ups on Windows. + environ, cmdline = env_cmd + environ = dict(environ) # Ensures we are modifying a copy. + environ[CATCH_EXCEPTIONS_ENV_VAR_NAME] = '1' + return NormalizeOutput(GetShellCommandOutput((environ, cmdline))) + + +def GetOutputOfAllCommands(): + """Returns concatenated output from several representative commands.""" + + return (GetCommandOutput(COMMAND_WITH_COLOR) + + GetCommandOutput(COMMAND_WITH_TIME) + + GetCommandOutput(COMMAND_WITH_DISABLED) + + GetCommandOutput(COMMAND_WITH_SHARDING)) + + +test_list = GetShellCommandOutput(COMMAND_LIST_TESTS) +SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list +SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list +SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list +SUPPORTS_STACK_TRACES = NO_STACKTRACE_SUPPORT_FLAG not in sys.argv + +CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and + SUPPORTS_TYPED_TESTS and + SUPPORTS_THREADS and + SUPPORTS_STACK_TRACES) + +class GTestOutputTest(gtest_test_utils.TestCase): + def RemoveUnsupportedTests(self, test_output): + if not SUPPORTS_DEATH_TESTS: + test_output = RemoveMatchingTests(test_output, 'DeathTest') + if not SUPPORTS_TYPED_TESTS: + test_output = RemoveMatchingTests(test_output, 'TypedTest') + test_output = RemoveMatchingTests(test_output, 'TypedDeathTest') + test_output = RemoveMatchingTests(test_output, 'TypeParamDeathTest') + if not SUPPORTS_THREADS: + test_output = RemoveMatchingTests(test_output, + 'ExpectFailureWithThreadsTest') + test_output = RemoveMatchingTests(test_output, + 'ScopedFakeTestPartResultReporterTest') + test_output = RemoveMatchingTests(test_output, + 'WorksConcurrently') + if not SUPPORTS_STACK_TRACES: + test_output = RemoveStackTraces(test_output) + + return test_output + + def testOutput(self): + output = GetOutputOfAllCommands() + + golden_file = open(GOLDEN_PATH, 'rb') + # A mis-configured source control system can cause \r appear in EOL + # sequences when we read the golden file irrespective of an operating + # system used. Therefore, we need to strip those \r's from newlines + # unconditionally. + golden = ToUnixLineEnding(golden_file.read().decode()) + golden_file.close() + + # We want the test to pass regardless of certain features being + # supported or not. + + # We still have to remove type name specifics in all cases. + normalized_actual = RemoveTypeInfoDetails(output) + normalized_golden = RemoveTypeInfoDetails(golden) + + if CAN_GENERATE_GOLDEN_FILE: + self.assertEqual(normalized_golden, normalized_actual, + '\n'.join(difflib.unified_diff( + normalized_golden.split('\n'), + normalized_actual.split('\n'), + 'golden', 'actual'))) + else: + normalized_actual = NormalizeToCurrentPlatform( + RemoveTestCounts(normalized_actual)) + normalized_golden = NormalizeToCurrentPlatform( + RemoveTestCounts(self.RemoveUnsupportedTests(normalized_golden))) + + # This code is very handy when debugging golden file differences: + if os.getenv('DEBUG_GTEST_OUTPUT_TEST'): + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_googletest-output-test_normalized_actual.txt'), 'wb').write( + normalized_actual) + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_googletest-output-test_normalized_golden.txt'), 'wb').write( + normalized_golden) + + self.assertEqual(normalized_golden, normalized_actual) + + +if __name__ == '__main__': + if NO_STACKTRACE_SUPPORT_FLAG in sys.argv: + # unittest.main() can't handle unknown flags + sys.argv.remove(NO_STACKTRACE_SUPPORT_FLAG) + + if GENGOLDEN_FLAG in sys.argv: + if CAN_GENERATE_GOLDEN_FILE: + output = GetOutputOfAllCommands() + golden_file = open(GOLDEN_PATH, 'wb') + golden_file.write(output) + golden_file.close() + else: + message = ( + """Unable to write a golden file when compiled in an environment +that does not support all the required features (death tests, +typed tests, stack traces, and multiple threads). +Please build this test and generate the golden file using Blaze on Linux.""") + + sys.stderr.write(message) + sys.exit(1) + else: + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-output-test_.cc b/3rdparty/gtest/test/googletest-output-test_.cc new file mode 100644 index 0000000..4f716d8 --- /dev/null +++ b/3rdparty/gtest/test/googletest-output-test_.cc @@ -0,0 +1,1157 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The purpose of this file is to generate Google Test output under +// various conditions. The output will then be verified by +// googletest-output-test.py to ensure that Google Test generates the +// desired messages. Therefore, most tests in this file are MEANT TO +// FAIL. + +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" +#include "src/gtest-internal-inl.h" + +#include + +#if _MSC_VER +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127 /* conditional expression is constant */) +#endif // _MSC_VER + +#if GTEST_IS_THREADSAFE +using testing::ScopedFakeTestPartResultReporter; +using testing::TestPartResultArray; + +using testing::internal::Notification; +using testing::internal::ThreadWithParam; +#endif + +namespace posix = ::testing::internal::posix; + +// Tests catching fatal failures. + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// This function calls a test subroutine, catches the fatal failure it +// generates, and then returns early. +void TryTestSubroutine() { + // Calls a subrountine that yields a fatal failure. + TestEq1(2); + + // Catches the fatal failure and aborts the test. + // + // The testing::Test:: prefix is necessary when calling + // HasFatalFailure() outside of a TEST, TEST_F, or test fixture. + if (testing::Test::HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +TEST(PassingTest, PassingTest1) { +} + +TEST(PassingTest, PassingTest2) { +} + +// Tests that parameters of failing parameterized tests are printed in the +// failing test summary. +class FailingParamTest : public testing::TestWithParam {}; + +TEST_P(FailingParamTest, Fails) { + EXPECT_EQ(1, GetParam()); +} + +// This generates a test which will fail. Google Test is expected to print +// its parameter when it outputs the list of all failed tests. +INSTANTIATE_TEST_SUITE_P(PrintingFailingParams, + FailingParamTest, + testing::Values(2)); + +// Tests that an empty value for the test suite basename yields just +// the test name without any prior / +class EmptyBasenameParamInst : public testing::TestWithParam {}; + +TEST_P(EmptyBasenameParamInst, Passes) { EXPECT_EQ(1, GetParam()); } + +INSTANTIATE_TEST_SUITE_P(, EmptyBasenameParamInst, testing::Values(1)); + +static const char kGoldenString[] = "\"Line\0 1\"\nLine 2"; + +TEST(NonfatalFailureTest, EscapesStringOperands) { + std::string actual = "actual \"string\""; + EXPECT_EQ(kGoldenString, actual); + + const char* golden = kGoldenString; + EXPECT_EQ(golden, actual); +} + +TEST(NonfatalFailureTest, DiffForLongStrings) { + std::string golden_str(kGoldenString, sizeof(kGoldenString) - 1); + EXPECT_EQ(golden_str, "Line 2"); +} + +// Tests catching a fatal failure in a subroutine. +TEST(FatalFailureTest, FatalFailureInSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + TryTestSubroutine(); +} + +// Tests catching a fatal failure in a nested subroutine. +TEST(FatalFailureTest, FatalFailureInNestedSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + // Calls a subrountine that yields a fatal failure. + TryTestSubroutine(); + + // Catches the fatal failure and aborts the test. + // + // When calling HasFatalFailure() inside a TEST, TEST_F, or test + // fixture, the testing::Test:: prefix is not needed. + if (HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +// Tests HasFatalFailure() after a failed EXPECT check. +TEST(FatalFailureTest, NonfatalFailureInSubroutine) { + printf("(expecting a failure on false)\n"); + EXPECT_TRUE(false); // Generates a nonfatal failure + ASSERT_FALSE(HasFatalFailure()); // This should succeed. +} + +// Tests interleaving user logging and Google Test assertions. +TEST(LoggingTest, InterleavingLoggingAndAssertions) { + static const int a[4] = { + 3, 9, 2, 6 + }; + + printf("(expecting 2 failures on (3) >= (a[i]))\n"); + for (int i = 0; i < static_cast(sizeof(a)/sizeof(*a)); i++) { + printf("i == %d\n", i); + EXPECT_GE(3, a[i]); + } +} + +// Tests the SCOPED_TRACE macro. + +// A helper function for testing SCOPED_TRACE. +void SubWithoutTrace(int n) { + EXPECT_EQ(1, n); + ASSERT_EQ(2, n); +} + +// Another helper function for testing SCOPED_TRACE. +void SubWithTrace(int n) { + SCOPED_TRACE(testing::Message() << "n = " << n); + + SubWithoutTrace(n); +} + +TEST(SCOPED_TRACETest, AcceptedValues) { + SCOPED_TRACE("literal string"); + SCOPED_TRACE(std::string("std::string")); + SCOPED_TRACE(1337); // streamable type + const char* null_value = nullptr; + SCOPED_TRACE(null_value); + + ADD_FAILURE() << "Just checking that all these values work fine."; +} + +// Tests that SCOPED_TRACE() obeys lexical scopes. +TEST(SCOPED_TRACETest, ObeysScopes) { + printf("(expected to fail)\n"); + + // There should be no trace before SCOPED_TRACE() is invoked. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; + + { + SCOPED_TRACE("Expected trace"); + // After SCOPED_TRACE(), a failure in the current scope should contain + // the trace. + ADD_FAILURE() << "This failure is expected, and should have a trace."; + } + + // Once the control leaves the scope of the SCOPED_TRACE(), there + // should be no trace again. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; +} + +// Tests that SCOPED_TRACE works inside a loop. +TEST(SCOPED_TRACETest, WorksInLoop) { + printf("(expected to fail)\n"); + + for (int i = 1; i <= 2; i++) { + SCOPED_TRACE(testing::Message() << "i = " << i); + + SubWithoutTrace(i); + } +} + +// Tests that SCOPED_TRACE works in a subroutine. +TEST(SCOPED_TRACETest, WorksInSubroutine) { + printf("(expected to fail)\n"); + + SubWithTrace(1); + SubWithTrace(2); +} + +// Tests that SCOPED_TRACE can be nested. +TEST(SCOPED_TRACETest, CanBeNested) { + printf("(expected to fail)\n"); + + SCOPED_TRACE(""); // A trace without a message. + + SubWithTrace(2); +} + +// Tests that multiple SCOPED_TRACEs can be used in the same scope. +TEST(SCOPED_TRACETest, CanBeRepeated) { + printf("(expected to fail)\n"); + + SCOPED_TRACE("A"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A."; + + SCOPED_TRACE("B"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A and B."; + + { + SCOPED_TRACE("C"); + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and C."; + } + + SCOPED_TRACE("D"); + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and D."; +} + +#if GTEST_IS_THREADSAFE +// Tests that SCOPED_TRACE()s can be used concurrently from multiple +// threads. Namely, an assertion should be affected by +// SCOPED_TRACE()s in its own thread only. + +// Here's the sequence of actions that happen in the test: +// +// Thread A (main) | Thread B (spawned) +// ===============================|================================ +// spawns thread B | +// -------------------------------+-------------------------------- +// waits for n1 | SCOPED_TRACE("Trace B"); +// | generates failure #1 +// | notifies n1 +// -------------------------------+-------------------------------- +// SCOPED_TRACE("Trace A"); | waits for n2 +// generates failure #2 | +// notifies n2 | +// -------------------------------|-------------------------------- +// waits for n3 | generates failure #3 +// | trace B dies +// | generates failure #4 +// | notifies n3 +// -------------------------------|-------------------------------- +// generates failure #5 | finishes +// trace A dies | +// generates failure #6 | +// -------------------------------|-------------------------------- +// waits for thread B to finish | + +struct CheckPoints { + Notification n1; + Notification n2; + Notification n3; +}; + +static void ThreadWithScopedTrace(CheckPoints* check_points) { + { + SCOPED_TRACE("Trace B"); + ADD_FAILURE() + << "Expected failure #1 (in thread B, only trace B alive)."; + check_points->n1.Notify(); + check_points->n2.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #3 (in thread B, trace A & B both alive)."; + } // Trace B dies here. + ADD_FAILURE() + << "Expected failure #4 (in thread B, only trace A alive)."; + check_points->n3.Notify(); +} + +TEST(SCOPED_TRACETest, WorksConcurrently) { + printf("(expecting 6 failures)\n"); + + CheckPoints check_points; + ThreadWithParam thread(&ThreadWithScopedTrace, &check_points, + nullptr); + check_points.n1.WaitForNotification(); + + { + SCOPED_TRACE("Trace A"); + ADD_FAILURE() + << "Expected failure #2 (in thread A, trace A & B both alive)."; + check_points.n2.Notify(); + check_points.n3.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #5 (in thread A, only trace A alive)."; + } // Trace A dies here. + ADD_FAILURE() + << "Expected failure #6 (in thread A, no trace alive)."; + thread.Join(); +} +#endif // GTEST_IS_THREADSAFE + +// Tests basic functionality of the ScopedTrace utility (most of its features +// are already tested in SCOPED_TRACETest). +TEST(ScopedTraceTest, WithExplicitFileAndLine) { + testing::ScopedTrace trace("explicit_file.cc", 123, "expected trace message"); + ADD_FAILURE() << "Check that the trace is attached to a particular location."; +} + +TEST(DisabledTestsWarningTest, + DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) { + // This test body is intentionally empty. Its sole purpose is for + // verifying that the --gtest_also_run_disabled_tests flag + // suppresses the "YOU HAVE 12 DISABLED TESTS" warning at the end of + // the test output. +} + +// Tests using assertions outside of TEST and TEST_F. +// +// This function creates two failures intentionally. +void AdHocTest() { + printf("The non-test part of the code is expected to have 2 failures.\n\n"); + EXPECT_TRUE(false); + EXPECT_EQ(2, 3); +} + +// Runs all TESTs, all TEST_Fs, and the ad hoc test. +int RunAllTests() { + AdHocTest(); + return RUN_ALL_TESTS(); +} + +// Tests non-fatal failures in the fixture constructor. +class NonFatalFailureInFixtureConstructorTest : public testing::Test { + protected: + NonFatalFailureInFixtureConstructorTest() { + printf("(expecting 5 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in the test fixture c'tor."; + } + + ~NonFatalFailureInFixtureConstructorTest() override { + ADD_FAILURE() << "Expected failure #5, in the test fixture d'tor."; + } + + void SetUp() override { ADD_FAILURE() << "Expected failure #2, in SetUp()."; } + + void TearDown() override { + ADD_FAILURE() << "Expected failure #4, in TearDown."; + } +}; + +TEST_F(NonFatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "Expected failure #3, in the test body."; +} + +// Tests fatal failures in the fixture constructor. +class FatalFailureInFixtureConstructorTest : public testing::Test { + protected: + FatalFailureInFixtureConstructorTest() { + printf("(expecting 2 failures)\n"); + Init(); + } + + ~FatalFailureInFixtureConstructorTest() override { + ADD_FAILURE() << "Expected failure #2, in the test fixture d'tor."; + } + + void SetUp() override { + ADD_FAILURE() << "UNEXPECTED failure in SetUp(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + + void TearDown() override { + ADD_FAILURE() << "UNEXPECTED failure in TearDown(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + + private: + void Init() { + FAIL() << "Expected failure #1, in the test fixture c'tor."; + } +}; + +TEST_F(FatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "UNEXPECTED failure in the test body. " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; +} + +// Tests non-fatal failures in SetUp(). +class NonFatalFailureInSetUpTest : public testing::Test { + protected: + ~NonFatalFailureInSetUpTest() override { Deinit(); } + + void SetUp() override { + printf("(expecting 4 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in SetUp()."; + } + + void TearDown() override { FAIL() << "Expected failure #3, in TearDown()."; } + + private: + void Deinit() { + FAIL() << "Expected failure #4, in the test fixture d'tor."; + } +}; + +TEST_F(NonFatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "Expected failure #2, in the test function."; +} + +// Tests fatal failures in SetUp(). +class FatalFailureInSetUpTest : public testing::Test { + protected: + ~FatalFailureInSetUpTest() override { Deinit(); } + + void SetUp() override { + printf("(expecting 3 failures)\n"); + FAIL() << "Expected failure #1, in SetUp()."; + } + + void TearDown() override { FAIL() << "Expected failure #2, in TearDown()."; } + + private: + void Deinit() { + FAIL() << "Expected failure #3, in the test fixture d'tor."; + } +}; + +TEST_F(FatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "UNEXPECTED failure in the test function. " + << "We should never get here, as SetUp() failed."; +} + +TEST(AddFailureAtTest, MessageContainsSpecifiedFileAndLineNumber) { + ADD_FAILURE_AT("foo.cc", 42) << "Expected nonfatal failure in foo.cc"; +} + +TEST(GtestFailAtTest, MessageContainsSpecifiedFileAndLineNumber) { + GTEST_FAIL_AT("foo.cc", 42) << "Expected fatal failure in foo.cc"; +} + +#if GTEST_IS_THREADSAFE + +// A unary function that may die. +void DieIf(bool should_die) { + GTEST_CHECK_(!should_die) << " - death inside DieIf()."; +} + +// Tests running death tests in a multi-threaded context. + +// Used for coordination between the main and the spawn thread. +struct SpawnThreadNotifications { + SpawnThreadNotifications() {} + + Notification spawn_thread_started; + Notification spawn_thread_ok_to_terminate; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications); +}; + +// The function to be executed in the thread spawn by the +// MultipleThreads test (below). +static void ThreadRoutine(SpawnThreadNotifications* notifications) { + // Signals the main thread that this thread has started. + notifications->spawn_thread_started.Notify(); + + // Waits for permission to finish from the main thread. + notifications->spawn_thread_ok_to_terminate.WaitForNotification(); +} + +// This is a death-test test, but it's not named with a DeathTest +// suffix. It starts threads which might interfere with later +// death tests, so it must run after all other death tests. +class DeathTestAndMultiThreadsTest : public testing::Test { + protected: + // Starts a thread and waits for it to begin. + void SetUp() override { + thread_.reset(new ThreadWithParam( + &ThreadRoutine, ¬ifications_, nullptr)); + notifications_.spawn_thread_started.WaitForNotification(); + } + // Tells the thread to finish, and reaps it. + // Depending on the version of the thread library in use, + // a manager thread might still be left running that will interfere + // with later death tests. This is unfortunate, but this class + // cleans up after itself as best it can. + void TearDown() override { + notifications_.spawn_thread_ok_to_terminate.Notify(); + } + + private: + SpawnThreadNotifications notifications_; + std::unique_ptr > thread_; +}; + +#endif // GTEST_IS_THREADSAFE + +// The MixedUpTestSuiteTest test case verifies that Google Test will fail a +// test if it uses a different fixture class than what other tests in +// the same test case use. It deliberately contains two fixture +// classes with the same name but defined in different namespaces. + +// The MixedUpTestSuiteWithSameTestNameTest test case verifies that +// when the user defines two tests with the same test case name AND +// same test name (but in different namespaces), the second test will +// fail. + +namespace foo { + +class MixedUpTestSuiteTest : public testing::Test { +}; + +TEST_F(MixedUpTestSuiteTest, FirstTestFromNamespaceFoo) {} +TEST_F(MixedUpTestSuiteTest, SecondTestFromNamespaceFoo) {} + +class MixedUpTestSuiteWithSameTestNameTest : public testing::Test { +}; + +TEST_F(MixedUpTestSuiteWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace foo + +namespace bar { + +class MixedUpTestSuiteTest : public testing::Test { +}; + +// The following two tests are expected to fail. We rely on the +// golden file to check that Google Test generates the right error message. +TEST_F(MixedUpTestSuiteTest, ThisShouldFail) {} +TEST_F(MixedUpTestSuiteTest, ThisShouldFailToo) {} + +class MixedUpTestSuiteWithSameTestNameTest : public testing::Test { +}; + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(MixedUpTestSuiteWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace bar + +// The following two test cases verify that Google Test catches the user +// error of mixing TEST and TEST_F in the same test case. The first +// test case checks the scenario where TEST_F appears before TEST, and +// the second one checks where TEST appears before TEST_F. + +class TEST_F_before_TEST_in_same_test_case : public testing::Test { +}; + +TEST_F(TEST_F_before_TEST_in_same_test_case, DefinedUsingTEST_F) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST(TEST_F_before_TEST_in_same_test_case, DefinedUsingTESTAndShouldFail) {} + +class TEST_before_TEST_F_in_same_test_case : public testing::Test { +}; + +TEST(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST_FAndShouldFail) { +} + +// Used for testing EXPECT_NONFATAL_FAILURE() and EXPECT_FATAL_FAILURE(). +int global_integer = 0; + +// Tests that EXPECT_NONFATAL_FAILURE() can reference global variables. +TEST(ExpectNonfatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(1, global_integer) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() can reference local variables +// (static or not). +TEST(ExpectNonfatalFailureTest, CanReferenceLocalVariables) { + int m = 0; + static int n; + n = 1; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(m, n) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() succeeds when there is exactly +// one non-fatal failure and no fatal failure. +TEST(ExpectNonfatalFailureTest, SucceedsWhenThereIsOneNonfatalFailure) { + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is no +// non-fatal failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsNoNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there are two +// non-fatal failures. +TEST(ExpectNonfatalFailureTest, FailsWhenThereAreTwoNonfatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure 1."; + ADD_FAILURE() << "Expected non-fatal failure 2."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is one fatal +// failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsOneFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_NONFATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() can reference global variables. +TEST(ExpectFatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(1, global_integer) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() can reference local static +// variables. +TEST(ExpectFatalFailureTest, CanReferenceLocalStaticVariables) { + static int n; + n = 1; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(0, n) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() succeeds when there is exactly +// one fatal failure and no non-fatal failure. +TEST(ExpectFatalFailureTest, SucceedsWhenThereIsOneFatalFailure) { + EXPECT_FATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is no fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsNoFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + }, ""); +} + +// A helper for generating a fatal failure. +void FatalFailure() { + FAIL() << "Expected fatal failure."; +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there are two +// fatal failures. +TEST(ExpectFatalFailureTest, FailsWhenThereAreTwoFatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + FatalFailure(); + FatalFailure(); + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is one non-fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsOneNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectFatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_FATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// This #ifdef block tests the output of value-parameterized tests. + +std::string ParamNameFunc(const testing::TestParamInfo& info) { + return info.param; +} + +class ParamTest : public testing::TestWithParam { +}; + +TEST_P(ParamTest, Success) { + EXPECT_EQ("a", GetParam()); +} + +TEST_P(ParamTest, Failure) { + EXPECT_EQ("b", GetParam()) << "Expected failure"; +} + +INSTANTIATE_TEST_SUITE_P(PrintingStrings, + ParamTest, + testing::Values(std::string("a")), + ParamNameFunc); + +// This #ifdef block tests the output of typed tests. +#if GTEST_HAS_TYPED_TEST + +template +class TypedTest : public testing::Test { +}; + +TYPED_TEST_SUITE(TypedTest, testing::Types); + +TYPED_TEST(TypedTest, Success) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST(TypedTest, Failure) { + EXPECT_EQ(1, TypeParam()) << "Expected failure"; +} + +typedef testing::Types TypesForTestWithNames; + +template +class TypedTestWithNames : public testing::Test {}; + +class TypedTestNames { + public: + template + static std::string GetName(int i) { + if (std::is_same::value) + return std::string("char") + ::testing::PrintToString(i); + if (std::is_same::value) + return std::string("int") + ::testing::PrintToString(i); + } +}; + +TYPED_TEST_SUITE(TypedTestWithNames, TypesForTestWithNames, TypedTestNames); + +TYPED_TEST(TypedTestWithNames, Success) {} + +TYPED_TEST(TypedTestWithNames, Failure) { FAIL(); } + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests the output of type-parameterized tests. +#if GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public testing::Test { +}; + +TYPED_TEST_SUITE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, Success) { + EXPECT_EQ(0U, TypeParam()); +} + +TYPED_TEST_P(TypedTestP, Failure) { + EXPECT_EQ(1U, TypeParam()) << "Expected failure"; +} + +REGISTER_TYPED_TEST_SUITE_P(TypedTestP, Success, Failure); + +typedef testing::Types UnsignedTypes; +INSTANTIATE_TYPED_TEST_SUITE_P(Unsigned, TypedTestP, UnsignedTypes); + +class TypedTestPNames { + public: + template + static std::string GetName(int i) { + if (std::is_same::value) { + return std::string("unsignedChar") + ::testing::PrintToString(i); + } + if (std::is_same::value) { + return std::string("unsignedInt") + ::testing::PrintToString(i); + } + } +}; + +INSTANTIATE_TYPED_TEST_SUITE_P(UnsignedCustomName, TypedTestP, UnsignedTypes, + TypedTestPNames); + +#endif // GTEST_HAS_TYPED_TEST_P + +#if GTEST_HAS_DEATH_TEST + +// We rely on the golden file to verify that tests whose test case +// name ends with DeathTest are run first. + +TEST(ADeathTest, ShouldRunFirst) { +} + +# if GTEST_HAS_TYPED_TEST + +// We rely on the golden file to verify that typed tests whose test +// case name ends with DeathTest are run first. + +template +class ATypedDeathTest : public testing::Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_SUITE(ATypedDeathTest, NumericTypes); + +TYPED_TEST(ATypedDeathTest, ShouldRunFirst) { +} + +# endif // GTEST_HAS_TYPED_TEST + +# if GTEST_HAS_TYPED_TEST_P + + +// We rely on the golden file to verify that type-parameterized tests +// whose test case name ends with DeathTest are run first. + +template +class ATypeParamDeathTest : public testing::Test { +}; + +TYPED_TEST_SUITE_P(ATypeParamDeathTest); + +TYPED_TEST_P(ATypeParamDeathTest, ShouldRunFirst) { +} + +REGISTER_TYPED_TEST_SUITE_P(ATypeParamDeathTest, ShouldRunFirst); + +INSTANTIATE_TYPED_TEST_SUITE_P(My, ATypeParamDeathTest, NumericTypes); + +# endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_HAS_DEATH_TEST + +// Tests various failure conditions of +// EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS}. +class ExpectFailureTest : public testing::Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + FAIL() << "Expected fatal failure."; + } else { + ADD_FAILURE() << "Expected non-fatal failure."; + } + } +}; + +TEST_F(ExpectFailureTest, ExpectFatalFailure) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Expected non-fatal " + "failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Some other fatal failure " + "expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(SUCCEED(), "Expected non-fatal failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Some other non-fatal " + "failure."); +} + +#if GTEST_IS_THREADSAFE + +class ExpectFailureWithThreadsTest : public ExpectFailureTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + ThreadWithParam thread(&AddFailure, failure, nullptr); + thread.Join(); + } +}; + +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_FATAL_FAILURE(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_NONFATAL_FAILURE(AddFailureInOtherThread(NONFATAL_FAILURE), + "Expected non-fatal failure."); +} + +typedef ExpectFailureWithThreadsTest ScopedFakeTestPartResultReporterTest; + +// Tests that the ScopedFakeTestPartResultReporter only catches failures from +// the current thread if it is instantiated with INTERCEPT_ONLY_CURRENT_THREAD. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) { + printf("(expecting 2 failures)\n"); + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailureInOtherThread(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + } + // The two failures should not have been intercepted. + EXPECT_EQ(0, results.size()) << "This shouldn't fail."; +} + +#endif // GTEST_IS_THREADSAFE + +TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Some other fatal failure expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected non-fatal " + "failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Some other non-fatal failure."); +} + +class DynamicFixture : public testing::Test { + protected: + DynamicFixture() { printf("DynamicFixture()\n"); } + ~DynamicFixture() override { printf("~DynamicFixture()\n"); } + void SetUp() override { printf("DynamicFixture::SetUp\n"); } + void TearDown() override { printf("DynamicFixture::TearDown\n"); } + + static void SetUpTestSuite() { printf("DynamicFixture::SetUpTestSuite\n"); } + static void TearDownTestSuite() { + printf("DynamicFixture::TearDownTestSuite\n"); + } +}; + +template +class DynamicTest : public DynamicFixture { + public: + void TestBody() override { EXPECT_TRUE(Pass); } +}; + +auto dynamic_test = ( + // Register two tests with the same fixture correctly. + testing::RegisterTest( + "DynamicFixture", "DynamicTestPass", nullptr, nullptr, __FILE__, + __LINE__, []() -> DynamicFixture* { return new DynamicTest; }), + testing::RegisterTest( + "DynamicFixture", "DynamicTestFail", nullptr, nullptr, __FILE__, + __LINE__, []() -> DynamicFixture* { return new DynamicTest; }), + + // Register the same fixture with another name. That's fine. + testing::RegisterTest( + "DynamicFixtureAnotherName", "DynamicTestPass", nullptr, nullptr, + __FILE__, __LINE__, + []() -> DynamicFixture* { return new DynamicTest; }), + + // Register two tests with the same fixture incorrectly. + testing::RegisterTest( + "BadDynamicFixture1", "FixtureBase", nullptr, nullptr, __FILE__, + __LINE__, []() -> DynamicFixture* { return new DynamicTest; }), + testing::RegisterTest( + "BadDynamicFixture1", "TestBase", nullptr, nullptr, __FILE__, __LINE__, + []() -> testing::Test* { return new DynamicTest; }), + + // Register two tests with the same fixture incorrectly by ommiting the + // return type. + testing::RegisterTest( + "BadDynamicFixture2", "FixtureBase", nullptr, nullptr, __FILE__, + __LINE__, []() -> DynamicFixture* { return new DynamicTest; }), + testing::RegisterTest("BadDynamicFixture2", "Derived", nullptr, nullptr, + __FILE__, __LINE__, + []() { return new DynamicTest; })); + +// Two test environments for testing testing::AddGlobalTestEnvironment(). + +class FooEnvironment : public testing::Environment { + public: + void SetUp() override { printf("%s", "FooEnvironment::SetUp() called.\n"); } + + void TearDown() override { + printf("%s", "FooEnvironment::TearDown() called.\n"); + FAIL() << "Expected fatal failure."; + } +}; + +class BarEnvironment : public testing::Environment { + public: + void SetUp() override { printf("%s", "BarEnvironment::SetUp() called.\n"); } + + void TearDown() override { + printf("%s", "BarEnvironment::TearDown() called.\n"); + ADD_FAILURE() << "Expected non-fatal failure."; + } +}; + +// The main function. +// +// The idea is to use Google Test to run all the tests we have defined (some +// of them are intended to fail), and then compare the test results +// with the "golden" file. +int main(int argc, char **argv) { + testing::GTEST_FLAG(print_time) = false; + + // We just run the tests, knowing some of them are intended to fail. + // We will use a separate Python script to compare the output of + // this program with the golden file. + + // It's hard to test InitGoogleTest() directly, as it has many + // global side effects. The following line serves as a sanity test + // for it. + testing::InitGoogleTest(&argc, argv); + bool internal_skip_environment_and_ad_hoc_tests = + std::count(argv, argv + argc, + std::string("internal_skip_environment_and_ad_hoc_tests")) > 0; + +#if GTEST_HAS_DEATH_TEST + if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { + // Skip the usual output capturing if we're running as the child + // process of an threadsafe-style death test. +# if GTEST_OS_WINDOWS + posix::FReopen("nul:", "w", stdout); +# else + posix::FReopen("/dev/null", "w", stdout); +# endif // GTEST_OS_WINDOWS + return RUN_ALL_TESTS(); + } +#endif // GTEST_HAS_DEATH_TEST + + if (internal_skip_environment_and_ad_hoc_tests) + return RUN_ALL_TESTS(); + + // Registers two global test environments. + // The golden file verifies that they are set up in the order they + // are registered, and torn down in the reverse order. + testing::AddGlobalTestEnvironment(new FooEnvironment); + testing::AddGlobalTestEnvironment(new BarEnvironment); +#if _MSC_VER +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4127 +#endif // _MSC_VER + return RunAllTests(); +} diff --git a/3rdparty/gtest/test/googletest-param-test-invalid-name1-test.py b/3rdparty/gtest/test/googletest-param-test-invalid-name1-test.py new file mode 100644 index 0000000..2a08477 --- /dev/null +++ b/3rdparty/gtest/test/googletest-param-test-invalid-name1-test.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# +# Copyright 2015 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Verifies that Google Test warns the user when not initialized properly.""" + +import gtest_test_utils + +binary_name = 'googletest-param-test-invalid-name1-test_' +COMMAND = gtest_test_utils.GetTestExecutablePath(binary_name) + + +def Assert(condition): + if not condition: + raise AssertionError + + +def TestExitCodeAndOutput(command): + """Runs the given command and verifies its exit code and output.""" + + err = ('Parameterized test name \'"InvalidWithQuotes"\' is invalid') + + p = gtest_test_utils.Subprocess(command) + Assert(p.terminated_by_signal) + + # Verify the output message contains appropriate output + Assert(err in p.output) + + +class GTestParamTestInvalidName1Test(gtest_test_utils.TestCase): + + def testExitCodeAndOutput(self): + TestExitCodeAndOutput(COMMAND) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-param-test-invalid-name1-test_.cc b/3rdparty/gtest/test/googletest-param-test-invalid-name1-test_.cc new file mode 100644 index 0000000..955d699 --- /dev/null +++ b/3rdparty/gtest/test/googletest-param-test-invalid-name1-test_.cc @@ -0,0 +1,50 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "gtest/gtest.h" + +namespace { +class DummyTest : public ::testing::TestWithParam {}; + +TEST_P(DummyTest, Dummy) { +} + +INSTANTIATE_TEST_SUITE_P(InvalidTestName, + DummyTest, + ::testing::Values("InvalidWithQuotes"), + ::testing::PrintToStringParamName()); + +} // namespace + +int main(int argc, char *argv[]) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + diff --git a/3rdparty/gtest/test/googletest-param-test-invalid-name2-test.py b/3rdparty/gtest/test/googletest-param-test-invalid-name2-test.py new file mode 100644 index 0000000..ab838f4 --- /dev/null +++ b/3rdparty/gtest/test/googletest-param-test-invalid-name2-test.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# +# Copyright 2015 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Verifies that Google Test warns the user when not initialized properly.""" + +import gtest_test_utils + +binary_name = 'googletest-param-test-invalid-name2-test_' +COMMAND = gtest_test_utils.GetTestExecutablePath(binary_name) + + +def Assert(condition): + if not condition: + raise AssertionError + + +def TestExitCodeAndOutput(command): + """Runs the given command and verifies its exit code and output.""" + + err = ('Duplicate parameterized test name \'a\'') + + p = gtest_test_utils.Subprocess(command) + Assert(p.terminated_by_signal) + + # Check for appropriate output + Assert(err in p.output) + + +class GTestParamTestInvalidName2Test(gtest_test_utils.TestCase): + + def testExitCodeAndOutput(self): + TestExitCodeAndOutput(COMMAND) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-param-test-invalid-name2-test_.cc b/3rdparty/gtest/test/googletest-param-test-invalid-name2-test_.cc new file mode 100644 index 0000000..76371df --- /dev/null +++ b/3rdparty/gtest/test/googletest-param-test-invalid-name2-test_.cc @@ -0,0 +1,55 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "gtest/gtest.h" + +namespace { +class DummyTest : public ::testing::TestWithParam {}; + +std::string StringParamTestSuffix( + const testing::TestParamInfo& info) { + return std::string(info.param); +} + +TEST_P(DummyTest, Dummy) { +} + +INSTANTIATE_TEST_SUITE_P(DuplicateTestNames, + DummyTest, + ::testing::Values("a", "b", "a", "c"), + StringParamTestSuffix); +} // namespace + +int main(int argc, char *argv[]) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + + diff --git a/3rdparty/gtest/test/googletest-param-test-test.cc b/3rdparty/gtest/test/googletest-param-test-test.cc new file mode 100644 index 0000000..6c187df --- /dev/null +++ b/3rdparty/gtest/test/googletest-param-test-test.cc @@ -0,0 +1,1055 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests for Google Test itself. This file verifies that the parameter +// generators objects produce correct parameter sequences and that +// Google Test runtime instantiates correct tests from those sequences. + +#include "gtest/gtest.h" + +# include +# include +# include +# include +# include +# include + +# include "src/gtest-internal-inl.h" // for UnitTestOptions +# include "test/googletest-param-test-test.h" + +using ::std::vector; +using ::std::sort; + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Bool; +using ::testing::Combine; +using ::testing::Message; +using ::testing::Range; +using ::testing::TestWithParam; +using ::testing::Values; +using ::testing::ValuesIn; + +using ::testing::internal::ParamGenerator; +using ::testing::internal::UnitTestOptions; + +// Prints a value to a string. +// +// FIXME: remove PrintValue() when we move matchers and +// EXPECT_THAT() from Google Mock to Google Test. At that time, we +// can write EXPECT_THAT(x, Eq(y)) to compare two tuples x and y, as +// EXPECT_THAT() and the matchers know how to print tuples. +template +::std::string PrintValue(const T& value) { + return testing::PrintToString(value); +} + +// Verifies that a sequence generated by the generator and accessed +// via the iterator object matches the expected one using Google Test +// assertions. +template +void VerifyGenerator(const ParamGenerator& generator, + const T (&expected_values)[N]) { + typename ParamGenerator::iterator it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the copy constructor.\n"; + // We cannot use EXPECT_EQ() here as the values may be tuples, + // which don't support <<. + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; + ++it; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the copy constructor.\n"; + + // Test the iterator assignment. The following lines verify that + // the sequence accessed via an iterator initialized via the + // assignment operator (as opposed to a copy constructor) matches + // just the same. + it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the assignment operator.\n"; + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; + ++it; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the assignment operator.\n"; +} + +template +void VerifyGeneratorIsEmpty(const ParamGenerator& generator) { + typename ParamGenerator::iterator it = generator.begin(); + EXPECT_TRUE(it == generator.end()); + + it = generator.begin(); + EXPECT_TRUE(it == generator.end()); +} + +// Generator tests. They test that each of the provided generator functions +// generates an expected sequence of values. The general test pattern +// instantiates a generator using one of the generator functions, +// checks the sequence produced by the generator using its iterator API, +// and then resets the iterator back to the beginning of the sequence +// and checks the sequence again. + +// Tests that iterators produced by generator functions conform to the +// ForwardIterator concept. +TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) { + const ParamGenerator gen = Range(0, 10); + ParamGenerator::iterator it = gen.begin(); + + // Verifies that iterator initialization works as expected. + ParamGenerator::iterator it2 = it; + EXPECT_TRUE(*it == *it2) << "Initialized iterators must point to the " + << "element same as its source points to"; + + // Verifies that iterator assignment works as expected. + ++it; + EXPECT_FALSE(*it == *it2); + it2 = it; + EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the " + << "element same as its source points to"; + + // Verifies that prefix operator++() returns *this. + EXPECT_EQ(&it, &(++it)) << "Result of the prefix operator++ must be " + << "refer to the original object"; + + // Verifies that the result of the postfix operator++ points to the value + // pointed to by the original iterator. + int original_value = *it; // Have to compute it outside of macro call to be + // unaffected by the parameter evaluation order. + EXPECT_EQ(original_value, *(it++)); + + // Verifies that prefix and postfix operator++() advance an iterator + // all the same. + it2 = it; + ++it; + ++it2; + EXPECT_TRUE(*it == *it2); +} + +// Tests that Range() generates the expected sequence. +TEST(RangeTest, IntRangeWithDefaultStep) { + const ParamGenerator gen = Range(0, 3); + const int expected_values[] = {0, 1, 2}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() generates the single element sequence +// as expected when provided with range limits that are equal. +TEST(RangeTest, IntRangeSingleValue) { + const ParamGenerator gen = Range(0, 1); + const int expected_values[] = {0}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() with generates empty sequence when +// supplied with an empty range. +TEST(RangeTest, IntRangeEmpty) { + const ParamGenerator gen = Range(0, 0); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence. +TEST(RangeTest, IntRangeWithCustomStep) { + const ParamGenerator gen = Range(0, 9, 3); + const int expected_values[] = {0, 3, 6}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence when the last element does not fall on the +// upper range limit. Sequences generated by Range() must not have +// elements beyond the range limits. +TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) { + const ParamGenerator gen = Range(0, 4, 3); + const int expected_values[] = {0, 3}; + VerifyGenerator(gen, expected_values); +} + +// Verifies that Range works with user-defined types that define +// copy constructor, operator=(), operator+(), and operator<(). +class DogAdder { + public: + explicit DogAdder(const char* a_value) : value_(a_value) {} + DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {} + + DogAdder operator=(const DogAdder& other) { + if (this != &other) + value_ = other.value_; + return *this; + } + DogAdder operator+(const DogAdder& other) const { + Message msg; + msg << value_.c_str() << other.value_.c_str(); + return DogAdder(msg.GetString().c_str()); + } + bool operator<(const DogAdder& other) const { + return value_ < other.value_; + } + const std::string& value() const { return value_; } + + private: + std::string value_; +}; + +TEST(RangeTest, WorksWithACustomType) { + const ParamGenerator gen = + Range(DogAdder("cat"), DogAdder("catdogdog"), DogAdder("dog")); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_STREQ("cat", it->value().c_str()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_STREQ("catdog", it->value().c_str()); + + EXPECT_TRUE(++it == gen.end()); +} + +class IntWrapper { + public: + explicit IntWrapper(int a_value) : value_(a_value) {} + IntWrapper(const IntWrapper& other) : value_(other.value_) {} + + IntWrapper operator=(const IntWrapper& other) { + value_ = other.value_; + return *this; + } + // operator+() adds a different type. + IntWrapper operator+(int other) const { return IntWrapper(value_ + other); } + bool operator<(const IntWrapper& other) const { + return value_ < other.value_; + } + int value() const { return value_; } + + private: + int value_; +}; + +TEST(RangeTest, WorksWithACustomTypeWithDifferentIncrementType) { + const ParamGenerator gen = Range(IntWrapper(0), IntWrapper(2)); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_EQ(0, it->value()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_EQ(1, it->value()); + + EXPECT_TRUE(++it == gen.end()); +} + +// Tests that ValuesIn() with an array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInArray) { + int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() with a const array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInConstArray) { + const int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Edge case. Tests that ValuesIn() with an array parameter containing a +// single element generates the single element sequence. +TEST(ValuesInTest, ValuesInSingleElementArray) { + int array[] = {42}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() generates the expected sequence for an STL +// container (vector). +TEST(ValuesInTest, ValuesInVector) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that ValuesIn() generates the expected sequence. +TEST(ValuesInTest, ValuesInIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an iterator range specifying a +// single value generates a single-element sequence. +TEST(ValuesInTest, ValuesInSingleElementIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(42); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an empty iterator range +// generates an empty sequence. +TEST(ValuesInTest, ValuesInEmptyIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + VerifyGeneratorIsEmpty(gen); +} + +// Tests that the Values() generates the expected sequence. +TEST(ValuesTest, ValuesWorks) { + const ParamGenerator gen = Values(3, 5, 8); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Values() generates the expected sequences from elements of +// different types convertible to ParamGenerator's parameter type. +TEST(ValuesTest, ValuesWorksForValuesOfCompatibleTypes) { + const ParamGenerator gen = Values(3, 5.0f, 8.0); + + const double expected_values[] = {3.0, 5.0, 8.0}; + VerifyGenerator(gen, expected_values); +} + +TEST(ValuesTest, ValuesWorksForMaxLengthList) { + const ParamGenerator gen = Values( + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500); + + const int expected_values[] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500}; + VerifyGenerator(gen, expected_values); +} + +// Edge case test. Tests that single-parameter Values() generates the sequence +// with the single value. +TEST(ValuesTest, ValuesWithSingleParameter) { + const ParamGenerator gen = Values(42); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Bool() generates sequence (false, true). +TEST(BoolTest, BoolWorks) { + const ParamGenerator gen = Bool(); + + const bool expected_values[] = {false, true}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Combine() with two parameters generates the expected sequence. +TEST(CombineTest, CombineWithTwoParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator > gen = + Combine(Values(foo, bar), Values(3, 4)); + + std::tuple expected_values[] = { + std::make_tuple(foo, 3), std::make_tuple(foo, 4), std::make_tuple(bar, 3), + std::make_tuple(bar, 4)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Combine() with three parameters generates the expected sequence. +TEST(CombineTest, CombineWithThreeParameters) { + const ParamGenerator > gen = + Combine(Values(0, 1), Values(3, 4), Values(5, 6)); + std::tuple expected_values[] = { + std::make_tuple(0, 3, 5), std::make_tuple(0, 3, 6), + std::make_tuple(0, 4, 5), std::make_tuple(0, 4, 6), + std::make_tuple(1, 3, 5), std::make_tuple(1, 3, 6), + std::make_tuple(1, 4, 5), std::make_tuple(1, 4, 6)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the first parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the second parameter. +TEST(CombineTest, CombineWithFirstParameterSingleValue) { + const ParamGenerator > gen = + Combine(Values(42), Values(0, 1)); + + std::tuple expected_values[] = {std::make_tuple(42, 0), + std::make_tuple(42, 1)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the second parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the first parameter. +TEST(CombineTest, CombineWithSecondParameterSingleValue) { + const ParamGenerator > gen = + Combine(Values(0, 1), Values(42)); + + std::tuple expected_values[] = {std::make_tuple(0, 42), + std::make_tuple(1, 42)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that when the first parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithFirstParameterEmptyRange) { + const ParamGenerator > gen = + Combine(Range(0, 0), Values(0, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that when the second parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithSecondParameterEmptyRange) { + const ParamGenerator > gen = + Combine(Values(0, 1), Range(1, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Edge case. Tests that combine works with the maximum number +// of parameters supported by Google Test (currently 10). +TEST(CombineTest, CombineWithMaxNumberOfParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator< + std::tuple > + gen = + Combine(Values(foo, bar), Values(1), Values(2), Values(3), Values(4), + Values(5), Values(6), Values(7), Values(8), Values(9)); + + std::tuple + expected_values[] = {std::make_tuple(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9), + std::make_tuple(bar, 1, 2, 3, 4, 5, 6, 7, 8, 9)}; + VerifyGenerator(gen, expected_values); +} + +class NonDefaultConstructAssignString { + public: + NonDefaultConstructAssignString(const std::string& s) : str_(s) {} + + const std::string& str() const { return str_; } + + private: + std::string str_; + + // Not default constructible + NonDefaultConstructAssignString(); + // Not assignable + void operator=(const NonDefaultConstructAssignString&); +}; + +TEST(CombineTest, NonDefaultConstructAssign) { + const ParamGenerator > gen = + Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"), + NonDefaultConstructAssignString("B"))); + + ParamGenerator >::iterator + it = gen.begin(); + + EXPECT_EQ(0, std::get<0>(*it)); + EXPECT_EQ("A", std::get<1>(*it).str()); + ++it; + + EXPECT_EQ(0, std::get<0>(*it)); + EXPECT_EQ("B", std::get<1>(*it).str()); + ++it; + + EXPECT_EQ(1, std::get<0>(*it)); + EXPECT_EQ("A", std::get<1>(*it).str()); + ++it; + + EXPECT_EQ(1, std::get<0>(*it)); + EXPECT_EQ("B", std::get<1>(*it).str()); + ++it; + + EXPECT_TRUE(it == gen.end()); +} + + +// Tests that an generator produces correct sequence after being +// assigned from another generator. +TEST(ParamGeneratorTest, AssignmentWorks) { + ParamGenerator gen = Values(1, 2); + const ParamGenerator gen2 = Values(3, 4); + gen = gen2; + + const int expected_values[] = {3, 4}; + VerifyGenerator(gen, expected_values); +} + +// This test verifies that the tests are expanded and run as specified: +// one test per element from the sequence produced by the generator +// specified in INSTANTIATE_TEST_SUITE_P. It also verifies that the test's +// fixture constructor, SetUp(), and TearDown() have run and have been +// supplied with the correct parameters. + +// The use of environment object allows detection of the case where no test +// case functionality is run at all. In this case TearDownTestSuite will not +// be able to detect missing tests, naturally. +template +class TestGenerationEnvironment : public ::testing::Environment { + public: + static TestGenerationEnvironment* Instance() { + static TestGenerationEnvironment* instance = new TestGenerationEnvironment; + return instance; + } + + void FixtureConstructorExecuted() { fixture_constructor_count_++; } + void SetUpExecuted() { set_up_count_++; } + void TearDownExecuted() { tear_down_count_++; } + void TestBodyExecuted() { test_body_count_++; } + + void TearDown() override { + // If all MultipleTestGenerationTest tests have been de-selected + // by the filter flag, the following checks make no sense. + bool perform_check = false; + + for (int i = 0; i < kExpectedCalls; ++i) { + Message msg; + msg << "TestsExpandedAndRun/" << i; + if (UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + msg.GetString().c_str())) { + perform_check = true; + } + } + if (perform_check) { + EXPECT_EQ(kExpectedCalls, fixture_constructor_count_) + << "Fixture constructor of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, set_up_count_) + << "Fixture SetUp method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, tear_down_count_) + << "Fixture TearDown method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, test_body_count_) + << "Test in ParamTestGenerationTest test case " + << "has not been run as expected."; + } + } + + private: + TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), + tear_down_count_(0), test_body_count_(0) {} + + int fixture_constructor_count_; + int set_up_count_; + int tear_down_count_; + int test_body_count_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationEnvironment); +}; + +const int test_generation_params[] = {36, 42, 72}; + +class TestGenerationTest : public TestWithParam { + public: + enum { + PARAMETER_COUNT = + sizeof(test_generation_params)/sizeof(test_generation_params[0]) + }; + + typedef TestGenerationEnvironment Environment; + + TestGenerationTest() { + Environment::Instance()->FixtureConstructorExecuted(); + current_parameter_ = GetParam(); + } + void SetUp() override { + Environment::Instance()->SetUpExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + void TearDown() override { + Environment::Instance()->TearDownExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + + static void SetUpTestSuite() { + bool all_tests_in_test_case_selected = true; + + for (int i = 0; i < PARAMETER_COUNT; ++i) { + Message test_name; + test_name << "TestsExpandedAndRun/" << i; + if ( !UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + test_name.GetString())) { + all_tests_in_test_case_selected = false; + } + } + EXPECT_TRUE(all_tests_in_test_case_selected) + << "When running the TestGenerationTest test case all of its tests\n" + << "must be selected by the filter flag for the test case to pass.\n" + << "If not all of them are enabled, we can't reliably conclude\n" + << "that the correct number of tests have been generated."; + + collected_parameters_.clear(); + } + + static void TearDownTestSuite() { + vector expected_values(test_generation_params, + test_generation_params + PARAMETER_COUNT); + // Test execution order is not guaranteed by Google Test, + // so the order of values in collected_parameters_ can be + // different and we have to sort to compare. + sort(expected_values.begin(), expected_values.end()); + sort(collected_parameters_.begin(), collected_parameters_.end()); + + EXPECT_TRUE(collected_parameters_ == expected_values); + } + + protected: + int current_parameter_; + static vector collected_parameters_; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationTest); +}; +vector TestGenerationTest::collected_parameters_; + +TEST_P(TestGenerationTest, TestsExpandedAndRun) { + Environment::Instance()->TestBodyExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + collected_parameters_.push_back(GetParam()); +} +INSTANTIATE_TEST_SUITE_P(TestExpansionModule, TestGenerationTest, + ValuesIn(test_generation_params)); + +// This test verifies that the element sequence (third parameter of +// INSTANTIATE_TEST_SUITE_P) is evaluated in InitGoogleTest() and neither at +// the call site of INSTANTIATE_TEST_SUITE_P nor in RUN_ALL_TESTS(). For +// that, we declare param_value_ to be a static member of +// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in +// main(), just before invocation of InitGoogleTest(). After calling +// InitGoogleTest(), we set the value to 2. If the sequence is evaluated +// before or after InitGoogleTest, INSTANTIATE_TEST_SUITE_P will create a +// test with parameter other than 1, and the test body will fail the +// assertion. +class GeneratorEvaluationTest : public TestWithParam { + public: + static int param_value() { return param_value_; } + static void set_param_value(int param_value) { param_value_ = param_value; } + + private: + static int param_value_; +}; +int GeneratorEvaluationTest::param_value_ = 0; + +TEST_P(GeneratorEvaluationTest, GeneratorsEvaluatedInMain) { + EXPECT_EQ(1, GetParam()); +} +INSTANTIATE_TEST_SUITE_P(GenEvalModule, GeneratorEvaluationTest, + Values(GeneratorEvaluationTest::param_value())); + +// Tests that generators defined in a different translation unit are +// functional. Generator extern_gen is defined in gtest-param-test_test2.cc. +extern ParamGenerator extern_gen; +class ExternalGeneratorTest : public TestWithParam {}; +TEST_P(ExternalGeneratorTest, ExternalGenerator) { + // Sequence produced by extern_gen contains only a single value + // which we verify here. + EXPECT_EQ(GetParam(), 33); +} +INSTANTIATE_TEST_SUITE_P(ExternalGeneratorModule, ExternalGeneratorTest, + extern_gen); + +// Tests that a parameterized test case can be defined in one translation +// unit and instantiated in another. This test will be instantiated in +// gtest-param-test_test2.cc. ExternalInstantiationTest fixture class is +// defined in gtest-param-test_test.h. +TEST_P(ExternalInstantiationTest, IsMultipleOf33) { + EXPECT_EQ(0, GetParam() % 33); +} + +// Tests that a parameterized test case can be instantiated with multiple +// generators. +class MultipleInstantiationTest : public TestWithParam {}; +TEST_P(MultipleInstantiationTest, AllowsMultipleInstances) { +} +INSTANTIATE_TEST_SUITE_P(Sequence1, MultipleInstantiationTest, Values(1, 2)); +INSTANTIATE_TEST_SUITE_P(Sequence2, MultipleInstantiationTest, Range(3, 5)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. This test will be instantiated +// here and in gtest-param-test_test2.cc. +// InstantiationInMultipleTranslationUnitsTest fixture class +// is defined in gtest-param-test_test.h. +TEST_P(InstantiationInMultipleTranslationUnitsTest, IsMultipleOf42) { + EXPECT_EQ(0, GetParam() % 42); +} +INSTANTIATE_TEST_SUITE_P(Sequence1, InstantiationInMultipleTranslationUnitsTest, + Values(42, 42 * 2)); + +// Tests that each iteration of parameterized test runs in a separate test +// object. +class SeparateInstanceTest : public TestWithParam { + public: + SeparateInstanceTest() : count_(0) {} + + static void TearDownTestSuite() { + EXPECT_GE(global_count_, 2) + << "If some (but not all) SeparateInstanceTest tests have been " + << "filtered out this test will fail. Make sure that all " + << "GeneratorEvaluationTest are selected or de-selected together " + << "by the test filter."; + } + + protected: + int count_; + static int global_count_; +}; +int SeparateInstanceTest::global_count_ = 0; + +TEST_P(SeparateInstanceTest, TestsRunInSeparateInstances) { + EXPECT_EQ(0, count_++); + global_count_++; +} +INSTANTIATE_TEST_SUITE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4)); + +// Tests that all instantiations of a test have named appropriately. Test +// defined with TEST_P(TestSuiteName, TestName) and instantiated with +// INSTANTIATE_TEST_SUITE_P(SequenceName, TestSuiteName, generator) must be +// named SequenceName/TestSuiteName.TestName/i, where i is the 0-based index of +// the sequence element used to instantiate the test. +class NamingTest : public TestWithParam {}; + +TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_suite_name()); + + Message index_stream; + index_stream << "TestsReportCorrectNamesAndParameters/" << GetParam(); + EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name()); + + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); +} + +INSTANTIATE_TEST_SUITE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); + +// Tests that macros in test names are expanded correctly. +class MacroNamingTest : public TestWithParam {}; + +#define PREFIX_WITH_FOO(test_name) Foo##test_name +#define PREFIX_WITH_MACRO(test_name) Macro##test_name + +TEST_P(PREFIX_WITH_MACRO(NamingTest), PREFIX_WITH_FOO(SomeTestName)) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_STREQ("FortyTwo/MacroNamingTest", test_info->test_suite_name()); + EXPECT_STREQ("FooSomeTestName", test_info->name()); +} + +INSTANTIATE_TEST_SUITE_P(FortyTwo, MacroNamingTest, Values(42)); + +// Tests the same thing for non-parametrized tests. +class MacroNamingTestNonParametrized : public ::testing::Test {}; + +TEST_F(PREFIX_WITH_MACRO(NamingTestNonParametrized), + PREFIX_WITH_FOO(SomeTestName)) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_STREQ("MacroNamingTestNonParametrized", test_info->test_suite_name()); + EXPECT_STREQ("FooSomeTestName", test_info->name()); +} + +// Tests that user supplied custom parameter names are working correctly. +// Runs the test with a builtin helper method which uses PrintToString, +// as well as a custom function and custom functor to ensure all possible +// uses work correctly. +class CustomFunctorNamingTest : public TestWithParam {}; +TEST_P(CustomFunctorNamingTest, CustomTestNames) {} + +struct CustomParamNameFunctor { + std::string operator()(const ::testing::TestParamInfo& inf) { + return inf.param; + } +}; + +INSTANTIATE_TEST_SUITE_P(CustomParamNameFunctor, CustomFunctorNamingTest, + Values(std::string("FunctorName")), + CustomParamNameFunctor()); + +INSTANTIATE_TEST_SUITE_P(AllAllowedCharacters, CustomFunctorNamingTest, + Values("abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "01234567890_"), + CustomParamNameFunctor()); + +inline std::string CustomParamNameFunction( + const ::testing::TestParamInfo& inf) { + return inf.param; +} + +class CustomFunctionNamingTest : public TestWithParam {}; +TEST_P(CustomFunctionNamingTest, CustomTestNames) {} + +INSTANTIATE_TEST_SUITE_P(CustomParamNameFunction, CustomFunctionNamingTest, + Values(std::string("FunctionName")), + CustomParamNameFunction); + +INSTANTIATE_TEST_SUITE_P(CustomParamNameFunctionP, CustomFunctionNamingTest, + Values(std::string("FunctionNameP")), + &CustomParamNameFunction); + +// Test custom naming with a lambda + +class CustomLambdaNamingTest : public TestWithParam {}; +TEST_P(CustomLambdaNamingTest, CustomTestNames) {} + +INSTANTIATE_TEST_SUITE_P(CustomParamNameLambda, CustomLambdaNamingTest, + Values(std::string("LambdaName")), + [](const ::testing::TestParamInfo& inf) { + return inf.param; + }); + +TEST(CustomNamingTest, CheckNameRegistry) { + ::testing::UnitTest* unit_test = ::testing::UnitTest::GetInstance(); + std::set test_names; + for (int suite_num = 0; suite_num < unit_test->total_test_suite_count(); + ++suite_num) { + const ::testing::TestSuite* test_suite = unit_test->GetTestSuite(suite_num); + for (int test_num = 0; test_num < test_suite->total_test_count(); + ++test_num) { + const ::testing::TestInfo* test_info = test_suite->GetTestInfo(test_num); + test_names.insert(std::string(test_info->name())); + } + } + EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctorName")); + EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctionName")); + EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctionNameP")); + EXPECT_EQ(1u, test_names.count("CustomTestNames/LambdaName")); +} + +// Test a numeric name to ensure PrintToStringParamName works correctly. + +class CustomIntegerNamingTest : public TestWithParam {}; + +TEST_P(CustomIntegerNamingTest, TestsReportCorrectNames) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + Message test_name_stream; + test_name_stream << "TestsReportCorrectNames/" << GetParam(); + EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name()); +} + +INSTANTIATE_TEST_SUITE_P(PrintToString, CustomIntegerNamingTest, Range(0, 5), + ::testing::PrintToStringParamName()); + +// Test a custom struct with PrintToString. + +struct CustomStruct { + explicit CustomStruct(int value) : x(value) {} + int x; +}; + +std::ostream& operator<<(std::ostream& stream, const CustomStruct& val) { + stream << val.x; + return stream; +} + +class CustomStructNamingTest : public TestWithParam {}; + +TEST_P(CustomStructNamingTest, TestsReportCorrectNames) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + Message test_name_stream; + test_name_stream << "TestsReportCorrectNames/" << GetParam(); + EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name()); +} + +INSTANTIATE_TEST_SUITE_P(PrintToString, CustomStructNamingTest, + Values(CustomStruct(0), CustomStruct(1)), + ::testing::PrintToStringParamName()); + +// Test that using a stateful parameter naming function works as expected. + +struct StatefulNamingFunctor { + StatefulNamingFunctor() : sum(0) {} + std::string operator()(const ::testing::TestParamInfo& info) { + int value = info.param + sum; + sum += info.param; + return ::testing::PrintToString(value); + } + int sum; +}; + +class StatefulNamingTest : public ::testing::TestWithParam { + protected: + StatefulNamingTest() : sum_(0) {} + int sum_; +}; + +TEST_P(StatefulNamingTest, TestsReportCorrectNames) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + sum_ += GetParam(); + Message test_name_stream; + test_name_stream << "TestsReportCorrectNames/" << sum_; + EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name()); +} + +INSTANTIATE_TEST_SUITE_P(StatefulNamingFunctor, StatefulNamingTest, Range(0, 5), + StatefulNamingFunctor()); + +// Class that cannot be streamed into an ostream. It needs to be copyable +// (and, in case of MSVC, also assignable) in order to be a test parameter +// type. Its default copy constructor and assignment operator do exactly +// what we need. +class Unstreamable { + public: + explicit Unstreamable(int value) : value_(value) {} + // -Wunused-private-field: dummy accessor for `value_`. + const int& dummy_value() const { return value_; } + + private: + int value_; +}; + +class CommentTest : public TestWithParam {}; + +TEST_P(CommentTest, TestsCorrectlyReportUnstreamableParams) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); +} + +INSTANTIATE_TEST_SUITE_P(InstantiationWithComments, CommentTest, + Values(Unstreamable(1))); + +// Verify that we can create a hierarchy of test fixtures, where the base +// class fixture is not parameterized and the derived class is. In this case +// ParameterizedDerivedTest inherits from NonParameterizedBaseTest. We +// perform simple tests on both. +class NonParameterizedBaseTest : public ::testing::Test { + public: + NonParameterizedBaseTest() : n_(17) { } + protected: + int n_; +}; + +class ParameterizedDerivedTest : public NonParameterizedBaseTest, + public ::testing::WithParamInterface { + protected: + ParameterizedDerivedTest() : count_(0) { } + int count_; + static int global_count_; +}; + +int ParameterizedDerivedTest::global_count_ = 0; + +TEST_F(NonParameterizedBaseTest, FixtureIsInitialized) { + EXPECT_EQ(17, n_); +} + +TEST_P(ParameterizedDerivedTest, SeesSequence) { + EXPECT_EQ(17, n_); + EXPECT_EQ(0, count_++); + EXPECT_EQ(GetParam(), global_count_++); +} + +class ParameterizedDeathTest : public ::testing::TestWithParam { }; + +TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) { + EXPECT_DEATH_IF_SUPPORTED(GetParam(), + ".* value-parameterized test .*"); +} + +INSTANTIATE_TEST_SUITE_P(RangeZeroToFive, ParameterizedDerivedTest, + Range(0, 5)); + +// Tests param generator working with Enums +enum MyEnums { + ENUM1 = 1, + ENUM2 = 3, + ENUM3 = 8, +}; + +class MyEnumTest : public testing::TestWithParam {}; + +TEST_P(MyEnumTest, ChecksParamMoreThanZero) { EXPECT_GE(10, GetParam()); } +INSTANTIATE_TEST_SUITE_P(MyEnumTests, MyEnumTest, + ::testing::Values(ENUM1, ENUM2, 0)); + +int main(int argc, char **argv) { + // Used in TestGenerationTest test suite. + AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); + // Used in GeneratorEvaluationTest test suite. Tests that the updated value + // will be picked up for instantiating tests in GeneratorEvaluationTest. + GeneratorEvaluationTest::set_param_value(1); + + ::testing::InitGoogleTest(&argc, argv); + + // Used in GeneratorEvaluationTest test suite. Tests that value updated + // here will NOT be used for instantiating tests in + // GeneratorEvaluationTest. + GeneratorEvaluationTest::set_param_value(2); + + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/googletest-param-test-test.h b/3rdparty/gtest/test/googletest-param-test-test.h new file mode 100644 index 0000000..6480570 --- /dev/null +++ b/3rdparty/gtest/test/googletest-param-test-test.h @@ -0,0 +1,51 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This header file provides classes and functions used internally +// for testing Google Test itself. + +#ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ +#define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ + +#include "gtest/gtest.h" + +// Test fixture for testing definition and instantiation of a test +// in separate translation units. +class ExternalInstantiationTest : public ::testing::TestWithParam { +}; + +// Test fixture for testing instantiation of a test in multiple +// translation units. +class InstantiationInMultipleTranslationUnitsTest + : public ::testing::TestWithParam { +}; + +#endif // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ diff --git a/3rdparty/gtest/test/googletest-param-test2-test.cc b/3rdparty/gtest/test/googletest-param-test2-test.cc new file mode 100644 index 0000000..2a29fb1 --- /dev/null +++ b/3rdparty/gtest/test/googletest-param-test2-test.cc @@ -0,0 +1,61 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include "gtest/gtest.h" +#include "test/googletest-param-test-test.h" + +using ::testing::Values; +using ::testing::internal::ParamGenerator; + +// Tests that generators defined in a different translation unit +// are functional. The test using extern_gen is defined +// in googletest-param-test-test.cc. +ParamGenerator extern_gen = Values(33); + +// Tests that a parameterized test case can be defined in one translation unit +// and instantiated in another. The test is defined in +// googletest-param-test-test.cc and ExternalInstantiationTest fixture class is +// defined in gtest-param-test_test.h. +INSTANTIATE_TEST_SUITE_P(MultiplesOf33, + ExternalInstantiationTest, + Values(33, 66)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. Another instantiation is defined +// in googletest-param-test-test.cc and +// InstantiationInMultipleTranslationUnitsTest fixture is defined in +// gtest-param-test_test.h +INSTANTIATE_TEST_SUITE_P(Sequence2, + InstantiationInMultipleTranslationUnitsTest, + Values(42*3, 42*4, 42*5)); + diff --git a/3rdparty/gtest/test/googletest-port-test.cc b/3rdparty/gtest/test/googletest-port-test.cc new file mode 100644 index 0000000..60d637c --- /dev/null +++ b/3rdparty/gtest/test/googletest-port-test.cc @@ -0,0 +1,1272 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// This file tests the internal cross-platform support utilities. +#include + +#include "gtest/internal/gtest-port.h" + +#if GTEST_OS_MAC +# include +#endif // GTEST_OS_MAC + +#include +#include +#include // For std::pair and std::make_pair. +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" +#include "src/gtest-internal-inl.h" + +using std::make_pair; +using std::pair; + +namespace testing { +namespace internal { + +TEST(IsXDigitTest, WorksForNarrowAscii) { + EXPECT_TRUE(IsXDigit('0')); + EXPECT_TRUE(IsXDigit('9')); + EXPECT_TRUE(IsXDigit('A')); + EXPECT_TRUE(IsXDigit('F')); + EXPECT_TRUE(IsXDigit('a')); + EXPECT_TRUE(IsXDigit('f')); + + EXPECT_FALSE(IsXDigit('-')); + EXPECT_FALSE(IsXDigit('g')); + EXPECT_FALSE(IsXDigit('G')); +} + +TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast('\x80'))); + EXPECT_FALSE(IsXDigit(static_cast('0' | '\x80'))); +} + +TEST(IsXDigitTest, WorksForWideAscii) { + EXPECT_TRUE(IsXDigit(L'0')); + EXPECT_TRUE(IsXDigit(L'9')); + EXPECT_TRUE(IsXDigit(L'A')); + EXPECT_TRUE(IsXDigit(L'F')); + EXPECT_TRUE(IsXDigit(L'a')); + EXPECT_TRUE(IsXDigit(L'f')); + + EXPECT_FALSE(IsXDigit(L'-')); + EXPECT_FALSE(IsXDigit(L'g')); + EXPECT_FALSE(IsXDigit(L'G')); +} + +TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast(0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x100))); +} + +class Base { + public: + // Copy constructor and assignment operator do exactly what we need, so we + // use them. + Base() : member_(0) {} + explicit Base(int n) : member_(n) {} + virtual ~Base() {} + int member() { return member_; } + + private: + int member_; +}; + +class Derived : public Base { + public: + explicit Derived(int n) : Base(n) {} +}; + +TEST(ImplicitCastTest, ConvertsPointers) { + Derived derived(0); + EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_(&derived)); +} + +TEST(ImplicitCastTest, CanUseInheritance) { + Derived derived(1); + Base base = ::testing::internal::ImplicitCast_(derived); + EXPECT_EQ(derived.member(), base.member()); +} + +class Castable { + public: + explicit Castable(bool* converted) : converted_(converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseNonConstCastOperator) { + bool converted = false; + Castable castable(&converted); + Base base = ::testing::internal::ImplicitCast_(castable); + EXPECT_TRUE(converted); +} + +class ConstCastable { + public: + explicit ConstCastable(bool* converted) : converted_(converted) {} + operator Base() const { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) { + bool converted = false; + const ConstCastable const_castable(&converted); + Base base = ::testing::internal::ImplicitCast_(const_castable); + EXPECT_TRUE(converted); +} + +class ConstAndNonConstCastable { + public: + ConstAndNonConstCastable(bool* converted, bool* const_converted) + : converted_(converted), const_converted_(const_converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + operator Base() const { + *const_converted_ = true; + return Base(); + } + + private: + bool* converted_; + bool* const_converted_; +}; + +TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) { + bool converted = false; + bool const_converted = false; + ConstAndNonConstCastable castable(&converted, &const_converted); + Base base = ::testing::internal::ImplicitCast_(castable); + EXPECT_TRUE(converted); + EXPECT_FALSE(const_converted); + + converted = false; + const_converted = false; + const ConstAndNonConstCastable const_castable(&converted, &const_converted); + base = ::testing::internal::ImplicitCast_(const_castable); + EXPECT_FALSE(converted); + EXPECT_TRUE(const_converted); +} + +class To { + public: + To(bool* converted) { *converted = true; } // NOLINT +}; + +TEST(ImplicitCastTest, CanUseImplicitConstructor) { + bool converted = false; + To to = ::testing::internal::ImplicitCast_(&converted); + (void)to; + EXPECT_TRUE(converted); +} + +TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { + if (AlwaysFalse()) + GTEST_CHECK_(false) << "This should never be executed; " + "It's a compilation test only."; + + if (AlwaysTrue()) + GTEST_CHECK_(true); + else + ; // NOLINT + + if (AlwaysFalse()) + ; // NOLINT + else + GTEST_CHECK_(true) << ""; +} + +TEST(GtestCheckSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + GTEST_CHECK_(true); + } + + switch (0) + case 0: + GTEST_CHECK_(true) << "Check failed in switch case"; +} + +// Verifies behavior of FormatFileLocation. +TEST(FormatFileLocationTest, FormatsFileLocation) { + EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42)); +} + +TEST(FormatFileLocationTest, FormatsUnknownFile) { + EXPECT_PRED_FORMAT2(IsSubstring, "unknown file", + FormatFileLocation(nullptr, 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(nullptr, 42)); +} + +TEST(FormatFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1)); +} + +TEST(FormatFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file:", FormatFileLocation(nullptr, -1)); +} + +// Verifies behavior of FormatCompilerIndependentFileLocation. +TEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) { + EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) { + EXPECT_EQ("unknown file:42", + FormatCompilerIndependentFileLocation(nullptr, 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(nullptr, -1)); +} + +#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX || GTEST_OS_FUCHSIA || \ + GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ + GTEST_OS_NETBSD || GTEST_OS_OPENBSD +void* ThreadFunc(void* data) { + internal::Mutex* mutex = static_cast(data); + mutex->Lock(); + mutex->Unlock(); + return nullptr; +} + +TEST(GetThreadCountTest, ReturnsCorrectValue) { + const size_t starting_count = GetThreadCount(); + pthread_t thread_id; + + internal::Mutex mutex; + { + internal::MutexLock lock(&mutex); + pthread_attr_t attr; + ASSERT_EQ(0, pthread_attr_init(&attr)); + ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); + + const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); + ASSERT_EQ(0, pthread_attr_destroy(&attr)); + ASSERT_EQ(0, status); + EXPECT_EQ(starting_count + 1, GetThreadCount()); + } + + void* dummy; + ASSERT_EQ(0, pthread_join(thread_id, &dummy)); + + // The OS may not immediately report the updated thread count after + // joining a thread, causing flakiness in this test. To counter that, we + // wait for up to .5 seconds for the OS to report the correct value. + for (int i = 0; i < 5; ++i) { + if (GetThreadCount() == starting_count) + break; + + SleepMilliseconds(100); + } + + EXPECT_EQ(starting_count, GetThreadCount()); +} +#else +TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { + EXPECT_EQ(0U, GetThreadCount()); +} +#endif // GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX || GTEST_OS_FUCHSIA + +TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { + const bool a_false_condition = false; + const char regex[] = +#ifdef _MSC_VER + "googletest-port-test\\.cc\\(\\d+\\):" +#elif GTEST_USES_POSIX_RE + "googletest-port-test\\.cc:[0-9]+" +#else + "googletest-port-test\\.cc:\\d+" +#endif // _MSC_VER + ".*a_false_condition.*Extra info.*"; + + EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info", + regex); +} + +#if GTEST_HAS_DEATH_TEST + +TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { + EXPECT_EXIT({ + GTEST_CHECK_(true) << "Extra info"; + ::std::cerr << "Success\n"; + exit(0); }, + ::testing::ExitedWithCode(0), "Success"); +} + +#endif // GTEST_HAS_DEATH_TEST + +// Verifies that Google Test choose regular expression engine appropriate to +// the platform. The test will produce compiler errors in case of failure. +// For simplicity, we only cover the most important platforms here. +TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { +#if !GTEST_USES_PCRE +# if GTEST_HAS_POSIX_RE + + EXPECT_TRUE(GTEST_USES_POSIX_RE); + +# else + + EXPECT_TRUE(GTEST_USES_SIMPLE_RE); + +# endif +#endif // !GTEST_USES_PCRE +} + +#if GTEST_USES_POSIX_RE + +# if GTEST_HAS_TYPED_TEST + +template +class RETest : public ::testing::Test {}; + +// Defines StringTypes as the list of all string types that class RE +// supports. +typedef testing::Types< ::std::string, const char*> StringTypes; + +TYPED_TEST_SUITE(RETest, StringTypes); + +// Tests RE's implicit constructors. +TYPED_TEST(RETest, ImplicitConstructorWorks) { + const RE empty(TypeParam("")); + EXPECT_STREQ("", empty.pattern()); + + const RE simple(TypeParam("hello")); + EXPECT_STREQ("hello", simple.pattern()); + + const RE normal(TypeParam(".*(\\w+)")); + EXPECT_STREQ(".*(\\w+)", normal.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TYPED_TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE invalid(TypeParam("?")); + }, "\"?\" is not a valid POSIX Extended regular expression."); +} + +// Tests RE::FullMatch(). +TYPED_TEST(RETest, FullMatchWorks) { + const RE empty(TypeParam("")); + EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty)); + EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty)); + + const RE re(TypeParam("a.*z")); + EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re)); +} + +// Tests RE::PartialMatch(). +TYPED_TEST(RETest, PartialMatchWorks) { + const RE empty(TypeParam("")); + EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty)); + + const RE re(TypeParam("a.*z")); + EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re)); + EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); +} + +# endif // GTEST_HAS_TYPED_TEST + +#elif GTEST_USES_SIMPLE_RE + +TEST(IsInSetTest, NulCharIsNotInAnySet) { + EXPECT_FALSE(IsInSet('\0', "")); + EXPECT_FALSE(IsInSet('\0', "\0")); + EXPECT_FALSE(IsInSet('\0', "a")); +} + +TEST(IsInSetTest, WorksForNonNulChars) { + EXPECT_FALSE(IsInSet('a', "Ab")); + EXPECT_FALSE(IsInSet('c', "")); + + EXPECT_TRUE(IsInSet('b', "bcd")); + EXPECT_TRUE(IsInSet('b', "ab")); +} + +TEST(IsAsciiDigitTest, IsFalseForNonDigit) { + EXPECT_FALSE(IsAsciiDigit('\0')); + EXPECT_FALSE(IsAsciiDigit(' ')); + EXPECT_FALSE(IsAsciiDigit('+')); + EXPECT_FALSE(IsAsciiDigit('-')); + EXPECT_FALSE(IsAsciiDigit('.')); + EXPECT_FALSE(IsAsciiDigit('a')); +} + +TEST(IsAsciiDigitTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiDigit('0')); + EXPECT_TRUE(IsAsciiDigit('1')); + EXPECT_TRUE(IsAsciiDigit('5')); + EXPECT_TRUE(IsAsciiDigit('9')); +} + +TEST(IsAsciiPunctTest, IsFalseForNonPunct) { + EXPECT_FALSE(IsAsciiPunct('\0')); + EXPECT_FALSE(IsAsciiPunct(' ')); + EXPECT_FALSE(IsAsciiPunct('\n')); + EXPECT_FALSE(IsAsciiPunct('a')); + EXPECT_FALSE(IsAsciiPunct('0')); +} + +TEST(IsAsciiPunctTest, IsTrueForPunct) { + for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) { + EXPECT_PRED1(IsAsciiPunct, *p); + } +} + +TEST(IsRepeatTest, IsFalseForNonRepeatChar) { + EXPECT_FALSE(IsRepeat('\0')); + EXPECT_FALSE(IsRepeat(' ')); + EXPECT_FALSE(IsRepeat('a')); + EXPECT_FALSE(IsRepeat('1')); + EXPECT_FALSE(IsRepeat('-')); +} + +TEST(IsRepeatTest, IsTrueForRepeatChar) { + EXPECT_TRUE(IsRepeat('?')); + EXPECT_TRUE(IsRepeat('*')); + EXPECT_TRUE(IsRepeat('+')); +} + +TEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) { + EXPECT_FALSE(IsAsciiWhiteSpace('\0')); + EXPECT_FALSE(IsAsciiWhiteSpace('a')); + EXPECT_FALSE(IsAsciiWhiteSpace('1')); + EXPECT_FALSE(IsAsciiWhiteSpace('+')); + EXPECT_FALSE(IsAsciiWhiteSpace('_')); +} + +TEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) { + EXPECT_TRUE(IsAsciiWhiteSpace(' ')); + EXPECT_TRUE(IsAsciiWhiteSpace('\n')); + EXPECT_TRUE(IsAsciiWhiteSpace('\r')); + EXPECT_TRUE(IsAsciiWhiteSpace('\t')); + EXPECT_TRUE(IsAsciiWhiteSpace('\v')); + EXPECT_TRUE(IsAsciiWhiteSpace('\f')); +} + +TEST(IsAsciiWordCharTest, IsFalseForNonWordChar) { + EXPECT_FALSE(IsAsciiWordChar('\0')); + EXPECT_FALSE(IsAsciiWordChar('+')); + EXPECT_FALSE(IsAsciiWordChar('.')); + EXPECT_FALSE(IsAsciiWordChar(' ')); + EXPECT_FALSE(IsAsciiWordChar('\n')); +} + +TEST(IsAsciiWordCharTest, IsTrueForLetter) { + EXPECT_TRUE(IsAsciiWordChar('a')); + EXPECT_TRUE(IsAsciiWordChar('b')); + EXPECT_TRUE(IsAsciiWordChar('A')); + EXPECT_TRUE(IsAsciiWordChar('Z')); +} + +TEST(IsAsciiWordCharTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiWordChar('0')); + EXPECT_TRUE(IsAsciiWordChar('1')); + EXPECT_TRUE(IsAsciiWordChar('7')); + EXPECT_TRUE(IsAsciiWordChar('9')); +} + +TEST(IsAsciiWordCharTest, IsTrueForUnderscore) { + EXPECT_TRUE(IsAsciiWordChar('_')); +} + +TEST(IsValidEscapeTest, IsFalseForNonPrintable) { + EXPECT_FALSE(IsValidEscape('\0')); + EXPECT_FALSE(IsValidEscape('\007')); +} + +TEST(IsValidEscapeTest, IsFalseForDigit) { + EXPECT_FALSE(IsValidEscape('0')); + EXPECT_FALSE(IsValidEscape('9')); +} + +TEST(IsValidEscapeTest, IsFalseForWhiteSpace) { + EXPECT_FALSE(IsValidEscape(' ')); + EXPECT_FALSE(IsValidEscape('\n')); +} + +TEST(IsValidEscapeTest, IsFalseForSomeLetter) { + EXPECT_FALSE(IsValidEscape('a')); + EXPECT_FALSE(IsValidEscape('Z')); +} + +TEST(IsValidEscapeTest, IsTrueForPunct) { + EXPECT_TRUE(IsValidEscape('.')); + EXPECT_TRUE(IsValidEscape('-')); + EXPECT_TRUE(IsValidEscape('^')); + EXPECT_TRUE(IsValidEscape('$')); + EXPECT_TRUE(IsValidEscape('(')); + EXPECT_TRUE(IsValidEscape(']')); + EXPECT_TRUE(IsValidEscape('{')); + EXPECT_TRUE(IsValidEscape('|')); +} + +TEST(IsValidEscapeTest, IsTrueForSomeLetter) { + EXPECT_TRUE(IsValidEscape('d')); + EXPECT_TRUE(IsValidEscape('D')); + EXPECT_TRUE(IsValidEscape('s')); + EXPECT_TRUE(IsValidEscape('S')); + EXPECT_TRUE(IsValidEscape('w')); + EXPECT_TRUE(IsValidEscape('W')); +} + +TEST(AtomMatchesCharTest, EscapedPunct) { + EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, '\\', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, '_', '.')); + EXPECT_FALSE(AtomMatchesChar(true, '.', 'a')); + + EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\')); + EXPECT_TRUE(AtomMatchesChar(true, '_', '_')); + EXPECT_TRUE(AtomMatchesChar(true, '+', '+')); + EXPECT_TRUE(AtomMatchesChar(true, '.', '.')); +} + +TEST(AtomMatchesCharTest, Escaped_d) { + EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', '.')); + + EXPECT_TRUE(AtomMatchesChar(true, 'd', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'd', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_D) { + EXPECT_FALSE(AtomMatchesChar(true, 'D', '0')); + EXPECT_FALSE(AtomMatchesChar(true, 'D', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', '-')); +} + +TEST(AtomMatchesCharTest, Escaped_s) { + EXPECT_FALSE(AtomMatchesChar(true, 's', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 's', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '.')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 's', ' ')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\t')); +} + +TEST(AtomMatchesCharTest, Escaped_S) { + EXPECT_FALSE(AtomMatchesChar(true, 'S', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r')); + + EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_w) { + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '+')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n')); + + EXPECT_TRUE(AtomMatchesChar(true, 'w', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', '_')); +} + +TEST(AtomMatchesCharTest, Escaped_W) { + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '9')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '_')); + + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '*')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n')); +} + +TEST(AtomMatchesCharTest, EscapedWhiteSpace) { + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 't', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 't', 't')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f')); + + EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f')); + EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r')); + EXPECT_TRUE(AtomMatchesChar(true, 't', '\t')); + EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v')); +} + +TEST(AtomMatchesCharTest, UnescapedDot) { + EXPECT_FALSE(AtomMatchesChar(false, '.', '\n')); + + EXPECT_TRUE(AtomMatchesChar(false, '.', '\0')); + EXPECT_TRUE(AtomMatchesChar(false, '.', '.')); + EXPECT_TRUE(AtomMatchesChar(false, '.', 'a')); + EXPECT_TRUE(AtomMatchesChar(false, '.', ' ')); +} + +TEST(AtomMatchesCharTest, UnescapedChar) { + EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0')); + EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b')); + EXPECT_FALSE(AtomMatchesChar(false, '$', 'a')); + + EXPECT_TRUE(AtomMatchesChar(false, '$', '$')); + EXPECT_TRUE(AtomMatchesChar(false, '5', '5')); + EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z')); +} + +TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) { + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)), + "NULL is not a valid simple regular expression"); + EXPECT_NONFATAL_FAILURE( + ASSERT_FALSE(ValidateRegex("a\\")), + "Syntax error at index 1 in simple regular expression \"a\\\": "); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")), + "invalid escape sequence \"\\h\""); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")), + "'(' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")), + "')' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")), + "'[' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")), + "'{' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")), + "'?' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")), + "'*' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")), + "'+' can only follow a repeatable token"); +} + +TEST(ValidateRegexTest, ReturnsTrueForValid) { + EXPECT_TRUE(ValidateRegex("")); + EXPECT_TRUE(ValidateRegex("a")); + EXPECT_TRUE(ValidateRegex(".*")); + EXPECT_TRUE(ValidateRegex("^a_+")); + EXPECT_TRUE(ValidateRegex("^a\\t\\&?")); + EXPECT_TRUE(ValidateRegex("09*$")); + EXPECT_TRUE(ValidateRegex("^Z$")); + EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba")); + // Repeating more than once. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab")); + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab")); + // Repeating zero times. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc")); + + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g")); +} + +TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) { + EXPECT_TRUE(MatchRegexAtHead("", "")); + EXPECT_TRUE(MatchRegexAtHead("", "ab")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) { + EXPECT_FALSE(MatchRegexAtHead("$", "a")); + + EXPECT_TRUE(MatchRegexAtHead("$", "")); + EXPECT_TRUE(MatchRegexAtHead("a$", "a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\w", "+")); + EXPECT_FALSE(MatchRegexAtHead("\\W", "ab")); + + EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab")); + EXPECT_TRUE(MatchRegexAtHead("\\d", "1a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) { + EXPECT_FALSE(MatchRegexAtHead(".+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("a?b", "aab")); + + EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "ab")); +} + +TEST(MatchRegexAtHeadTest, + WorksWhenRegexStartsWithRepetionOfEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b")); + + EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab")); + EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b")); +} + +TEST(MatchRegexAtHeadTest, MatchesSequentially) { + EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc")); + + EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) { + EXPECT_FALSE(MatchRegexAnywhere("", NULL)); +} + +TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) { + EXPECT_FALSE(MatchRegexAnywhere("^a", "ba")); + EXPECT_FALSE(MatchRegexAnywhere("^$", "a")); + + EXPECT_TRUE(MatchRegexAnywhere("^a", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^$", "")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) { + EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123")); + EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere(".*=", "=")); + EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "= ...=")); +} + +// Tests RE's implicit constructors. +TEST(RETest, ImplicitConstructorWorks) { + const RE empty(""); + EXPECT_STREQ("", empty.pattern()); + + const RE simple("hello"); + EXPECT_STREQ("hello", simple.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE normal(NULL); + }, "NULL is not a valid simple regular expression"); + + EXPECT_NONFATAL_FAILURE({ + const RE normal(".*(\\w+"); + }, "'(' is unsupported"); + + EXPECT_NONFATAL_FAILURE({ + const RE invalid("^?"); + }, "'?' can only follow a repeatable token"); +} + +// Tests RE::FullMatch(). +TEST(RETest, FullMatchWorks) { + const RE empty(""); + EXPECT_TRUE(RE::FullMatch("", empty)); + EXPECT_FALSE(RE::FullMatch("a", empty)); + + const RE re1("a"); + EXPECT_TRUE(RE::FullMatch("a", re1)); + + const RE re("a.*z"); + EXPECT_TRUE(RE::FullMatch("az", re)); + EXPECT_TRUE(RE::FullMatch("axyz", re)); + EXPECT_FALSE(RE::FullMatch("baz", re)); + EXPECT_FALSE(RE::FullMatch("azy", re)); +} + +// Tests RE::PartialMatch(). +TEST(RETest, PartialMatchWorks) { + const RE empty(""); + EXPECT_TRUE(RE::PartialMatch("", empty)); + EXPECT_TRUE(RE::PartialMatch("a", empty)); + + const RE re("a.*z"); + EXPECT_TRUE(RE::PartialMatch("az", re)); + EXPECT_TRUE(RE::PartialMatch("axyz", re)); + EXPECT_TRUE(RE::PartialMatch("baz", re)); + EXPECT_TRUE(RE::PartialMatch("azy", re)); + EXPECT_FALSE(RE::PartialMatch("zza", re)); +} + +#endif // GTEST_USES_POSIX_RE + +#if !GTEST_OS_WINDOWS_MOBILE + +TEST(CaptureTest, CapturesStdout) { + CaptureStdout(); + fprintf(stdout, "abc"); + EXPECT_STREQ("abc", GetCapturedStdout().c_str()); + + CaptureStdout(); + fprintf(stdout, "def%cghi", '\0'); + EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout())); +} + +TEST(CaptureTest, CapturesStderr) { + CaptureStderr(); + fprintf(stderr, "jkl"); + EXPECT_STREQ("jkl", GetCapturedStderr().c_str()); + + CaptureStderr(); + fprintf(stderr, "jkl%cmno", '\0'); + EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr())); +} + +// Tests that stdout and stderr capture don't interfere with each other. +TEST(CaptureTest, CapturesStdoutAndStderr) { + CaptureStdout(); + CaptureStderr(); + fprintf(stdout, "pqr"); + fprintf(stderr, "stu"); + EXPECT_STREQ("pqr", GetCapturedStdout().c_str()); + EXPECT_STREQ("stu", GetCapturedStderr().c_str()); +} + +TEST(CaptureDeathTest, CannotReenterStdoutCapture) { + CaptureStdout(); + EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(), + "Only one stdout capturer can exist at a time"); + GetCapturedStdout(); + + // We cannot test stderr capturing using death tests as they use it + // themselves. +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) { + ThreadLocal t1; + EXPECT_EQ(0, t1.get()); + + ThreadLocal t2; + EXPECT_TRUE(t2.get() == nullptr); +} + +TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) { + ThreadLocal t1(123); + EXPECT_EQ(123, t1.get()); + + int i = 0; + ThreadLocal t2(&i); + EXPECT_EQ(&i, t2.get()); +} + +class NoDefaultContructor { + public: + explicit NoDefaultContructor(const char*) {} + NoDefaultContructor(const NoDefaultContructor&) {} +}; + +TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { + ThreadLocal bar(NoDefaultContructor("foo")); + bar.pointer(); +} + +TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { + ThreadLocal thread_local_string; + + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); + + // Verifies the condition still holds after calling set. + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); +} + +TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { + ThreadLocal thread_local_string; + const ThreadLocal& const_thread_local_string = + thread_local_string; + + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); + + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); +} + +#if GTEST_IS_THREADSAFE + +void AddTwo(int* param) { *param += 2; } + +TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) { + int i = 40; + ThreadWithParam thread(&AddTwo, &i, nullptr); + thread.Join(); + EXPECT_EQ(42, i); +} + +TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { + // AssertHeld() is flaky only in the presence of multiple threads accessing + // the lock. In this case, the test is robust. + EXPECT_DEATH_IF_SUPPORTED({ + Mutex m; + { MutexLock lock(&m); } + m.AssertHeld(); + }, + "thread .*hold"); +} + +TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { + Mutex m; + MutexLock lock(&m); + m.AssertHeld(); +} + +class AtomicCounterWithMutex { + public: + explicit AtomicCounterWithMutex(Mutex* mutex) : + value_(0), mutex_(mutex), random_(42) {} + + void Increment() { + MutexLock lock(mutex_); + int temp = value_; + { + // We need to put up a memory barrier to prevent reads and writes to + // value_ rearranged with the call to SleepMilliseconds when observed + // from other threads. +#if GTEST_HAS_PTHREAD + // On POSIX, locking a mutex puts up a memory barrier. We cannot use + // Mutex and MutexLock here or rely on their memory barrier + // functionality as we are testing them here. + pthread_mutex_t memory_barrier_mutex; + GTEST_CHECK_POSIX_SUCCESS_( + pthread_mutex_init(&memory_barrier_mutex, nullptr)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex)); + + SleepMilliseconds(static_cast(random_.Generate(30))); + + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex)); +#elif GTEST_OS_WINDOWS + // On Windows, performing an interlocked access puts up a memory barrier. + volatile LONG dummy = 0; + ::InterlockedIncrement(&dummy); + SleepMilliseconds(static_cast(random_.Generate(30))); + ::InterlockedIncrement(&dummy); +#else +# error "Memory barrier not implemented on this platform." +#endif // GTEST_HAS_PTHREAD + } + value_ = temp + 1; + } + int value() const { return value_; } + + private: + volatile int value_; + Mutex* const mutex_; // Protects value_. + Random random_; +}; + +void CountingThreadFunc(pair param) { + for (int i = 0; i < param.second; ++i) + param.first->Increment(); +} + +// Tests that the mutex only lets one thread at a time to lock it. +TEST(MutexTest, OnlyOneThreadCanLockAtATime) { + Mutex mutex; + AtomicCounterWithMutex locked_counter(&mutex); + + typedef ThreadWithParam > ThreadType; + const int kCycleCount = 20; + const int kThreadCount = 7; + std::unique_ptr counting_threads[kThreadCount]; + Notification threads_can_start; + // Creates and runs kThreadCount threads that increment locked_counter + // kCycleCount times each. + for (int i = 0; i < kThreadCount; ++i) { + counting_threads[i].reset(new ThreadType(&CountingThreadFunc, + make_pair(&locked_counter, + kCycleCount), + &threads_can_start)); + } + threads_can_start.Notify(); + for (int i = 0; i < kThreadCount; ++i) + counting_threads[i]->Join(); + + // If the mutex lets more than one thread to increment the counter at a + // time, they are likely to encounter a race condition and have some + // increments overwritten, resulting in the lower then expected counter + // value. + EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value()); +} + +template +void RunFromThread(void (func)(T), T param) { + ThreadWithParam thread(func, param, nullptr); + thread.Join(); +} + +void RetrieveThreadLocalValue( + pair*, std::string*> param) { + *param.second = param.first->get(); +} + +TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { + ThreadLocal thread_local_string("foo"); + EXPECT_STREQ("foo", thread_local_string.get().c_str()); + + thread_local_string.set("bar"); + EXPECT_STREQ("bar", thread_local_string.get().c_str()); + + std::string result; + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); + EXPECT_STREQ("foo", result.c_str()); +} + +// Keeps track of whether of destructors being called on instances of +// DestructorTracker. On Windows, waits for the destructor call reports. +class DestructorCall { + public: + DestructorCall() { + invoked_ = false; +#if GTEST_OS_WINDOWS + wait_event_.Reset(::CreateEvent(NULL, TRUE, FALSE, NULL)); + GTEST_CHECK_(wait_event_.Get() != NULL); +#endif + } + + bool CheckDestroyed() const { +#if GTEST_OS_WINDOWS + if (::WaitForSingleObject(wait_event_.Get(), 1000) != WAIT_OBJECT_0) + return false; +#endif + return invoked_; + } + + void ReportDestroyed() { + invoked_ = true; +#if GTEST_OS_WINDOWS + ::SetEvent(wait_event_.Get()); +#endif + } + + static std::vector& List() { return *list_; } + + static void ResetList() { + for (size_t i = 0; i < list_->size(); ++i) { + delete list_->at(i); + } + list_->clear(); + } + + private: + bool invoked_; +#if GTEST_OS_WINDOWS + AutoHandle wait_event_; +#endif + static std::vector* const list_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DestructorCall); +}; + +std::vector* const DestructorCall::list_ = + new std::vector; + +// DestructorTracker keeps track of whether its instances have been +// destroyed. +class DestructorTracker { + public: + DestructorTracker() : index_(GetNewIndex()) {} + DestructorTracker(const DestructorTracker& /* rhs */) + : index_(GetNewIndex()) {} + ~DestructorTracker() { + // We never access DestructorCall::List() concurrently, so we don't need + // to protect this access with a mutex. + DestructorCall::List()[index_]->ReportDestroyed(); + } + + private: + static size_t GetNewIndex() { + DestructorCall::List().push_back(new DestructorCall); + return DestructorCall::List().size() - 1; + } + const size_t index_; + + GTEST_DISALLOW_ASSIGN_(DestructorTracker); +}; + +typedef ThreadLocal* ThreadParam; + +void CallThreadLocalGet(ThreadParam thread_local_param) { + thread_local_param->get(); +} + +// Tests that when a ThreadLocal object dies in a thread, it destroys +// the managed object for that thread. +TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { + DestructorCall::ResetList(); + + { + ThreadLocal thread_local_tracker; + ASSERT_EQ(0U, DestructorCall::List().size()); + + // This creates another DestructorTracker object for the main thread. + thread_local_tracker.get(); + ASSERT_EQ(1U, DestructorCall::List().size()); + ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); + } + + // Now thread_local_tracker has died. + ASSERT_EQ(1U, DestructorCall::List().size()); + EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); + + DestructorCall::ResetList(); +} + +// Tests that when a thread exits, the thread-local object for that +// thread is destroyed. +TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { + DestructorCall::ResetList(); + + { + ThreadLocal thread_local_tracker; + ASSERT_EQ(0U, DestructorCall::List().size()); + + // This creates another DestructorTracker object in the new thread. + ThreadWithParam thread(&CallThreadLocalGet, + &thread_local_tracker, nullptr); + thread.Join(); + + // The thread has exited, and we should have a DestroyedTracker + // instance created for it. But it may not have been destroyed yet. + ASSERT_EQ(1U, DestructorCall::List().size()); + } + + // The thread has exited and thread_local_tracker has died. + ASSERT_EQ(1U, DestructorCall::List().size()); + EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); + + DestructorCall::ResetList(); +} + +TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { + ThreadLocal thread_local_string; + thread_local_string.set("Foo"); + EXPECT_STREQ("Foo", thread_local_string.get().c_str()); + + std::string result; + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); + EXPECT_TRUE(result.empty()); +} + +#endif // GTEST_IS_THREADSAFE + +#if GTEST_OS_WINDOWS +TEST(WindowsTypesTest, HANDLEIsVoidStar) { + StaticAssertTypeEq(); +} + +#if GTEST_OS_WINDOWS_MINGW && !defined(__MINGW64_VERSION_MAJOR) +TEST(WindowsTypesTest, _CRITICAL_SECTIONIs_CRITICAL_SECTION) { + StaticAssertTypeEq(); +} +#else +TEST(WindowsTypesTest, CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION) { + StaticAssertTypeEq(); +} +#endif + +#endif // GTEST_OS_WINDOWS + +} // namespace internal +} // namespace testing diff --git a/3rdparty/gtest/test/googletest-printers-test.cc b/3rdparty/gtest/test/googletest-printers-test.cc new file mode 100644 index 0000000..4bdc9ad --- /dev/null +++ b/3rdparty/gtest/test/googletest-printers-test.cc @@ -0,0 +1,1620 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Test - The Google C++ Testing and Mocking Framework +// +// This file tests the universal value printer. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest-printers.h" +#include "gtest/gtest.h" + +// Some user-defined types for testing the universal value printer. + +// An anonymous enum type. +enum AnonymousEnum { + kAE1 = -1, + kAE2 = 1 +}; + +// An enum without a user-defined printer. +enum EnumWithoutPrinter { + kEWP1 = -2, + kEWP2 = 42 +}; + +// An enum with a << operator. +enum EnumWithStreaming { + kEWS1 = 10 +}; + +std::ostream& operator<<(std::ostream& os, EnumWithStreaming e) { + return os << (e == kEWS1 ? "kEWS1" : "invalid"); +} + +// An enum with a PrintTo() function. +enum EnumWithPrintTo { + kEWPT1 = 1 +}; + +void PrintTo(EnumWithPrintTo e, std::ostream* os) { + *os << (e == kEWPT1 ? "kEWPT1" : "invalid"); +} + +// A class implicitly convertible to BiggestInt. +class BiggestIntConvertible { + public: + operator ::testing::internal::BiggestInt() const { return 42; } +}; + +// A user-defined unprintable class template in the global namespace. +template +class UnprintableTemplateInGlobal { + public: + UnprintableTemplateInGlobal() : value_() {} + private: + T value_; +}; + +// A user-defined streamable type in the global namespace. +class StreamableInGlobal { + public: + virtual ~StreamableInGlobal() {} +}; + +inline void operator<<(::std::ostream& os, const StreamableInGlobal& /* x */) { + os << "StreamableInGlobal"; +} + +void operator<<(::std::ostream& os, const StreamableInGlobal* /* x */) { + os << "StreamableInGlobal*"; +} + +namespace foo { + +// A user-defined unprintable type in a user namespace. +class UnprintableInFoo { + public: + UnprintableInFoo() : z_(0) { memcpy(xy_, "\xEF\x12\x0\x0\x34\xAB\x0\x0", 8); } + double z() const { return z_; } + private: + char xy_[8]; + double z_; +}; + +// A user-defined printable type in a user-chosen namespace. +struct PrintableViaPrintTo { + PrintableViaPrintTo() : value() {} + int value; +}; + +void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) { + *os << "PrintableViaPrintTo: " << x.value; +} + +// A type with a user-defined << for printing its pointer. +struct PointerPrintable { +}; + +::std::ostream& operator<<(::std::ostream& os, + const PointerPrintable* /* x */) { + return os << "PointerPrintable*"; +} + +// A user-defined printable class template in a user-chosen namespace. +template +class PrintableViaPrintToTemplate { + public: + explicit PrintableViaPrintToTemplate(const T& a_value) : value_(a_value) {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +void PrintTo(const PrintableViaPrintToTemplate& x, ::std::ostream* os) { + *os << "PrintableViaPrintToTemplate: " << x.value(); +} + +// A user-defined streamable class template in a user namespace. +template +class StreamableTemplateInFoo { + public: + StreamableTemplateInFoo() : value_() {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +inline ::std::ostream& operator<<(::std::ostream& os, + const StreamableTemplateInFoo& x) { + return os << "StreamableTemplateInFoo: " << x.value(); +} + +// A user-defined streamable but recursivly-defined container type in +// a user namespace, it mimics therefore std::filesystem::path or +// boost::filesystem::path. +class PathLike { + public: + struct iterator { + typedef PathLike value_type; + + iterator& operator++(); + PathLike& operator*(); + }; + + using value_type = char; + using const_iterator = iterator; + + PathLike() {} + + iterator begin() const { return iterator(); } + iterator end() const { return iterator(); } + + friend ::std::ostream& operator<<(::std::ostream& os, const PathLike&) { + return os << "Streamable-PathLike"; + } +}; + +} // namespace foo + +namespace testing { +namespace gtest_printers_test { + +using ::std::deque; +using ::std::list; +using ::std::make_pair; +using ::std::map; +using ::std::multimap; +using ::std::multiset; +using ::std::pair; +using ::std::set; +using ::std::vector; +using ::testing::PrintToString; +using ::testing::internal::FormatForComparisonFailureMessage; +using ::testing::internal::ImplicitCast_; +using ::testing::internal::NativeArray; +using ::testing::internal::RE; +using ::testing::internal::RelationToSourceReference; +using ::testing::internal::Strings; +using ::testing::internal::UniversalPrint; +using ::testing::internal::UniversalPrinter; +using ::testing::internal::UniversalTersePrint; +using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; + +// Prints a value to a string using the universal value printer. This +// is a helper for testing UniversalPrinter::Print() for various types. +template +std::string Print(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Prints a value passed by reference to a string, using the universal +// value printer. This is a helper for testing +// UniversalPrinter::Print() for various types. +template +std::string PrintByRef(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Tests printing various enum types. + +TEST(PrintEnumTest, AnonymousEnum) { + EXPECT_EQ("-1", Print(kAE1)); + EXPECT_EQ("1", Print(kAE2)); +} + +TEST(PrintEnumTest, EnumWithoutPrinter) { + EXPECT_EQ("-2", Print(kEWP1)); + EXPECT_EQ("42", Print(kEWP2)); +} + +TEST(PrintEnumTest, EnumWithStreaming) { + EXPECT_EQ("kEWS1", Print(kEWS1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +TEST(PrintEnumTest, EnumWithPrintTo) { + EXPECT_EQ("kEWPT1", Print(kEWPT1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +// Tests printing a class implicitly convertible to BiggestInt. + +TEST(PrintClassTest, BiggestIntConvertible) { + EXPECT_EQ("42", Print(BiggestIntConvertible())); +} + +// Tests printing various char types. + +// char. +TEST(PrintCharTest, PlainChar) { + EXPECT_EQ("'\\0'", Print('\0')); + EXPECT_EQ("'\\'' (39, 0x27)", Print('\'')); + EXPECT_EQ("'\"' (34, 0x22)", Print('"')); + EXPECT_EQ("'?' (63, 0x3F)", Print('?')); + EXPECT_EQ("'\\\\' (92, 0x5C)", Print('\\')); + EXPECT_EQ("'\\a' (7)", Print('\a')); + EXPECT_EQ("'\\b' (8)", Print('\b')); + EXPECT_EQ("'\\f' (12, 0xC)", Print('\f')); + EXPECT_EQ("'\\n' (10, 0xA)", Print('\n')); + EXPECT_EQ("'\\r' (13, 0xD)", Print('\r')); + EXPECT_EQ("'\\t' (9)", Print('\t')); + EXPECT_EQ("'\\v' (11, 0xB)", Print('\v')); + EXPECT_EQ("'\\x7F' (127)", Print('\x7F')); + EXPECT_EQ("'\\xFF' (255)", Print('\xFF')); + EXPECT_EQ("' ' (32, 0x20)", Print(' ')); + EXPECT_EQ("'a' (97, 0x61)", Print('a')); +} + +// signed char. +TEST(PrintCharTest, SignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'\\xCE' (-50)", + Print(static_cast(-50))); +} + +// unsigned char. +TEST(PrintCharTest, UnsignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'b' (98, 0x62)", + Print(static_cast('b'))); +} + +// Tests printing other simple, built-in types. + +// bool. +TEST(PrintBuiltInTypeTest, Bool) { + EXPECT_EQ("false", Print(false)); + EXPECT_EQ("true", Print(true)); +} + +// wchar_t. +TEST(PrintBuiltInTypeTest, Wchar_t) { + EXPECT_EQ("L'\\0'", Print(L'\0')); + EXPECT_EQ("L'\\'' (39, 0x27)", Print(L'\'')); + EXPECT_EQ("L'\"' (34, 0x22)", Print(L'"')); + EXPECT_EQ("L'?' (63, 0x3F)", Print(L'?')); + EXPECT_EQ("L'\\\\' (92, 0x5C)", Print(L'\\')); + EXPECT_EQ("L'\\a' (7)", Print(L'\a')); + EXPECT_EQ("L'\\b' (8)", Print(L'\b')); + EXPECT_EQ("L'\\f' (12, 0xC)", Print(L'\f')); + EXPECT_EQ("L'\\n' (10, 0xA)", Print(L'\n')); + EXPECT_EQ("L'\\r' (13, 0xD)", Print(L'\r')); + EXPECT_EQ("L'\\t' (9)", Print(L'\t')); + EXPECT_EQ("L'\\v' (11, 0xB)", Print(L'\v')); + EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); + EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); + EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); + EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); + EXPECT_EQ("L'\\x576' (1398)", Print(static_cast(0x576))); + EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast(0xC74D))); +} + +// Test that Int64 provides more storage than wchar_t. +TEST(PrintTypeSizeTest, Wchar_t) { + EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64)); +} + +// Various integer types. +TEST(PrintBuiltInTypeTest, Integer) { + EXPECT_EQ("'\\xFF' (255)", Print(static_cast(255))); // uint8 + EXPECT_EQ("'\\x80' (-128)", Print(static_cast(-128))); // int8 + EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16 + EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16 + EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32 + EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32 + EXPECT_EQ("18446744073709551615", + Print(static_cast(-1))); // uint64 + EXPECT_EQ("-9223372036854775808", + Print(static_cast(1) << 63)); // int64 +} + +// Size types. +TEST(PrintBuiltInTypeTest, Size_t) { + EXPECT_EQ("1", Print(sizeof('a'))); // size_t. +#if !GTEST_OS_WINDOWS + // Windows has no ssize_t type. + EXPECT_EQ("-2", Print(static_cast(-2))); // ssize_t. +#endif // !GTEST_OS_WINDOWS +} + +// Floating-points. +TEST(PrintBuiltInTypeTest, FloatingPoints) { + EXPECT_EQ("1.5", Print(1.5f)); // float + EXPECT_EQ("-2.5", Print(-2.5)); // double +} + +// Since ::std::stringstream::operator<<(const void *) formats the pointer +// output differently with different compilers, we have to create the expected +// output first and use it as our expectation. +static std::string PrintPointer(const void* p) { + ::std::stringstream expected_result_stream; + expected_result_stream << p; + return expected_result_stream.str(); +} + +// Tests printing C strings. + +// const char*. +TEST(PrintCStringTest, Const) { + const char* p = "World"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p)); +} + +// char*. +TEST(PrintCStringTest, NonConst) { + char p[] = "Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"", + Print(static_cast(p))); +} + +// NULL C string. +TEST(PrintCStringTest, Null) { + const char* p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that C strings are escaped properly. +TEST(PrintCStringTest, EscapesProperly) { + const char* p = "'\"?\\\a\b\f\n\r\t\v\x7F\xFF a"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\x7F\\xFF a\"", + Print(p)); +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) + +// const wchar_t*. +TEST(PrintWideCStringTest, Const) { + const wchar_t* p = L"World"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p)); +} + +// wchar_t*. +TEST(PrintWideCStringTest, NonConst) { + wchar_t p[] = L"Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"", + Print(static_cast(p))); +} + +// NULL wide C string. +TEST(PrintWideCStringTest, Null) { + const wchar_t* p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that wide C strings are escaped properly. +TEST(PrintWideCStringTest, EscapesProperly) { + const wchar_t s[] = {'\'', '"', '?', '\\', '\a', '\b', '\f', '\n', '\r', + '\t', '\v', 0xD3, 0x576, 0x8D3, 0xC74D, ' ', 'a', '\0'}; + EXPECT_EQ(PrintPointer(s) + " pointing to L\"'\\\"?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", + Print(static_cast(s))); +} +#endif // native wchar_t + +// Tests printing pointers to other char types. + +// signed char*. +TEST(PrintCharPointerTest, SignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// const signed char*. +TEST(PrintCharPointerTest, ConstSignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// unsigned char*. +TEST(PrintCharPointerTest, UnsignedChar) { + unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// const unsigned char*. +TEST(PrintCharPointerTest, ConstUnsignedChar) { + const unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to simple, built-in types. + +// bool*. +TEST(PrintPointerToBuiltInTypeTest, Bool) { + bool* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// void*. +TEST(PrintPointerToBuiltInTypeTest, Void) { + void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// const void*. +TEST(PrintPointerToBuiltInTypeTest, ConstVoid) { + const void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to pointers. +TEST(PrintPointerToPointerTest, IntPointerPointer) { + int** p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing (non-member) function pointers. + +void MyFunction(int /* n */) {} + +TEST(PrintPointerTest, NonMemberFunctionPointer) { + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + EXPECT_EQ( + PrintPointer(reinterpret_cast( + reinterpret_cast(&MyFunction))), + Print(&MyFunction)); + int (*p)(bool) = NULL; // NOLINT + EXPECT_EQ("NULL", Print(p)); +} + +// An assertion predicate determining whether a one string is a prefix for +// another. +template +AssertionResult HasPrefix(const StringType& str, const StringType& prefix) { + if (str.find(prefix, 0) == 0) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(prefix[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << begin_string_quote << prefix << "\" is not a prefix of " + << begin_string_quote << str << "\"\n"; +} + +// Tests printing member variable pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. + +struct Foo { + public: + virtual ~Foo() {} + int MyMethod(char x) { return x + 1; } + virtual char MyVirtualMethod(int /* n */) { return 'a'; } + + int value; +}; + +TEST(PrintPointerTest, MemberVariablePointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::value), + Print(sizeof(&Foo::value)) + "-byte object ")); + int Foo::*p = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing member function pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. +TEST(PrintPointerTest, MemberFunctionPointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::MyMethod), + Print(sizeof(&Foo::MyMethod)) + "-byte object ")); + EXPECT_TRUE( + HasPrefix(Print(&Foo::MyVirtualMethod), + Print(sizeof((&Foo::MyVirtualMethod))) + "-byte object ")); + int (Foo::*p)(char) = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing C arrays. + +// The difference between this and Print() is that it ensures that the +// argument is a reference to an array. +template +std::string PrintArrayHelper(T (&a)[N]) { + return Print(a); +} + +// One-dimensional array. +TEST(PrintArrayTest, OneDimensionalArray) { + int a[5] = { 1, 2, 3, 4, 5 }; + EXPECT_EQ("{ 1, 2, 3, 4, 5 }", PrintArrayHelper(a)); +} + +// Two-dimensional array. +TEST(PrintArrayTest, TwoDimensionalArray) { + int a[2][5] = { + { 1, 2, 3, 4, 5 }, + { 6, 7, 8, 9, 0 } + }; + EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", PrintArrayHelper(a)); +} + +// Array of const elements. +TEST(PrintArrayTest, ConstArray) { + const bool a[1] = { false }; + EXPECT_EQ("{ false }", PrintArrayHelper(a)); +} + +// char array without terminating NUL. +TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + char a[] = { 'H', '\0', 'i' }; + EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// const char array with terminating NUL. +TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { + const char a[] = "\0Hi"; + EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); +} + +// const wchar_t array without terminating NUL. +TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const wchar_t a[] = { L'H', L'\0', L'i' }; + EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// wchar_t array with terminating NUL. +TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { + const wchar_t a[] = L"\0Hi"; + EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); +} + +// Array of objects. +TEST(PrintArrayTest, ObjectArray) { + std::string a[3] = {"Hi", "Hello", "Ni hao"}; + EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a)); +} + +// Array with many elements. +TEST(PrintArrayTest, BigArray) { + int a[100] = { 1, 2, 3 }; + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }", + PrintArrayHelper(a)); +} + +// Tests printing ::string and ::std::string. + +// ::std::string. +TEST(PrintStringTest, StringInStdNamespace) { + const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const ::std::string str(s, sizeof(s)); + EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + Print(str)); +} + +TEST(PrintStringTest, StringAmbiguousHex) { + // "\x6BANANA" is ambiguous, it can be interpreted as starting with either of: + // '\x6', '\x6B', or '\x6BA'. + + // a hex escaping sequence following by a decimal digit + EXPECT_EQ("\"0\\x12\" \"3\"", Print(::std::string("0\x12" "3"))); + // a hex escaping sequence following by a hex digit (lower-case) + EXPECT_EQ("\"mm\\x6\" \"bananas\"", Print(::std::string("mm\x6" "bananas"))); + // a hex escaping sequence following by a hex digit (upper-case) + EXPECT_EQ("\"NOM\\x6\" \"BANANA\"", Print(::std::string("NOM\x6" "BANANA"))); + // a hex escaping sequence following by a non-xdigit + EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!"))); +} + +// Tests printing ::std::wstring. +#if GTEST_HAS_STD_WSTRING +// ::std::wstring. +TEST(PrintWideStringTest, StringInStdNamespace) { + const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t)); + EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + "\\xD3\\x576\\x8D3\\xC74D a\\0\"", + Print(str)); +} + +TEST(PrintWideStringTest, StringAmbiguousHex) { + // same for wide strings. + EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3"))); + EXPECT_EQ("L\"mm\\x6\" L\"bananas\"", + Print(::std::wstring(L"mm\x6" L"bananas"))); + EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"", + Print(::std::wstring(L"NOM\x6" L"BANANA"))); + EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!"))); +} +#endif // GTEST_HAS_STD_WSTRING + +// Tests printing types that support generic streaming (i.e. streaming +// to std::basic_ostream for any valid Char and +// CharTraits types). + +// Tests printing a non-template type that supports generic streaming. + +class AllowsGenericStreaming {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreaming& /* a */) { + return os << "AllowsGenericStreaming"; +} + +TEST(PrintTypeWithGenericStreamingTest, NonTemplateType) { + AllowsGenericStreaming a; + EXPECT_EQ("AllowsGenericStreaming", Print(a)); +} + +// Tests printing a template type that supports generic streaming. + +template +class AllowsGenericStreamingTemplate {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingTemplate& /* a */) { + return os << "AllowsGenericStreamingTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TemplateType) { + AllowsGenericStreamingTemplate a; + EXPECT_EQ("AllowsGenericStreamingTemplate", Print(a)); +} + +// Tests printing a type that supports generic streaming and can be +// implicitly converted to another printable type. + +template +class AllowsGenericStreamingAndImplicitConversionTemplate { + public: + operator bool() const { return false; } +}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingAndImplicitConversionTemplate& /* a */) { + return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { + AllowsGenericStreamingAndImplicitConversionTemplate a; + EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); +} + +#if GTEST_HAS_ABSL + +// Tests printing ::absl::string_view. + +TEST(PrintStringViewTest, SimpleStringView) { + const ::absl::string_view sp = "Hello"; + EXPECT_EQ("\"Hello\"", Print(sp)); +} + +TEST(PrintStringViewTest, UnprintableCharacters) { + const char str[] = "NUL (\0) and \r\t"; + const ::absl::string_view sp(str, sizeof(str) - 1); + EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); +} + +#endif // GTEST_HAS_ABSL + +// Tests printing STL containers. + +TEST(PrintStlContainerTest, EmptyDeque) { + deque empty; + EXPECT_EQ("{}", Print(empty)); +} + +TEST(PrintStlContainerTest, NonEmptyDeque) { + deque non_empty; + non_empty.push_back(1); + non_empty.push_back(3); + EXPECT_EQ("{ 1, 3 }", Print(non_empty)); +} + + +TEST(PrintStlContainerTest, OneElementHashMap) { + ::std::unordered_map map1; + map1[1] = 'a'; + EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); +} + +TEST(PrintStlContainerTest, HashMultiMap) { + ::std::unordered_multimap map1; + map1.insert(make_pair(5, true)); + map1.insert(make_pair(5, false)); + + // Elements of hash_multimap can be printed in any order. + const std::string result = Print(map1); + EXPECT_TRUE(result == "{ (5, true), (5, false) }" || + result == "{ (5, false), (5, true) }") + << " where Print(map1) returns \"" << result << "\"."; +} + + + +TEST(PrintStlContainerTest, HashSet) { + ::std::unordered_set set1; + set1.insert(1); + EXPECT_EQ("{ 1 }", Print(set1)); +} + +TEST(PrintStlContainerTest, HashMultiSet) { + const int kSize = 5; + int a[kSize] = { 1, 1, 2, 5, 1 }; + ::std::unordered_multiset set1(a, a + kSize); + + // Elements of hash_multiset can be printed in any order. + const std::string result = Print(set1); + const std::string expected_pattern = "{ d, d, d, d, d }"; // d means a digit. + + // Verifies the result matches the expected pattern; also extracts + // the numbers in the result. + ASSERT_EQ(expected_pattern.length(), result.length()); + std::vector numbers; + for (size_t i = 0; i != result.length(); i++) { + if (expected_pattern[i] == 'd') { + ASSERT_NE(isdigit(static_cast(result[i])), 0); + numbers.push_back(result[i] - '0'); + } else { + EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " + << result; + } + } + + // Makes sure the result contains the right numbers. + std::sort(numbers.begin(), numbers.end()); + std::sort(a, a + kSize); + EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); +} + + +TEST(PrintStlContainerTest, List) { + const std::string a[] = {"hello", "world"}; + const list strings(a, a + 2); + EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings)); +} + +TEST(PrintStlContainerTest, Map) { + map map1; + map1[1] = true; + map1[5] = false; + map1[3] = true; + EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1)); +} + +TEST(PrintStlContainerTest, MultiMap) { + multimap map1; + // The make_pair template function would deduce the type as + // pair here, and since the key part in a multimap has to + // be constant, without a templated ctor in the pair class (as in + // libCstd on Solaris), make_pair call would fail to compile as no + // implicit conversion is found. Thus explicit typename is used + // here instead. + map1.insert(pair(true, 0)); + map1.insert(pair(true, 1)); + map1.insert(pair(false, 2)); + EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1)); +} + +TEST(PrintStlContainerTest, Set) { + const unsigned int a[] = { 3, 0, 5 }; + set set1(a, a + 3); + EXPECT_EQ("{ 0, 3, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, MultiSet) { + const int a[] = { 1, 1, 2, 5, 1 }; + multiset set1(a, a + 5); + EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1)); +} + + +TEST(PrintStlContainerTest, SinglyLinkedList) { + int a[] = { 9, 2, 8 }; + const std::forward_list ints(a, a + 3); + EXPECT_EQ("{ 9, 2, 8 }", Print(ints)); +} + +TEST(PrintStlContainerTest, Pair) { + pair p(true, 5); + EXPECT_EQ("(true, 5)", Print(p)); +} + +TEST(PrintStlContainerTest, Vector) { + vector v; + v.push_back(1); + v.push_back(2); + EXPECT_EQ("{ 1, 2 }", Print(v)); +} + +TEST(PrintStlContainerTest, LongSequence) { + const int a[100] = { 1, 2, 3 }; + const vector v(a, a + 100); + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " + "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v)); +} + +TEST(PrintStlContainerTest, NestedContainer) { + const int a1[] = { 1, 2 }; + const int a2[] = { 3, 4, 5 }; + const list l1(a1, a1 + 2); + const list l2(a2, a2 + 3); + + vector > v; + v.push_back(l1); + v.push_back(l2); + EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v)); +} + +TEST(PrintStlContainerTest, OneDimensionalNativeArray) { + const int a[3] = { 1, 2, 3 }; + NativeArray b(a, 3, RelationToSourceReference()); + EXPECT_EQ("{ 1, 2, 3 }", Print(b)); +} + +TEST(PrintStlContainerTest, TwoDimensionalNativeArray) { + const int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; + NativeArray b(a, 2, RelationToSourceReference()); + EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b)); +} + +// Tests that a class named iterator isn't treated as a container. + +struct iterator { + char x; +}; + +TEST(PrintStlContainerTest, Iterator) { + iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + +// Tests that a class named const_iterator isn't treated as a container. + +struct const_iterator { + char x; +}; + +TEST(PrintStlContainerTest, ConstIterator) { + const_iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + +// Tests printing ::std::tuples. + +// Tuples of various arities. +TEST(PrintStdTupleTest, VariousSizes) { + ::std::tuple<> t0; + EXPECT_EQ("()", Print(t0)); + + ::std::tuple t1(5); + EXPECT_EQ("(5)", Print(t1)); + + ::std::tuple t2('a', true); + EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); + + ::std::tuple t3(false, 2, 3); + EXPECT_EQ("(false, 2, 3)", Print(t3)); + + ::std::tuple t4(false, 2, 3, 4); + EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); + + const char* const str = "8"; + ::std::tuple + t10(false, 'a', static_cast(3), 4, 5, 1.5F, -2.5, str, // NOLINT + nullptr, "10"); + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + + " pointing to \"8\", NULL, \"10\")", + Print(t10)); +} + +// Nested tuples. +TEST(PrintStdTupleTest, NestedTuple) { + ::std::tuple< ::std::tuple, char> nested( + ::std::make_tuple(5, true), 'a'); + EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); +} + +TEST(PrintNullptrT, Basic) { + EXPECT_EQ("(nullptr)", Print(nullptr)); +} + +TEST(PrintReferenceWrapper, Printable) { + int x = 5; + EXPECT_EQ("@" + PrintPointer(&x) + " 5", Print(std::ref(x))); + EXPECT_EQ("@" + PrintPointer(&x) + " 5", Print(std::cref(x))); +} + +TEST(PrintReferenceWrapper, Unprintable) { + ::foo::UnprintableInFoo up; + EXPECT_EQ( + "@" + PrintPointer(&up) + + " 16-byte object ", + Print(std::ref(up))); + EXPECT_EQ( + "@" + PrintPointer(&up) + + " 16-byte object ", + Print(std::cref(up))); +} + +// Tests printing user-defined unprintable types. + +// Unprintable types in the global namespace. +TEST(PrintUnprintableTypeTest, InGlobalNamespace) { + EXPECT_EQ("1-byte object <00>", + Print(UnprintableTemplateInGlobal())); +} + +// Unprintable types in a user namespace. +TEST(PrintUnprintableTypeTest, InUserNamespace) { + EXPECT_EQ("16-byte object ", + Print(::foo::UnprintableInFoo())); +} + +// Unprintable types are that too big to be printed completely. + +struct Big { + Big() { memset(array, 0, sizeof(array)); } + char array[257]; +}; + +TEST(PrintUnpritableTypeTest, BigObject) { + EXPECT_EQ("257-byte object <00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 ... 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00>", + Print(Big())); +} + +// Tests printing user-defined streamable types. + +// Streamable types in the global namespace. +TEST(PrintStreamableTypeTest, InGlobalNamespace) { + StreamableInGlobal x; + EXPECT_EQ("StreamableInGlobal", Print(x)); + EXPECT_EQ("StreamableInGlobal*", Print(&x)); +} + +// Printable template types in a user namespace. +TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { + EXPECT_EQ("StreamableTemplateInFoo: 0", + Print(::foo::StreamableTemplateInFoo())); +} + +// Tests printing a user-defined recursive container type that has a << +// operator. +TEST(PrintStreamableTypeTest, PathLikeInUserNamespace) { + ::foo::PathLike x; + EXPECT_EQ("Streamable-PathLike", Print(x)); + const ::foo::PathLike cx; + EXPECT_EQ("Streamable-PathLike", Print(cx)); +} + +// Tests printing user-defined types that have a PrintTo() function. +TEST(PrintPrintableTypeTest, InUserNamespace) { + EXPECT_EQ("PrintableViaPrintTo: 0", + Print(::foo::PrintableViaPrintTo())); +} + +// Tests printing a pointer to a user-defined type that has a << +// operator for its pointer. +TEST(PrintPrintableTypeTest, PointerInUserNamespace) { + ::foo::PointerPrintable x; + EXPECT_EQ("PointerPrintable*", Print(&x)); +} + +// Tests printing user-defined class template that have a PrintTo() function. +TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { + EXPECT_EQ("PrintableViaPrintToTemplate: 5", + Print(::foo::PrintableViaPrintToTemplate(5))); +} + +// Tests that the universal printer prints both the address and the +// value of a reference. +TEST(PrintReferenceTest, PrintsAddressAndValue) { + int n = 5; + EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n)); + + int a[2][3] = { + { 0, 1, 2 }, + { 3, 4, 5 } + }; + EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }", + PrintByRef(a)); + + const ::foo::UnprintableInFoo x; + EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object " + "", + PrintByRef(x)); +} + +// Tests that the universal printer prints a function pointer passed by +// reference. +TEST(PrintReferenceTest, HandlesFunctionPointer) { + void (*fp)(int n) = &MyFunction; + const std::string fp_pointer_string = + PrintPointer(reinterpret_cast(&fp)); + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + const std::string fp_string = PrintPointer(reinterpret_cast( + reinterpret_cast(fp))); + EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, + PrintByRef(fp)); +} + +// Tests that the universal printer prints a member function pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberFunctionPointer) { + int (Foo::*p)(char ch) = &Foo::MyMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(reinterpret_cast(&p)) + " " + + Print(sizeof(p)) + "-byte object ")); + + char (Foo::*p2)(int n) = &Foo::MyVirtualMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p2), + "@" + PrintPointer(reinterpret_cast(&p2)) + " " + + Print(sizeof(p2)) + "-byte object ")); +} + +// Tests that the universal printer prints a member variable pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberVariablePointer) { + int Foo::*p = &Foo::value; // NOLINT + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); +} + +// Tests that FormatForComparisonFailureMessage(), which is used to print +// an operand in a comparison assertion (e.g. ASSERT_EQ) when the assertion +// fails, formats the operand in the desired way. + +// scalar +TEST(FormatForComparisonFailureMessageTest, WorksForScalar) { + EXPECT_STREQ("123", + FormatForComparisonFailureMessage(123, 124).c_str()); +} + +// non-char pointer +TEST(FormatForComparisonFailureMessageTest, WorksForNonCharPointer) { + int n = 0; + EXPECT_EQ(PrintPointer(&n), + FormatForComparisonFailureMessage(&n, &n).c_str()); +} + +// non-char array +TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { + // In expression 'array == x', 'array' is compared by pointer. + // Therefore we want to print an array operand as a pointer. + int n[] = { 1, 2, 3 }; + EXPECT_EQ(PrintPointer(n), + FormatForComparisonFailureMessage(n, n).c_str()); +} + +// Tests formatting a char pointer when it's compared with another pointer. +// In this case we want to print it as a raw pointer, as the comparison is by +// pointer. + +// char pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a C string (we don't + // even know if it's supposed to point to a valid C string). + + // const char* + const char* s = "hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // char* + char ch = 'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// wchar_t pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a wide C string (we don't + // even know if it's supposed to point to a valid wide C string). + + // const wchar_t* + const wchar_t* s = L"hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // wchar_t* + wchar_t ch = L'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// Tests formatting a char pointer when it's compared to a string object. +// In this case we want to print the char pointer as a C string. + +// char pointer vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsStdString) { + const char* s = "hello \"world"; + EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::string()).c_str()); + + // char* + char str[] = "hi\1"; + char* p = str; + EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::string()).c_str()); +} + +#if GTEST_HAS_STD_WSTRING +// wchar_t pointer vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsStdWString) { + const wchar_t* s = L"hi \"world"; + EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::wstring()).c_str()); + + // wchar_t* + wchar_t str[] = L"hi\1"; + wchar_t* p = str; + EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::wstring()).c_str()); +} +#endif + +// Tests formatting a char array when it's compared with a pointer or array. +// In this case we want to print the array as a row pointer, as the comparison +// is by pointer. + +// char array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsPointer) { + char str[] = "hi \"world\""; + char* p = nullptr; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// char array vs char array +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsCharArray) { + const char str[] = "hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// wchar_t array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsPointer) { + wchar_t str[] = L"hi \"world\""; + wchar_t* p = nullptr; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// wchar_t array vs wchar_t array +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWCharArray) { + const wchar_t str[] = L"hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// Tests formatting a char array when it's compared with a string object. +// In this case we want to print the array as a C string. + +// char array vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsStdString) { + const char str[] = "hi \"world\""; + EXPECT_STREQ("\"hi \\\"world\\\"\"", // The content should be escaped. + FormatForComparisonFailureMessage(str, ::std::string()).c_str()); +} + +#if GTEST_HAS_STD_WSTRING +// wchar_t array vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsStdWString) { + const wchar_t str[] = L"hi \"w\0rld\""; + EXPECT_STREQ( + "L\"hi \\\"w\"", // The content should be escaped. + // Embedded NUL terminates the string. + FormatForComparisonFailureMessage(str, ::std::wstring()).c_str()); +} +#endif + +// Useful for testing PrintToString(). We cannot use EXPECT_EQ() +// there as its implementation uses PrintToString(). The caller must +// ensure that 'value' has no side effect. +#define EXPECT_PRINT_TO_STRING_(value, expected_string) \ + EXPECT_TRUE(PrintToString(value) == (expected_string)) \ + << " where " #value " prints as " << (PrintToString(value)) + +TEST(PrintToStringTest, WorksForScalar) { + EXPECT_PRINT_TO_STRING_(123, "123"); +} + +TEST(PrintToStringTest, WorksForPointerToConstChar) { + const char* p = "hello"; + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); +} + +TEST(PrintToStringTest, WorksForPointerToNonConstChar) { + char s[] = "hello"; + char* p = s; + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); +} + +TEST(PrintToStringTest, EscapesForPointerToConstChar) { + const char* p = "hello\n"; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\n\""); +} + +TEST(PrintToStringTest, EscapesForPointerToNonConstChar) { + char s[] = "hello\1"; + char* p = s; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\x1\""); +} + +TEST(PrintToStringTest, WorksForArray) { + int n[3] = { 1, 2, 3 }; + EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }"); +} + +TEST(PrintToStringTest, WorksForCharArray) { + char s[] = "hello"; + EXPECT_PRINT_TO_STRING_(s, "\"hello\""); +} + +TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { + const char str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(str_with_nul, "\"hello\\0 world\""); + + char mutable_str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); +} + + TEST(PrintToStringTest, ContainsNonLatin) { + // Sanity test with valid UTF-8. Prints both in hex and as text. + std::string non_ascii_str = ::std::string("오전 4:30"); + EXPECT_PRINT_TO_STRING_(non_ascii_str, + "\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n" + " As Text: \"오전 4:30\""); + non_ascii_str = ::std::string("From ä — ẑ"); + EXPECT_PRINT_TO_STRING_(non_ascii_str, + "\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\"" + "\n As Text: \"From ä — ẑ\""); +} + +TEST(IsValidUTF8Test, IllFormedUTF8) { + // The following test strings are ill-formed UTF-8 and are printed + // as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is + // expected to fail, thus output does not contain "As Text:". + + static const char *const kTestdata[][2] = { + // 2-byte lead byte followed by a single-byte character. + {"\xC3\x74", "\"\\xC3t\""}, + // Valid 2-byte character followed by an orphan trail byte. + {"\xC3\x84\xA4", "\"\\xC3\\x84\\xA4\""}, + // Lead byte without trail byte. + {"abc\xC3", "\"abc\\xC3\""}, + // 3-byte lead byte, single-byte character, orphan trail byte. + {"x\xE2\x70\x94", "\"x\\xE2p\\x94\""}, + // Truncated 3-byte character. + {"\xE2\x80", "\"\\xE2\\x80\""}, + // Truncated 3-byte character followed by valid 2-byte char. + {"\xE2\x80\xC3\x84", "\"\\xE2\\x80\\xC3\\x84\""}, + // Truncated 3-byte character followed by a single-byte character. + {"\xE2\x80\x7A", "\"\\xE2\\x80z\""}, + // 3-byte lead byte followed by valid 3-byte character. + {"\xE2\xE2\x80\x94", "\"\\xE2\\xE2\\x80\\x94\""}, + // 4-byte lead byte followed by valid 3-byte character. + {"\xF0\xE2\x80\x94", "\"\\xF0\\xE2\\x80\\x94\""}, + // Truncated 4-byte character. + {"\xF0\xE2\x80", "\"\\xF0\\xE2\\x80\""}, + // Invalid UTF-8 byte sequences embedded in other chars. + {"abc\xE2\x80\x94\xC3\x74xyc", "\"abc\\xE2\\x80\\x94\\xC3txyc\""}, + {"abc\xC3\x84\xE2\x80\xC3\x84xyz", + "\"abc\\xC3\\x84\\xE2\\x80\\xC3\\x84xyz\""}, + // Non-shortest UTF-8 byte sequences are also ill-formed. + // The classics: xC0, xC1 lead byte. + {"\xC0\x80", "\"\\xC0\\x80\""}, + {"\xC1\x81", "\"\\xC1\\x81\""}, + // Non-shortest sequences. + {"\xE0\x80\x80", "\"\\xE0\\x80\\x80\""}, + {"\xf0\x80\x80\x80", "\"\\xF0\\x80\\x80\\x80\""}, + // Last valid code point before surrogate range, should be printed as text, + // too. + {"\xED\x9F\xBF", "\"\\xED\\x9F\\xBF\"\n As Text: \"퟿\""}, + // Start of surrogate lead. Surrogates are not printed as text. + {"\xED\xA0\x80", "\"\\xED\\xA0\\x80\""}, + // Last non-private surrogate lead. + {"\xED\xAD\xBF", "\"\\xED\\xAD\\xBF\""}, + // First private-use surrogate lead. + {"\xED\xAE\x80", "\"\\xED\\xAE\\x80\""}, + // Last private-use surrogate lead. + {"\xED\xAF\xBF", "\"\\xED\\xAF\\xBF\""}, + // Mid-point of surrogate trail. + {"\xED\xB3\xBF", "\"\\xED\\xB3\\xBF\""}, + // First valid code point after surrogate range, should be printed as text, + // too. + {"\xEE\x80\x80", "\"\\xEE\\x80\\x80\"\n As Text: \"\""} + }; + + for (int i = 0; i < int(sizeof(kTestdata)/sizeof(kTestdata[0])); ++i) { + EXPECT_PRINT_TO_STRING_(kTestdata[i][0], kTestdata[i][1]); + } +} + +#undef EXPECT_PRINT_TO_STRING_ + +TEST(UniversalTersePrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalTersePrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalTersePrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalTersePrint(s1, &ss1); + EXPECT_EQ("\"abc\"", ss1.str()); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalTersePrint(s2, &ss2); + EXPECT_EQ("\"abc\"", ss2.str()); + + const char* s3 = nullptr; + ::std::stringstream ss3; + UniversalTersePrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + +TEST(UniversalPrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalPrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalPrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalPrint(s1, &ss1); + EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", std::string(ss1.str())); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalPrint(s2, &ss2); + EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", std::string(ss2.str())); + + const char* s3 = nullptr; + ::std::stringstream ss3; + UniversalPrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + +TEST(UniversalPrintTest, WorksForCharArray) { + const char str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss1; + UniversalPrint(str, &ss1); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str()); + + const char mutable_str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss2; + UniversalPrint(mutable_str, &ss2); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str()); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple()); + EXPECT_EQ(0u, result.size()); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsOneTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::make_tuple(1)); + ASSERT_EQ(1u, result.size()); + EXPECT_EQ("1", result[0]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTwoTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::make_tuple(1, 'a')); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("'a' (97, 0x61)", result[1]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { + const int n = 1; + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tuple(n, "a")); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("\"a\"", result[1]); +} + +#if GTEST_HAS_ABSL + +TEST(PrintOptionalTest, Basic) { + absl::optional value; + EXPECT_EQ("(nullopt)", PrintToString(value)); + value = {7}; + EXPECT_EQ("(7)", PrintToString(value)); + EXPECT_EQ("(1.1)", PrintToString(absl::optional{1.1})); + EXPECT_EQ("(\"A\")", PrintToString(absl::optional{"A"})); +} + +struct NonPrintable { + unsigned char contents = 17; +}; + +TEST(PrintOneofTest, Basic) { + using Type = absl::variant; + EXPECT_EQ("('int' with value 7)", PrintToString(Type(7))); + EXPECT_EQ("('StreamableInGlobal' with value StreamableInGlobal)", + PrintToString(Type(StreamableInGlobal{}))); + EXPECT_EQ( + "('testing::gtest_printers_test::NonPrintable' with value 1-byte object " + "<11>)", + PrintToString(Type(NonPrintable{}))); +} +#endif // GTEST_HAS_ABSL +namespace { +class string_ref; + +/** + * This is a synthetic pointer to a fixed size string. + */ +class string_ptr { + public: + string_ptr(const char* data, size_t size) : data_(data), size_(size) {} + + string_ptr& operator++() noexcept { + data_ += size_; + return *this; + } + + string_ref operator*() const noexcept; + + private: + const char* data_; + size_t size_; +}; + +/** + * This is a synthetic reference of a fixed size string. + */ +class string_ref { + public: + string_ref(const char* data, size_t size) : data_(data), size_(size) {} + + string_ptr operator&() const noexcept { return {data_, size_}; } // NOLINT + + bool operator==(const char* s) const noexcept { + if (size_ > 0 && data_[size_ - 1] != 0) { + return std::string(data_, size_) == std::string(s); + } else { + return std::string(data_) == std::string(s); + } + } + + private: + const char* data_; + size_t size_; +}; + +string_ref string_ptr::operator*() const noexcept { return {data_, size_}; } + +TEST(string_ref, compare) { + const char* s = "alex\0davidjohn\0"; + string_ptr ptr(s, 5); + EXPECT_EQ(*ptr, "alex"); + EXPECT_TRUE(*ptr == "alex"); + ++ptr; + EXPECT_EQ(*ptr, "david"); + EXPECT_TRUE(*ptr == "david"); + ++ptr; + EXPECT_EQ(*ptr, "john"); +} + +} // namespace + +} // namespace gtest_printers_test +} // namespace testing diff --git a/3rdparty/gtest/test/googletest-shuffle-test.py b/3rdparty/gtest/test/googletest-shuffle-test.py new file mode 100644 index 0000000..573cc5e --- /dev/null +++ b/3rdparty/gtest/test/googletest-shuffle-test.py @@ -0,0 +1,323 @@ +#!/usr/bin/env python +# +# Copyright 2009 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Verifies that test shuffling works.""" + +import os +import gtest_test_utils + +# Command to run the googletest-shuffle-test_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-shuffle-test_') + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' + +TEST_FILTER = 'A*.A:A*.B:C*' + +ALL_TESTS = [] +ACTIVE_TESTS = [] +FILTERED_TESTS = [] +SHARDED_TESTS = [] + +SHUFFLED_ALL_TESTS = [] +SHUFFLED_ACTIVE_TESTS = [] +SHUFFLED_FILTERED_TESTS = [] +SHUFFLED_SHARDED_TESTS = [] + + +def AlsoRunDisabledTestsFlag(): + return '--gtest_also_run_disabled_tests' + + +def FilterFlag(test_filter): + return '--gtest_filter=%s' % (test_filter,) + + +def RepeatFlag(n): + return '--gtest_repeat=%s' % (n,) + + +def ShuffleFlag(): + return '--gtest_shuffle' + + +def RandomSeedFlag(n): + return '--gtest_random_seed=%s' % (n,) + + +def RunAndReturnOutput(extra_env, args): + """Runs the test program and returns its output.""" + + environ_copy = os.environ.copy() + environ_copy.update(extra_env) + + return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output + + +def GetTestsForAllIterations(extra_env, args): + """Runs the test program and returns a list of test lists. + + Args: + extra_env: a map from environment variables to their values + args: command line flags to pass to googletest-shuffle-test_ + + Returns: + A list where the i-th element is the list of tests run in the i-th + test iteration. + """ + + test_iterations = [] + for line in RunAndReturnOutput(extra_env, args).split('\n'): + if line.startswith('----'): + tests = [] + test_iterations.append(tests) + elif line.strip(): + tests.append(line.strip()) # 'TestCaseName.TestName' + + return test_iterations + + +def GetTestCases(tests): + """Returns a list of test cases in the given full test names. + + Args: + tests: a list of full test names + + Returns: + A list of test cases from 'tests', in their original order. + Consecutive duplicates are removed. + """ + + test_cases = [] + for test in tests: + test_case = test.split('.')[0] + if not test_case in test_cases: + test_cases.append(test_case) + + return test_cases + + +def CalculateTestLists(): + """Calculates the list of tests run under different flags.""" + + if not ALL_TESTS: + ALL_TESTS.extend( + GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0]) + + if not ACTIVE_TESTS: + ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0]) + + if not FILTERED_TESTS: + FILTERED_TESTS.extend( + GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0]) + + if not SHARDED_TESTS: + SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [])[0]) + + if not SHUFFLED_ALL_TESTS: + SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations( + {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_ACTIVE_TESTS: + SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_FILTERED_TESTS: + SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0]) + + if not SHUFFLED_SHARDED_TESTS: + SHUFFLED_SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + +class GTestShuffleUnitTest(gtest_test_utils.TestCase): + """Tests test shuffling.""" + + def setUp(self): + CalculateTestLists() + + def testShufflePreservesNumberOfTests(self): + self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS)) + self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS)) + self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS)) + self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) + + def testShuffleChangesTestOrder(self): + self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) + self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) + self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, + SHUFFLED_FILTERED_TESTS) + self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, + SHUFFLED_SHARDED_TESTS) + + def testShuffleChangesTestCaseOrder(self): + self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), + GetTestCases(SHUFFLED_ALL_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), + GetTestCases(SHUFFLED_ACTIVE_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), + GetTestCases(SHUFFLED_FILTERED_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), + GetTestCases(SHUFFLED_SHARDED_TESTS)) + + def testShuffleDoesNotRepeatTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), + '%s appears more than once' % (test,)) + + def testShuffleDoesNotCreateNewTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) + + def testShuffleIncludesAllTests(self): + for test in ALL_TESTS: + self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) + for test in ACTIVE_TESTS: + self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) + for test in FILTERED_TESTS: + self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) + for test in SHARDED_TESTS: + self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) + + def testShuffleLeavesDeathTestsAtFront(self): + non_death_test_found = False + for test in SHUFFLED_ACTIVE_TESTS: + if 'DeathTest.' in test: + self.assert_(not non_death_test_found, + '%s appears after a non-death test' % (test,)) + else: + non_death_test_found = True + + def _VerifyTestCasesDoNotInterleave(self, tests): + test_cases = [] + for test in tests: + [test_case, _] = test.split('.') + if test_cases and test_cases[-1] != test_case: + test_cases.append(test_case) + self.assertEqual(1, test_cases.count(test_case), + 'Test case %s is not grouped together in %s' % + (test_case, tests)) + + def testShuffleDoesNotInterleaveTestCases(self): + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS) + + def testShuffleRestoresOrderAfterEachIteration(self): + # Get the test lists in all 3 iterations, using random seed 1, 2, + # and 3 respectively. Google Test picks a different seed in each + # iteration, and this test depends on the current implementation + # picking successive numbers. This dependency is not ideal, but + # makes the test much easier to write. + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + # Make sure running the tests with random seed 1 gets the same + # order as in iteration 1 above. + [tests_with_seed1] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)]) + self.assertEqual(tests_in_iteration1, tests_with_seed1) + + # Make sure running the tests with random seed 2 gets the same + # order as in iteration 2 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 2. + [tests_with_seed2] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(2)]) + self.assertEqual(tests_in_iteration2, tests_with_seed2) + + # Make sure running the tests with random seed 3 gets the same + # order as in iteration 3 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 3. + [tests_with_seed3] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(3)]) + self.assertEqual(tests_in_iteration3, tests_with_seed3) + + def testShuffleGeneratesNewOrderInEachIteration(self): + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + self.assert_(tests_in_iteration1 != tests_in_iteration2, + tests_in_iteration1) + self.assert_(tests_in_iteration1 != tests_in_iteration3, + tests_in_iteration1) + self.assert_(tests_in_iteration2 != tests_in_iteration3, + tests_in_iteration2) + + def testShuffleShardedTestsPreservesPartition(self): + # If we run M tests on N shards, the same M tests should be run in + # total, regardless of the random seeds used by the shards. + [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '0'}, + [ShuffleFlag(), RandomSeedFlag(1)]) + [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(20)]) + [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '2'}, + [ShuffleFlag(), RandomSeedFlag(25)]) + sorted_sharded_tests = tests1 + tests2 + tests3 + sorted_sharded_tests.sort() + sorted_active_tests = [] + sorted_active_tests.extend(ACTIVE_TESTS) + sorted_active_tests.sort() + self.assertEqual(sorted_active_tests, sorted_sharded_tests) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-shuffle-test_.cc b/3rdparty/gtest/test/googletest-shuffle-test_.cc new file mode 100644 index 0000000..c1fc106 --- /dev/null +++ b/3rdparty/gtest/test/googletest-shuffle-test_.cc @@ -0,0 +1,101 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Verifies that test shuffling works. + +#include "gtest/gtest.h" + +namespace { + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Message; +using ::testing::Test; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::UnitTest; + +// The test methods are empty, as the sole purpose of this program is +// to print the test names before/after shuffling. + +class A : public Test {}; +TEST_F(A, A) {} +TEST_F(A, B) {} + +TEST(ADeathTest, A) {} +TEST(ADeathTest, B) {} +TEST(ADeathTest, C) {} + +TEST(B, A) {} +TEST(B, B) {} +TEST(B, C) {} +TEST(B, DISABLED_D) {} +TEST(B, DISABLED_E) {} + +TEST(BDeathTest, A) {} +TEST(BDeathTest, B) {} + +TEST(C, A) {} +TEST(C, B) {} +TEST(C, C) {} +TEST(C, DISABLED_D) {} + +TEST(CDeathTest, A) {} + +TEST(DISABLED_D, A) {} +TEST(DISABLED_D, DISABLED_B) {} + +// This printer prints the full test names only, starting each test +// iteration with a "----" marker. +class TestNamePrinter : public EmptyTestEventListener { + public: + void OnTestIterationStart(const UnitTest& /* unit_test */, + int /* iteration */) override { + printf("----\n"); + } + + void OnTestStart(const TestInfo& test_info) override { + printf("%s.%s\n", test_info.test_case_name(), test_info.name()); + } +}; + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + // Replaces the default printer with TestNamePrinter, which prints + // the test name only. + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new TestNamePrinter); + + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/googletest-test-part-test.cc b/3rdparty/gtest/test/googletest-test-part-test.cc new file mode 100644 index 0000000..44cf7ca --- /dev/null +++ b/3rdparty/gtest/test/googletest-test-part-test.cc @@ -0,0 +1,230 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "gtest/gtest-test-part.h" + +#include "gtest/gtest.h" + +using testing::Message; +using testing::Test; +using testing::TestPartResult; +using testing::TestPartResultArray; + +namespace { + +// Tests the TestPartResult class. + +// The test fixture for testing TestPartResult. +class TestPartResultTest : public Test { + protected: + TestPartResultTest() + : r1_(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"), + r2_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure!"), + r3_(TestPartResult::kFatalFailure, nullptr, -1, "Failure!"), + r4_(TestPartResult::kSkip, "foo/bar.cc", 2, "Skipped!") {} + + TestPartResult r1_, r2_, r3_, r4_; +}; + + +TEST_F(TestPartResultTest, ConstructorWorks) { + Message message; + message << "something is terribly wrong"; + message << static_cast(testing::internal::kStackTraceMarker); + message << "some unimportant stack trace"; + + const TestPartResult result(TestPartResult::kNonFatalFailure, + "some_file.cc", + 42, + message.GetString().c_str()); + + EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type()); + EXPECT_STREQ("some_file.cc", result.file_name()); + EXPECT_EQ(42, result.line_number()); + EXPECT_STREQ(message.GetString().c_str(), result.message()); + EXPECT_STREQ("something is terribly wrong", result.summary()); +} + +TEST_F(TestPartResultTest, ResultAccessorsWork) { + const TestPartResult success(TestPartResult::kSuccess, + "file.cc", + 42, + "message"); + EXPECT_TRUE(success.passed()); + EXPECT_FALSE(success.failed()); + EXPECT_FALSE(success.nonfatally_failed()); + EXPECT_FALSE(success.fatally_failed()); + EXPECT_FALSE(success.skipped()); + + const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(nonfatal_failure.passed()); + EXPECT_TRUE(nonfatal_failure.failed()); + EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); + EXPECT_FALSE(nonfatal_failure.fatally_failed()); + EXPECT_FALSE(nonfatal_failure.skipped()); + + const TestPartResult fatal_failure(TestPartResult::kFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(fatal_failure.passed()); + EXPECT_TRUE(fatal_failure.failed()); + EXPECT_FALSE(fatal_failure.nonfatally_failed()); + EXPECT_TRUE(fatal_failure.fatally_failed()); + EXPECT_FALSE(fatal_failure.skipped()); + + const TestPartResult skip(TestPartResult::kSkip, "file.cc", 42, "message"); + EXPECT_FALSE(skip.passed()); + EXPECT_FALSE(skip.failed()); + EXPECT_FALSE(skip.nonfatally_failed()); + EXPECT_FALSE(skip.fatally_failed()); + EXPECT_TRUE(skip.skipped()); +} + +// Tests TestPartResult::type(). +TEST_F(TestPartResultTest, type) { + EXPECT_EQ(TestPartResult::kSuccess, r1_.type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, r2_.type()); + EXPECT_EQ(TestPartResult::kFatalFailure, r3_.type()); + EXPECT_EQ(TestPartResult::kSkip, r4_.type()); +} + +// Tests TestPartResult::file_name(). +TEST_F(TestPartResultTest, file_name) { + EXPECT_STREQ("foo/bar.cc", r1_.file_name()); + EXPECT_STREQ(nullptr, r3_.file_name()); + EXPECT_STREQ("foo/bar.cc", r4_.file_name()); +} + +// Tests TestPartResult::line_number(). +TEST_F(TestPartResultTest, line_number) { + EXPECT_EQ(10, r1_.line_number()); + EXPECT_EQ(-1, r2_.line_number()); + EXPECT_EQ(2, r4_.line_number()); +} + +// Tests TestPartResult::message(). +TEST_F(TestPartResultTest, message) { + EXPECT_STREQ("Success!", r1_.message()); + EXPECT_STREQ("Skipped!", r4_.message()); +} + +// Tests TestPartResult::passed(). +TEST_F(TestPartResultTest, Passed) { + EXPECT_TRUE(r1_.passed()); + EXPECT_FALSE(r2_.passed()); + EXPECT_FALSE(r3_.passed()); + EXPECT_FALSE(r4_.passed()); +} + +// Tests TestPartResult::failed(). +TEST_F(TestPartResultTest, Failed) { + EXPECT_FALSE(r1_.failed()); + EXPECT_TRUE(r2_.failed()); + EXPECT_TRUE(r3_.failed()); + EXPECT_FALSE(r4_.failed()); +} + +// Tests TestPartResult::failed(). +TEST_F(TestPartResultTest, Skipped) { + EXPECT_FALSE(r1_.skipped()); + EXPECT_FALSE(r2_.skipped()); + EXPECT_FALSE(r3_.skipped()); + EXPECT_TRUE(r4_.skipped()); +} + +// Tests TestPartResult::fatally_failed(). +TEST_F(TestPartResultTest, FatallyFailed) { + EXPECT_FALSE(r1_.fatally_failed()); + EXPECT_FALSE(r2_.fatally_failed()); + EXPECT_TRUE(r3_.fatally_failed()); + EXPECT_FALSE(r4_.fatally_failed()); +} + +// Tests TestPartResult::nonfatally_failed(). +TEST_F(TestPartResultTest, NonfatallyFailed) { + EXPECT_FALSE(r1_.nonfatally_failed()); + EXPECT_TRUE(r2_.nonfatally_failed()); + EXPECT_FALSE(r3_.nonfatally_failed()); + EXPECT_FALSE(r4_.nonfatally_failed()); +} + +// Tests the TestPartResultArray class. + +class TestPartResultArrayTest : public Test { + protected: + TestPartResultArrayTest() + : r1_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure 1"), + r2_(TestPartResult::kFatalFailure, "foo/bar.cc", -1, "Failure 2") {} + + const TestPartResult r1_, r2_; +}; + +// Tests that TestPartResultArray initially has size 0. +TEST_F(TestPartResultArrayTest, InitialSizeIsZero) { + TestPartResultArray results; + EXPECT_EQ(0, results.size()); +} + +// Tests that TestPartResultArray contains the given TestPartResult +// after one Append() operation. +TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) { + TestPartResultArray results; + results.Append(r1_); + EXPECT_EQ(1, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); +} + +// Tests that TestPartResultArray contains the given TestPartResults +// after two Append() operations. +TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { + TestPartResultArray results; + results.Append(r1_); + results.Append(r2_); + EXPECT_EQ(2, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); + EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); +} + +typedef TestPartResultArrayTest TestPartResultArrayDeathTest; + +// Tests that the program dies when GetTestPartResult() is called with +// an invalid index. +TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) { + TestPartResultArray results; + results.Append(r1_); + + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(-1), ""); + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(1), ""); +} + +} // namespace diff --git a/3rdparty/gtest/test/googletest-test2_test.cc b/3rdparty/gtest/test/googletest-test2_test.cc new file mode 100644 index 0000000..2e425da --- /dev/null +++ b/3rdparty/gtest/test/googletest-test2_test.cc @@ -0,0 +1,61 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include "gtest/gtest.h" +#include "googletest-param-test-test.h" + +using ::testing::Values; +using ::testing::internal::ParamGenerator; + +// Tests that generators defined in a different translation unit +// are functional. The test using extern_gen_2 is defined +// in googletest-param-test-test.cc. +ParamGenerator extern_gen_2 = Values(33); + +// Tests that a parameterized test case can be defined in one translation unit +// and instantiated in another. The test is defined in +// googletest-param-test-test.cc and ExternalInstantiationTest fixture class is +// defined in gtest-param-test_test.h. +INSTANTIATE_TEST_SUITE_P(MultiplesOf33, + ExternalInstantiationTest, + Values(33, 66)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. Another instantiation is defined +// in googletest-param-test-test.cc and +// InstantiationInMultipleTranslationUnitsTest fixture is defined in +// gtest-param-test_test.h +INSTANTIATE_TEST_SUITE_P(Sequence2, + InstantiationInMultipleTranslationUnitsTest, + Values(42*3, 42*4, 42*5)); + diff --git a/3rdparty/gtest/test/googletest-throw-on-failure-test.py b/3rdparty/gtest/test/googletest-throw-on-failure-test.py new file mode 100644 index 0000000..ea627c4 --- /dev/null +++ b/3rdparty/gtest/test/googletest-throw-on-failure-test.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests Google Test's throw-on-failure mode with exceptions disabled. + +This script invokes googletest-throw-on-failure-test_ (a program written with +Google Test) with different environments and command line flags. +""" + +import os +import gtest_test_utils + + +# Constants. + +# The command line flag for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE = 'gtest_throw_on_failure' + +# Path to the googletest-throw-on-failure-test_ program, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'googletest-throw-on-failure-test_') + + +# Utilities. + + +def SetEnvVar(env_var, value): + """Sets an environment variable to a given value; unsets it when the + given value is None. + """ + + env_var = env_var.upper() + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def Run(command): + """Runs a command; returns True/False if its exit code is/isn't 0.""" + + print('Running "%s". . .' % ' '.join(command)) + p = gtest_test_utils.Subprocess(command) + return p.exited and p.exit_code == 0 + + +# The tests. +class ThrowOnFailureTest(gtest_test_utils.TestCase): + """Tests the throw-on-failure mode.""" + + def RunAndVerify(self, env_var_value, flag_value, should_fail): + """Runs googletest-throw-on-failure-test_ and verifies that it does + (or does not) exit with a non-zero code. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + should_fail: True if and only if the program is expected to fail. + """ + + SetEnvVar(THROW_ON_FAILURE, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = '--%s=0' % THROW_ON_FAILURE + else: + flag = '--%s' % THROW_ON_FAILURE + + command = [EXE_PATH] + if flag: + command.append(flag) + + if should_fail: + should_or_not = 'should' + else: + should_or_not = 'should not' + + failed = not Run(command) + + SetEnvVar(THROW_ON_FAILURE, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a non-zero ' + 'exit code.' % + (THROW_ON_FAILURE, env_var_value_msg, ' '.join(command), + should_or_not)) + self.assert_(failed == should_fail, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, flag_value=None, should_fail=False) + + def testThrowOnFailureEnvVar(self): + """Tests using the GTEST_THROW_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value=None, + should_fail=True) + + def testThrowOnFailureFlag(self): + """Tests using the --gtest_throw_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value=None, + flag_value='1', + should_fail=True) + + def testThrowOnFailureFlagOverridesEnvVar(self): + """Tests that --gtest_throw_on_failure overrides GTEST_THROW_ON_FAILURE.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='0', + flag_value='1', + should_fail=True) + self.RunAndVerify(env_var_value='1', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value='1', + should_fail=True) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-throw-on-failure-test_.cc b/3rdparty/gtest/test/googletest-throw-on-failure-test_.cc new file mode 100644 index 0000000..83bb914 --- /dev/null +++ b/3rdparty/gtest/test/googletest-throw-on-failure-test_.cc @@ -0,0 +1,71 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Tests Google Test's throw-on-failure mode with exceptions disabled. +// +// This program must be compiled with exceptions disabled. It will be +// invoked by googletest-throw-on-failure-test.py, and is expected to exit +// with non-zero in the throw-on-failure mode or 0 otherwise. + +#include "gtest/gtest.h" + +#include // for fflush, fprintf, NULL, etc. +#include // for exit +#include // for set_terminate + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(nullptr); + exit(1); +} + +int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the throw-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + // In the throw-on-failure mode with exceptions disabled, this + // assertion will cause the program to exit with a non-zero code. + EXPECT_EQ(2, 3); + + // When not in the throw-on-failure mode, the control will reach + // here. + return 0; +} diff --git a/3rdparty/gtest/test/googletest-uninitialized-test.py b/3rdparty/gtest/test/googletest-uninitialized-test.py new file mode 100644 index 0000000..69595a0 --- /dev/null +++ b/3rdparty/gtest/test/googletest-uninitialized-test.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Verifies that Google Test warns the user when not initialized properly.""" + +import gtest_test_utils + +COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-uninitialized-test_') + + +def Assert(condition): + if not condition: + raise AssertionError + + +def AssertEq(expected, actual): + if expected != actual: + print('Expected: %s' % (expected,)) + print(' Actual: %s' % (actual,)) + raise AssertionError + + +def TestExitCodeAndOutput(command): + """Runs the given command and verifies its exit code and output.""" + + # Verifies that 'command' exits with code 1. + p = gtest_test_utils.Subprocess(command) + if p.exited and p.exit_code == 0: + Assert('IMPORTANT NOTICE' in p.output); + Assert('InitGoogleTest' in p.output) + + +class GTestUninitializedTest(gtest_test_utils.TestCase): + def testExitCodeAndOutput(self): + TestExitCodeAndOutput(COMMAND) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/googletest-uninitialized-test_.cc b/3rdparty/gtest/test/googletest-uninitialized-test_.cc new file mode 100644 index 0000000..b4434d5 --- /dev/null +++ b/3rdparty/gtest/test/googletest-uninitialized-test_.cc @@ -0,0 +1,42 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "gtest/gtest.h" + +TEST(DummyTest, Dummy) { + // This test doesn't verify anything. We just need it to create a + // realistic stage for testing the behavior of Google Test when + // RUN_ALL_TESTS() is called without + // testing::InitGoogleTest() being called first. +} + +int main() { + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/gtest-typed-test2_test.cc b/3rdparty/gtest/test/gtest-typed-test2_test.cc new file mode 100644 index 0000000..7000160 --- /dev/null +++ b/3rdparty/gtest/test/gtest-typed-test2_test.cc @@ -0,0 +1,44 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include + +#include "test/gtest-typed-test_test.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_TYPED_TEST_P + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +INSTANTIATE_TYPED_TEST_SUITE_P(Vector, ContainerTest, + testing::Types >); + +#endif // GTEST_HAS_TYPED_TEST_P diff --git a/3rdparty/gtest/test/gtest-typed-test_test.cc b/3rdparty/gtest/test/gtest-typed-test_test.cc new file mode 100644 index 0000000..5411832 --- /dev/null +++ b/3rdparty/gtest/test/gtest-typed-test_test.cc @@ -0,0 +1,462 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "test/gtest-typed-test_test.h" + +#include +#include +#include + +#include "gtest/gtest.h" + +#if _MSC_VER +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127 /* conditional expression is constant */) +#endif // _MSC_VER + +using testing::Test; + +// Used for testing that SetUpTestSuite()/TearDownTestSuite(), fixture +// ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and +// type-parameterized test. +template +class CommonTest : public Test { + // For some technical reason, SetUpTestSuite() and TearDownTestSuite() + // must be public. + public: + static void SetUpTestSuite() { + shared_ = new T(5); + } + + static void TearDownTestSuite() { + delete shared_; + shared_ = nullptr; + } + + // This 'protected:' is optional. There's no harm in making all + // members of this fixture class template public. + protected: + // We used to use std::list here, but switched to std::vector since + // MSVC's doesn't compile cleanly with /W4. + typedef std::vector Vector; + typedef std::set IntSet; + + CommonTest() : value_(1) {} + + ~CommonTest() override { EXPECT_EQ(3, value_); } + + void SetUp() override { + EXPECT_EQ(1, value_); + value_++; + } + + void TearDown() override { + EXPECT_EQ(2, value_); + value_++; + } + + T value_; + static T* shared_; +}; + +template +T* CommonTest::shared_ = nullptr; + +// This #ifdef block tests typed tests. +#if GTEST_HAS_TYPED_TEST + +using testing::Types; + +// Tests that SetUpTestSuite()/TearDownTestSuite(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in typed tests + +typedef Types TwoTypes; +TYPED_TEST_SUITE(CommonTest, TwoTypes); + +TYPED_TEST(CommonTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Typedefs in the fixture class template can be visited via the + // "typename TestFixture::" prefix. + typename TestFixture::Vector empty; + EXPECT_EQ(0U, empty.size()); + + typename TestFixture::IntSet empty2; + EXPECT_EQ(0U, empty2.size()); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST(CommonTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != nullptr); + EXPECT_EQ(5, *this->shared_); + + // TypeParam can be used to refer to the type parameter. + EXPECT_EQ(static_cast(2), this->value_); +} + +// Tests that multiple TYPED_TEST_SUITE's can be defined in the same +// translation unit. + +template +class TypedTest1 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_SUITE can be a +// single type. +TYPED_TEST_SUITE(TypedTest1, int); +TYPED_TEST(TypedTest1, A) {} + +template +class TypedTest2 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_SUITE can be a +// Types<...> type list. +TYPED_TEST_SUITE(TypedTest2, Types); + +// This also verifies that tests from different typed test cases can +// share the same name. +TYPED_TEST(TypedTest2, A) {} + +// Tests that a typed test case can be defined in a namespace. + +namespace library1 { + +template +class NumericTest : public Test { +}; + +typedef Types NumericTypes; +TYPED_TEST_SUITE(NumericTest, NumericTypes); + +TYPED_TEST(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +} // namespace library1 + +// Tests that custom names work. +template +class TypedTestWithNames : public Test {}; + +class TypedTestNames { + public: + template + static std::string GetName(int i) { + if (std::is_same::value) { + return std::string("char") + ::testing::PrintToString(i); + } + if (std::is_same::value) { + return std::string("int") + ::testing::PrintToString(i); + } + } +}; + +TYPED_TEST_SUITE(TypedTestWithNames, TwoTypes, TypedTestNames); + +TYPED_TEST(TypedTestWithNames, TestSuiteName) { + if (std::is_same::value) { + EXPECT_STREQ(::testing::UnitTest::GetInstance() + ->current_test_info() + ->test_case_name(), + "TypedTestWithNames/char0"); + } + if (std::is_same::value) { + EXPECT_STREQ(::testing::UnitTest::GetInstance() + ->current_test_info() + ->test_case_name(), + "TypedTestWithNames/int1"); + } +} + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests type-parameterized tests. +#if GTEST_HAS_TYPED_TEST_P + +using testing::Types; +using testing::internal::TypedTestSuitePState; + +// Tests TypedTestSuitePState. + +class TypedTestSuitePStateTest : public Test { + protected: + void SetUp() override { + state_.AddTestName("foo.cc", 0, "FooTest", "A"); + state_.AddTestName("foo.cc", 0, "FooTest", "B"); + state_.AddTestName("foo.cc", 0, "FooTest", "C"); + } + + TypedTestSuitePState state_; +}; + +TEST_F(TypedTestSuitePStateTest, SucceedsForMatchingList) { + const char* tests = "A, B, C"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +// Makes sure that the order of the tests and spaces around the names +// don't matter. +TEST_F(TypedTestSuitePStateTest, IgnoresOrderAndSpaces) { + const char* tests = "A,C, B"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +using TypedTestSuitePStateDeathTest = TypedTestSuitePStateTest; + +TEST_F(TypedTestSuitePStateDeathTest, DetectsDuplicates) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), + "foo\\.cc.1.?: Test A is listed more than once\\."); +} + +TEST_F(TypedTestSuitePStateDeathTest, DetectsExtraTest) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), + "foo\\.cc.1.?: No test named D can be found in this test suite\\."); +} + +TEST_F(TypedTestSuitePStateDeathTest, DetectsMissedTest) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), + "foo\\.cc.1.?: You forgot to list test B\\."); +} + +// Tests that defining a test for a parameterized test case generates +// a run-time error if the test case has been registered. +TEST_F(TypedTestSuitePStateDeathTest, DetectsTestAfterRegistration) { + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); + EXPECT_DEATH_IF_SUPPORTED( + state_.AddTestName("foo.cc", 2, "FooTest", "D"), + "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_SUITE_P" + "\\(FooTest, \\.\\.\\.\\)\\."); +} + +// Tests that SetUpTestSuite()/TearDownTestSuite(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in type-parameterized tests. + +template +class DerivedTest : public CommonTest { +}; + +TYPED_TEST_SUITE_P(DerivedTest); + +TYPED_TEST_P(DerivedTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != nullptr); + EXPECT_EQ(5, *this->shared_); + EXPECT_EQ(2, this->value_); +} + +REGISTER_TYPED_TEST_SUITE_P(DerivedTest, + ValuesAreCorrect, ValuesAreStillCorrect); + +typedef Types MyTwoTypes; +INSTANTIATE_TYPED_TEST_SUITE_P(My, DerivedTest, MyTwoTypes); + +// Tests that custom names work with type parametrized tests. We reuse the +// TwoTypes from above here. +template +class TypeParametrizedTestWithNames : public Test {}; + +TYPED_TEST_SUITE_P(TypeParametrizedTestWithNames); + +TYPED_TEST_P(TypeParametrizedTestWithNames, TestSuiteName) { + if (std::is_same::value) { + EXPECT_STREQ(::testing::UnitTest::GetInstance() + ->current_test_info() + ->test_case_name(), + "CustomName/TypeParametrizedTestWithNames/parChar0"); + } + if (std::is_same::value) { + EXPECT_STREQ(::testing::UnitTest::GetInstance() + ->current_test_info() + ->test_case_name(), + "CustomName/TypeParametrizedTestWithNames/parInt1"); + } +} + +REGISTER_TYPED_TEST_SUITE_P(TypeParametrizedTestWithNames, TestSuiteName); + +class TypeParametrizedTestNames { + public: + template + static std::string GetName(int i) { + if (std::is_same::value) { + return std::string("parChar") + ::testing::PrintToString(i); + } + if (std::is_same::value) { + return std::string("parInt") + ::testing::PrintToString(i); + } + } +}; + +INSTANTIATE_TYPED_TEST_SUITE_P(CustomName, TypeParametrizedTestWithNames, + TwoTypes, TypeParametrizedTestNames); + +// Tests that multiple TYPED_TEST_SUITE_P's can be defined in the same +// translation unit. + +template +class TypedTestP1 : public Test { +}; + +TYPED_TEST_SUITE_P(TypedTestP1); + +// For testing that the code between TYPED_TEST_SUITE_P() and +// TYPED_TEST_P() is not enclosed in a namespace. +using IntAfterTypedTestSuiteP = int; + +TYPED_TEST_P(TypedTestP1, A) {} +TYPED_TEST_P(TypedTestP1, B) {} + +// For testing that the code between TYPED_TEST_P() and +// REGISTER_TYPED_TEST_SUITE_P() is not enclosed in a namespace. +using IntBeforeRegisterTypedTestSuiteP = int; + +REGISTER_TYPED_TEST_SUITE_P(TypedTestP1, A, B); + +template +class TypedTestP2 : public Test { +}; + +TYPED_TEST_SUITE_P(TypedTestP2); + +// This also verifies that tests from different type-parameterized +// test cases can share the same name. +TYPED_TEST_P(TypedTestP2, A) {} + +REGISTER_TYPED_TEST_SUITE_P(TypedTestP2, A); + +// Verifies that the code between TYPED_TEST_SUITE_P() and +// REGISTER_TYPED_TEST_SUITE_P() is not enclosed in a namespace. +IntAfterTypedTestSuiteP after = 0; +IntBeforeRegisterTypedTestSuiteP before = 0; + +// Verifies that the last argument of INSTANTIATE_TYPED_TEST_SUITE_P() +// can be either a single type or a Types<...> type list. +INSTANTIATE_TYPED_TEST_SUITE_P(Int, TypedTestP1, int); +INSTANTIATE_TYPED_TEST_SUITE_P(Int, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated more than once in the same translation unit. +INSTANTIATE_TYPED_TEST_SUITE_P(Double, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +typedef Types, std::set > MyContainers; +INSTANTIATE_TYPED_TEST_SUITE_P(My, ContainerTest, MyContainers); + +// Tests that a type-parameterized test case can be defined and +// instantiated in a namespace. + +namespace library2 { + +template +class NumericTest : public Test { +}; + +TYPED_TEST_SUITE_P(NumericTest); + +TYPED_TEST_P(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) { + EXPECT_LT(TypeParam(0), TypeParam(1)); +} + +REGISTER_TYPED_TEST_SUITE_P(NumericTest, + DefaultIsZero, ZeroIsLessThanOne); +typedef Types NumericTypes; +INSTANTIATE_TYPED_TEST_SUITE_P(My, NumericTest, NumericTypes); + +static const char* GetTestName() { + return testing::UnitTest::GetInstance()->current_test_info()->name(); +} +// Test the stripping of space from test names +template class TrimmedTest : public Test { }; +TYPED_TEST_SUITE_P(TrimmedTest); +TYPED_TEST_P(TrimmedTest, Test1) { EXPECT_STREQ("Test1", GetTestName()); } +TYPED_TEST_P(TrimmedTest, Test2) { EXPECT_STREQ("Test2", GetTestName()); } +TYPED_TEST_P(TrimmedTest, Test3) { EXPECT_STREQ("Test3", GetTestName()); } +TYPED_TEST_P(TrimmedTest, Test4) { EXPECT_STREQ("Test4", GetTestName()); } +TYPED_TEST_P(TrimmedTest, Test5) { EXPECT_STREQ("Test5", GetTestName()); } +REGISTER_TYPED_TEST_SUITE_P( + TrimmedTest, + Test1, Test2,Test3 , Test4 ,Test5 ); // NOLINT +template struct MyPair {}; +// Be sure to try a type with a comma in its name just in case it matters. +typedef Types > TrimTypes; +INSTANTIATE_TYPED_TEST_SUITE_P(My, TrimmedTest, TrimTypes); + +} // namespace library2 + +#endif // GTEST_HAS_TYPED_TEST_P + +#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) + +// Google Test may not support type-parameterized tests with some +// compilers. If we use conditional compilation to compile out all +// code referring to the gtest_main library, MSVC linker will not link +// that library at all and consequently complain about missing entry +// point defined in that library (fatal error LNK1561: entry point +// must be defined). This dummy test keeps gtest_main linked in. +TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {} + +#if _MSC_VER +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4127 +#endif // _MSC_VER + +#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) diff --git a/3rdparty/gtest/test/gtest-typed-test_test.h b/3rdparty/gtest/test/gtest-typed-test_test.h new file mode 100644 index 0000000..23137b7 --- /dev/null +++ b/3rdparty/gtest/test/gtest-typed-test_test.h @@ -0,0 +1,65 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ +#define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ + +#include "gtest/gtest.h" + +#if GTEST_HAS_TYPED_TEST_P + +using testing::Test; + +// For testing that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// ContainerTest will be instantiated in both gtest-typed-test_test.cc +// and gtest-typed-test2_test.cc. + +template +class ContainerTest : public Test { +}; + +TYPED_TEST_SUITE_P(ContainerTest); + +TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) { + TypeParam container; +} + +TYPED_TEST_P(ContainerTest, InitialSizeIsZero) { + TypeParam container; + EXPECT_EQ(0U, container.size()); +} + +REGISTER_TYPED_TEST_SUITE_P(ContainerTest, + CanBeDefaultConstructed, InitialSizeIsZero); + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ diff --git a/3rdparty/gtest/test/gtest-unittest-api_test.cc b/3rdparty/gtest/test/gtest-unittest-api_test.cc new file mode 100644 index 0000000..480a41f --- /dev/null +++ b/3rdparty/gtest/test/gtest-unittest-api_test.cc @@ -0,0 +1,340 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This file contains tests verifying correctness of data provided via +// UnitTest's public methods. + +#include "gtest/gtest.h" + +#include // For strcmp. +#include + +using ::testing::InitGoogleTest; + +namespace testing { +namespace internal { + +template +struct LessByName { + bool operator()(const T* a, const T* b) { + return strcmp(a->name(), b->name()) < 0; + } +}; + +class UnitTestHelper { + public: + // Returns the array of pointers to all test suites sorted by the test suite + // name. The caller is responsible for deleting the array. + static TestSuite const** GetSortedTestSuites() { + UnitTest& unit_test = *UnitTest::GetInstance(); + auto const** const test_suites = + new const TestSuite*[unit_test.total_test_suite_count()]; + + for (int i = 0; i < unit_test.total_test_suite_count(); ++i) + test_suites[i] = unit_test.GetTestSuite(i); + + std::sort(test_suites, + test_suites + unit_test.total_test_suite_count(), + LessByName()); + return test_suites; + } + + // Returns the test suite by its name. The caller doesn't own the returned + // pointer. + static const TestSuite* FindTestSuite(const char* name) { + UnitTest& unit_test = *UnitTest::GetInstance(); + for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { + const TestSuite* test_suite = unit_test.GetTestSuite(i); + if (0 == strcmp(test_suite->name(), name)) + return test_suite; + } + return nullptr; + } + + // Returns the array of pointers to all tests in a particular test suite + // sorted by the test name. The caller is responsible for deleting the + // array. + static TestInfo const** GetSortedTests(const TestSuite* test_suite) { + TestInfo const** const tests = + new const TestInfo*[test_suite->total_test_count()]; + + for (int i = 0; i < test_suite->total_test_count(); ++i) + tests[i] = test_suite->GetTestInfo(i); + + std::sort(tests, tests + test_suite->total_test_count(), + LessByName()); + return tests; + } +}; + +#if GTEST_HAS_TYPED_TEST +template class TestSuiteWithCommentTest : public Test {}; +TYPED_TEST_SUITE(TestSuiteWithCommentTest, Types); +TYPED_TEST(TestSuiteWithCommentTest, Dummy) {} + +const int kTypedTestSuites = 1; +const int kTypedTests = 1; +#else +const int kTypedTestSuites = 0; +const int kTypedTests = 0; +#endif // GTEST_HAS_TYPED_TEST + +// We can only test the accessors that do not change value while tests run. +// Since tests can be run in any order, the values the accessors that track +// test execution (such as failed_test_count) can not be predicted. +TEST(ApiTest, UnitTestImmutableAccessorsWork) { + UnitTest* unit_test = UnitTest::GetInstance(); + + ASSERT_EQ(2 + kTypedTestSuites, unit_test->total_test_suite_count()); + EXPECT_EQ(1 + kTypedTestSuites, unit_test->test_suite_to_run_count()); + EXPECT_EQ(2, unit_test->disabled_test_count()); + EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count()); + + const TestSuite** const test_suites = UnitTestHelper::GetSortedTestSuites(); + + EXPECT_STREQ("ApiTest", test_suites[0]->name()); + EXPECT_STREQ("DISABLED_Test", test_suites[1]->name()); +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestSuiteWithCommentTest/0", test_suites[2]->name()); +#endif // GTEST_HAS_TYPED_TEST + + delete[] test_suites; + + // The following lines initiate actions to verify certain methods in + // FinalSuccessChecker::TearDown. + + // Records a test property to verify TestResult::GetTestProperty(). + RecordProperty("key", "value"); +} + +AssertionResult IsNull(const char* str) { + if (str != nullptr) { + return testing::AssertionFailure() << "argument is " << str; + } + return AssertionSuccess(); +} + +TEST(ApiTest, TestSuiteImmutableAccessorsWork) { + const TestSuite* test_suite = UnitTestHelper::FindTestSuite("ApiTest"); + ASSERT_TRUE(test_suite != nullptr); + + EXPECT_STREQ("ApiTest", test_suite->name()); + EXPECT_TRUE(IsNull(test_suite->type_param())); + EXPECT_TRUE(test_suite->should_run()); + EXPECT_EQ(1, test_suite->disabled_test_count()); + EXPECT_EQ(3, test_suite->test_to_run_count()); + ASSERT_EQ(4, test_suite->total_test_count()); + + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_suite); + + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_suite_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_TRUE(IsNull(tests[0]->type_param())); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestSuiteDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_suite_name()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); + EXPECT_TRUE(tests[1]->should_run()); + + EXPECT_STREQ("TestSuiteImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_suite_name()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); + EXPECT_TRUE(tests[2]->should_run()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_suite_name()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); + EXPECT_TRUE(tests[3]->should_run()); + + delete[] tests; + tests = nullptr; + +#if GTEST_HAS_TYPED_TEST + test_suite = UnitTestHelper::FindTestSuite("TestSuiteWithCommentTest/0"); + ASSERT_TRUE(test_suite != nullptr); + + EXPECT_STREQ("TestSuiteWithCommentTest/0", test_suite->name()); + EXPECT_STREQ(GetTypeName().c_str(), test_suite->type_param()); + EXPECT_TRUE(test_suite->should_run()); + EXPECT_EQ(0, test_suite->disabled_test_count()); + EXPECT_EQ(1, test_suite->test_to_run_count()); + ASSERT_EQ(1, test_suite->total_test_count()); + + tests = UnitTestHelper::GetSortedTests(test_suite); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestSuiteWithCommentTest/0", tests[0]->test_suite_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); + EXPECT_TRUE(tests[0]->should_run()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST +} + +TEST(ApiTest, TestSuiteDisabledAccessorsWork) { + const TestSuite* test_suite = UnitTestHelper::FindTestSuite("DISABLED_Test"); + ASSERT_TRUE(test_suite != nullptr); + + EXPECT_STREQ("DISABLED_Test", test_suite->name()); + EXPECT_TRUE(IsNull(test_suite->type_param())); + EXPECT_FALSE(test_suite->should_run()); + EXPECT_EQ(1, test_suite->disabled_test_count()); + EXPECT_EQ(0, test_suite->test_to_run_count()); + ASSERT_EQ(1, test_suite->total_test_count()); + + const TestInfo* const test_info = test_suite->GetTestInfo(0); + EXPECT_STREQ("Dummy2", test_info->name()); + EXPECT_STREQ("DISABLED_Test", test_info->test_suite_name()); + EXPECT_TRUE(IsNull(test_info->value_param())); + EXPECT_TRUE(IsNull(test_info->type_param())); + EXPECT_FALSE(test_info->should_run()); +} + +// These two tests are here to provide support for testing +// test_suite_to_run_count, disabled_test_count, and test_to_run_count. +TEST(ApiTest, DISABLED_Dummy1) {} +TEST(DISABLED_Test, Dummy2) {} + +class FinalSuccessChecker : public Environment { + protected: + void TearDown() override { + UnitTest* unit_test = UnitTest::GetInstance(); + + EXPECT_EQ(1 + kTypedTestSuites, unit_test->successful_test_suite_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count()); + EXPECT_EQ(0, unit_test->failed_test_suite_count()); + EXPECT_EQ(0, unit_test->failed_test_count()); + EXPECT_TRUE(unit_test->Passed()); + EXPECT_FALSE(unit_test->Failed()); + ASSERT_EQ(2 + kTypedTestSuites, unit_test->total_test_suite_count()); + + const TestSuite** const test_suites = UnitTestHelper::GetSortedTestSuites(); + + EXPECT_STREQ("ApiTest", test_suites[0]->name()); + EXPECT_TRUE(IsNull(test_suites[0]->type_param())); + EXPECT_TRUE(test_suites[0]->should_run()); + EXPECT_EQ(1, test_suites[0]->disabled_test_count()); + ASSERT_EQ(4, test_suites[0]->total_test_count()); + EXPECT_EQ(3, test_suites[0]->successful_test_count()); + EXPECT_EQ(0, test_suites[0]->failed_test_count()); + EXPECT_TRUE(test_suites[0]->Passed()); + EXPECT_FALSE(test_suites[0]->Failed()); + + EXPECT_STREQ("DISABLED_Test", test_suites[1]->name()); + EXPECT_TRUE(IsNull(test_suites[1]->type_param())); + EXPECT_FALSE(test_suites[1]->should_run()); + EXPECT_EQ(1, test_suites[1]->disabled_test_count()); + ASSERT_EQ(1, test_suites[1]->total_test_count()); + EXPECT_EQ(0, test_suites[1]->successful_test_count()); + EXPECT_EQ(0, test_suites[1]->failed_test_count()); + +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestSuiteWithCommentTest/0", test_suites[2]->name()); + EXPECT_STREQ(GetTypeName().c_str(), test_suites[2]->type_param()); + EXPECT_TRUE(test_suites[2]->should_run()); + EXPECT_EQ(0, test_suites[2]->disabled_test_count()); + ASSERT_EQ(1, test_suites[2]->total_test_count()); + EXPECT_EQ(1, test_suites[2]->successful_test_count()); + EXPECT_EQ(0, test_suites[2]->failed_test_count()); + EXPECT_TRUE(test_suites[2]->Passed()); + EXPECT_FALSE(test_suites[2]->Failed()); +#endif // GTEST_HAS_TYPED_TEST + + const TestSuite* test_suite = UnitTestHelper::FindTestSuite("ApiTest"); + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_suite); + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_suite_name()); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestSuiteDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_suite_name()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); + EXPECT_TRUE(tests[1]->should_run()); + EXPECT_TRUE(tests[1]->result()->Passed()); + EXPECT_EQ(0, tests[1]->result()->test_property_count()); + + EXPECT_STREQ("TestSuiteImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_suite_name()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); + EXPECT_TRUE(tests[2]->should_run()); + EXPECT_TRUE(tests[2]->result()->Passed()); + EXPECT_EQ(0, tests[2]->result()->test_property_count()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_suite_name()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); + EXPECT_TRUE(tests[3]->should_run()); + EXPECT_TRUE(tests[3]->result()->Passed()); + EXPECT_EQ(1, tests[3]->result()->test_property_count()); + const TestProperty& property = tests[3]->result()->GetTestProperty(0); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); + + delete[] tests; + +#if GTEST_HAS_TYPED_TEST + test_suite = UnitTestHelper::FindTestSuite("TestSuiteWithCommentTest/0"); + tests = UnitTestHelper::GetSortedTests(test_suite); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestSuiteWithCommentTest/0", tests[0]->test_suite_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); + EXPECT_TRUE(tests[0]->should_run()); + EXPECT_TRUE(tests[0]->result()->Passed()); + EXPECT_EQ(0, tests[0]->result()->test_property_count()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST + delete[] test_suites; + } +}; + +} // namespace internal +} // namespace testing + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + AddGlobalTestEnvironment(new testing::internal::FinalSuccessChecker()); + + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/gtest_all_test.cc b/3rdparty/gtest/test/gtest_all_test.cc new file mode 100644 index 0000000..615b29b --- /dev/null +++ b/3rdparty/gtest/test/gtest_all_test.cc @@ -0,0 +1,46 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests for Google C++ Testing and Mocking Framework (Google Test) +// +// Sometimes it's desirable to build most of Google Test's own tests +// by compiling a single file. This file serves this purpose. +#include "test/googletest-filepath-test.cc" +#include "test/googletest-message-test.cc" +#include "test/googletest-options-test.cc" +#include "test/googletest-port-test.cc" +#include "test/googletest-test-part-test.cc" +#include "test/gtest-typed-test2_test.cc" +#include "test/gtest-typed-test_test.cc" +#include "test/gtest_pred_impl_unittest.cc" +#include "test/gtest_prod_test.cc" +#include "test/gtest_skip_test.cc" +#include "test/gtest_unittest.cc" +#include "test/production.cc" diff --git a/3rdparty/gtest/test/gtest_assert_by_exception_test.cc b/3rdparty/gtest/test/gtest_assert_by_exception_test.cc new file mode 100644 index 0000000..ada4cb3 --- /dev/null +++ b/3rdparty/gtest/test/gtest_assert_by_exception_test.cc @@ -0,0 +1,116 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Tests Google Test's assert-by-exception mode with exceptions enabled. + +#include "gtest/gtest.h" + +#include +#include +#include +#include + +class ThrowListener : public testing::EmptyTestEventListener { + void OnTestPartResult(const testing::TestPartResult& result) override { + if (result.type() == testing::TestPartResult::kFatalFailure) { + throw testing::AssertionException(result); + } + } +}; + +// Prints the given failure message and exits the program with +// non-zero. We use this instead of a Google Test assertion to +// indicate a failure, as the latter is been tested and cannot be +// relied on. +void Fail(const char* msg) { + printf("FAILURE: %s\n", msg); + fflush(stdout); + exit(1); +} + +static void AssertFalse() { + ASSERT_EQ(2, 3) << "Expected failure"; +} + +// Tests that an assertion failure throws a subclass of +// std::runtime_error. +TEST(Test, Test) { + // A successful assertion shouldn't throw. + try { + EXPECT_EQ(3, 3); + } catch(...) { + Fail("A successful assertion wrongfully threw."); + } + + // A successful assertion shouldn't throw. + try { + EXPECT_EQ(3, 4); + } catch(...) { + Fail("A failed non-fatal assertion wrongfully threw."); + } + + // A failed assertion should throw. + try { + AssertFalse(); + } catch(const testing::AssertionException& e) { + if (strstr(e.what(), "Expected failure") != nullptr) throw; + + printf("%s", + "A failed assertion did throw an exception of the right type, " + "but the message is incorrect. Instead of containing \"Expected " + "failure\", it is:\n"); + Fail(e.what()); + } catch(...) { + Fail("A failed assertion threw the wrong type of exception."); + } + Fail("A failed assertion should've thrown but didn't."); +} + +int kTestForContinuingTest = 0; + +TEST(Test, Test2) { + kTestForContinuingTest = 1; +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + testing::UnitTest::GetInstance()->listeners().Append(new ThrowListener); + + int result = RUN_ALL_TESTS(); + if (result == 0) { + printf("RUN_ALL_TESTS returned %d\n", result); + Fail("Expected failure instead."); + } + + if (kTestForContinuingTest == 0) { + Fail("Should have continued with other tests, but did not."); + } + return 0; +} diff --git a/3rdparty/gtest/test/gtest_environment_test.cc b/3rdparty/gtest/test/gtest_environment_test.cc new file mode 100644 index 0000000..064bfc5 --- /dev/null +++ b/3rdparty/gtest/test/gtest_environment_test.cc @@ -0,0 +1,188 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests using global test environments. + +#include +#include +#include "gtest/gtest.h" +#include "src/gtest-internal-inl.h" + +namespace testing { +GTEST_DECLARE_string_(filter); +} + +namespace { + +enum FailureType { + NO_FAILURE, NON_FATAL_FAILURE, FATAL_FAILURE +}; + +// For testing using global test environments. +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() { Reset(); } + + // Depending on the value of failure_in_set_up_, SetUp() will + // generate a non-fatal failure, generate a fatal failure, or + // succeed. + void SetUp() override { + set_up_was_run_ = true; + + switch (failure_in_set_up_) { + case NON_FATAL_FAILURE: + ADD_FAILURE() << "Expected non-fatal failure in global set-up."; + break; + case FATAL_FAILURE: + FAIL() << "Expected fatal failure in global set-up."; + break; + default: + break; + } + } + + // Generates a non-fatal failure. + void TearDown() override { + tear_down_was_run_ = true; + ADD_FAILURE() << "Expected non-fatal failure in global tear-down."; + } + + // Resets the state of the environment s.t. it can be reused. + void Reset() { + failure_in_set_up_ = NO_FAILURE; + set_up_was_run_ = false; + tear_down_was_run_ = false; + } + + // We call this function to set the type of failure SetUp() should + // generate. + void set_failure_in_set_up(FailureType type) { + failure_in_set_up_ = type; + } + + // Was SetUp() run? + bool set_up_was_run() const { return set_up_was_run_; } + + // Was TearDown() run? + bool tear_down_was_run() const { return tear_down_was_run_; } + + private: + FailureType failure_in_set_up_; + bool set_up_was_run_; + bool tear_down_was_run_; +}; + +// Was the TEST run? +bool test_was_run; + +// The sole purpose of this TEST is to enable us to check whether it +// was run. +TEST(FooTest, Bar) { + test_was_run = true; +} + +// Prints the message and aborts the program if condition is false. +void Check(bool condition, const char* msg) { + if (!condition) { + printf("FAILED: %s\n", msg); + testing::internal::posix::Abort(); + } +} + +// Runs the tests. Return true if and only if successful. +// +// The 'failure' parameter specifies the type of failure that should +// be generated by the global set-up. +int RunAllTests(MyEnvironment* env, FailureType failure) { + env->Reset(); + env->set_failure_in_set_up(failure); + test_was_run = false; + testing::internal::GetUnitTestImpl()->ClearAdHocTestResult(); + return RUN_ALL_TESTS(); +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // Registers a global test environment, and verifies that the + // registration function returns its argument. + MyEnvironment* const env = new MyEnvironment; + Check(testing::AddGlobalTestEnvironment(env) == env, + "AddGlobalTestEnvironment() should return its argument."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up is successful. + Check(RunAllTests(env, NO_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global tear-down " + "should generate a failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "failure"); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up generates no fatal failure. + Check(RunAllTests(env, NON_FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as both the global set-up " + "and the global tear-down should generate a non-fatal failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs no test when the global set-up + // generates a fatal failure. + Check(RunAllTests(env, FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global set-up " + "should generate a fatal failure."); + Check(!test_was_run, + "The tests should not run, as the global set-up should generate " + "a fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() doesn't do global set-up or + // tear-down when there is no test to run. + testing::GTEST_FLAG(filter) = "-*"; + Check(RunAllTests(env, NO_FAILURE) == 0, + "RUN_ALL_TESTS() should return zero, as there is no test to run."); + Check(!env->set_up_was_run(), + "The global set-up should not run, as there is no test to run."); + Check(!env->tear_down_was_run(), + "The global tear-down should not run, " + "as the global set-up was not run."); + + printf("PASS\n"); + return 0; +} diff --git a/3rdparty/gtest/test/gtest_help_test.py b/3rdparty/gtest/test/gtest_help_test.py new file mode 100644 index 0000000..582d24c --- /dev/null +++ b/3rdparty/gtest/test/gtest_help_test.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests the --help flag of Google C++ Testing and Mocking Framework. + +SYNOPSIS + gtest_help_test.py --build_dir=BUILD/DIR + # where BUILD/DIR contains the built gtest_help_test_ file. + gtest_help_test.py +""" + +import os +import re +import gtest_test_utils + + +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' +IS_WINDOWS = os.name == 'nt' + +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_') +FLAG_PREFIX = '--gtest_' +DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' +STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to' +UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG), + re.sub('^--', '/', LIST_TESTS_FLAG), + re.sub('_', '-', LIST_TESTS_FLAG)] +INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing' + +SUPPORTS_DEATH_TESTS = "DeathTest" in gtest_test_utils.Subprocess( + [PROGRAM_PATH, LIST_TESTS_FLAG]).output + +# The help message must match this regex. +HELP_REGEX = re.compile( + FLAG_PREFIX + r'list_tests.*' + + FLAG_PREFIX + r'filter=.*' + + FLAG_PREFIX + r'also_run_disabled_tests.*' + + FLAG_PREFIX + r'repeat=.*' + + FLAG_PREFIX + r'shuffle.*' + + FLAG_PREFIX + r'random_seed=.*' + + FLAG_PREFIX + r'color=.*' + + FLAG_PREFIX + r'print_time.*' + + FLAG_PREFIX + r'output=.*' + + FLAG_PREFIX + r'break_on_failure.*' + + FLAG_PREFIX + r'throw_on_failure.*' + + FLAG_PREFIX + r'catch_exceptions=0.*', + re.DOTALL) + + +def RunWithFlag(flag): + """Runs gtest_help_test_ with the given flag. + + Returns: + the exit code and the text output as a tuple. + Args: + flag: the command-line flag to pass to gtest_help_test_, or None. + """ + + if flag is None: + command = [PROGRAM_PATH] + else: + command = [PROGRAM_PATH, flag] + child = gtest_test_utils.Subprocess(command) + return child.exit_code, child.output + + +class GTestHelpTest(gtest_test_utils.TestCase): + """Tests the --help flag and its equivalent forms.""" + + def TestHelpFlag(self, flag): + """Verifies correct behavior when help flag is specified. + + The right message must be printed and the tests must + skipped when the given flag is specified. + + Args: + flag: A flag to pass to the binary or None. + """ + + exit_code, output = RunWithFlag(flag) + self.assertEquals(0, exit_code) + self.assert_(HELP_REGEX.search(output), output) + + if IS_LINUX: + self.assert_(STREAM_RESULT_TO_FLAG in output, output) + else: + self.assert_(STREAM_RESULT_TO_FLAG not in output, output) + + if SUPPORTS_DEATH_TESTS and not IS_WINDOWS: + self.assert_(DEATH_TEST_STYLE_FLAG in output, output) + else: + self.assert_(DEATH_TEST_STYLE_FLAG not in output, output) + + def TestNonHelpFlag(self, flag): + """Verifies correct behavior when no help flag is specified. + + Verifies that when no help flag is specified, the tests are run + and the help message is not printed. + + Args: + flag: A flag to pass to the binary or None. + """ + + exit_code, output = RunWithFlag(flag) + self.assert_(exit_code != 0) + self.assert_(not HELP_REGEX.search(output), output) + + def testPrintsHelpWithFullFlag(self): + self.TestHelpFlag('--help') + + def testPrintsHelpWithShortFlag(self): + self.TestHelpFlag('-h') + + def testPrintsHelpWithQuestionFlag(self): + self.TestHelpFlag('-?') + + def testPrintsHelpWithWindowsStyleQuestionFlag(self): + self.TestHelpFlag('/?') + + def testPrintsHelpWithUnrecognizedGoogleTestFlag(self): + self.TestHelpFlag(UNKNOWN_FLAG) + + def testPrintsHelpWithIncorrectFlagStyle(self): + for incorrect_flag in INCORRECT_FLAG_VARIANTS: + self.TestHelpFlag(incorrect_flag) + + def testRunsTestsWithoutHelpFlag(self): + """Verifies that when no help flag is specified, the tests are run + and the help message is not printed.""" + + self.TestNonHelpFlag(None) + + def testRunsTestsWithGtestInternalFlag(self): + """Verifies that the tests are run and no help message is printed when + a flag starting with Google Test prefix and 'internal_' is supplied.""" + + self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/gtest_help_test_.cc b/3rdparty/gtest/test/gtest_help_test_.cc new file mode 100644 index 0000000..750ae6c --- /dev/null +++ b/3rdparty/gtest/test/gtest_help_test_.cc @@ -0,0 +1,45 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// This program is meant to be run by gtest_help_test.py. Do not run +// it directly. + +#include "gtest/gtest.h" + +// When a help flag is specified, this program should skip the tests +// and exit with 0; otherwise the following test will be executed, +// causing this program to exit with a non-zero code. +TEST(HelpFlagTest, ShouldNotBeRun) { + ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified."; +} + +#if GTEST_HAS_DEATH_TEST +TEST(DeathTest, UsedByPythonScriptToDetectSupportForDeathTestsInThisBinary) {} +#endif diff --git a/3rdparty/gtest/test/gtest_json_test_utils.py b/3rdparty/gtest/test/gtest_json_test_utils.py new file mode 100644 index 0000000..62bbfc2 --- /dev/null +++ b/3rdparty/gtest/test/gtest_json_test_utils.py @@ -0,0 +1,60 @@ +# Copyright 2018, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test utilities for gtest_json_output.""" + +import re + + +def normalize(obj): + """Normalize output object. + + Args: + obj: Google Test's JSON output object to normalize. + + Returns: + Normalized output without any references to transient information that may + change from run to run. + """ + def _normalize(key, value): + if key == 'time': + return re.sub(r'^\d+(\.\d+)?s$', '*', value) + elif key == 'timestamp': + return re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$', '*', value) + elif key == 'failure': + value = re.sub(r'^.*[/\\](.*:)\d+\n', '\\1*\n', value) + return re.sub(r'Stack trace:\n(.|\n)*', 'Stack trace:\n*', value) + else: + return normalize(value) + if isinstance(obj, dict): + return {k: _normalize(k, v) for k, v in obj.items()} + if isinstance(obj, list): + return [normalize(x) for x in obj] + else: + return obj diff --git a/3rdparty/gtest/test/gtest_list_output_unittest.py b/3rdparty/gtest/test/gtest_list_output_unittest.py new file mode 100644 index 0000000..3bba7ea --- /dev/null +++ b/3rdparty/gtest/test/gtest_list_output_unittest.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +"""Unit test for Google Test's --gtest_list_tests flag. + +A user can ask Google Test to list all tests by specifying the +--gtest_list_tests flag. If output is requested, via --gtest_output=xml +or --gtest_output=json, the tests are listed, with extra information in the +output file. +This script tests such functionality by invoking gtest_list_output_unittest_ + (a program written with Google Test) the command line flags. +""" + +import os +import re +import gtest_test_utils + +GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' +GTEST_OUTPUT_FLAG = '--gtest_output' + +EXPECTED_XML = """<\?xml version="1.0" encoding="UTF-8"\?> + + + + + + +""" + +EXPECTED_JSON = """{ + "tests": 2, + "name": "AllTests", + "testsuites": \[ + { + "name": "FooTest", + "tests": 2, + "testsuite": \[ + { + "name": "Test1", + "file": ".*gtest_list_output_unittest_.cc", + "line": 43 + }, + { + "name": "Test2", + "file": ".*gtest_list_output_unittest_.cc", + "line": 45 + } + \] + } + \] +} +""" + + +class GTestListTestsOutputUnitTest(gtest_test_utils.TestCase): + """Unit test for Google Test's list tests with output to file functionality. + """ + + def testXml(self): + """Verifies XML output for listing tests in a Google Test binary. + + Runs a test program that generates an empty XML output, and + tests that the XML output is expected. + """ + self._TestOutput('xml', EXPECTED_XML) + + def testJSON(self): + """Verifies XML output for listing tests in a Google Test binary. + + Runs a test program that generates an empty XML output, and + tests that the XML output is expected. + """ + self._TestOutput('json', EXPECTED_JSON) + + def _GetOutput(self, out_format): + file_path = os.path.join(gtest_test_utils.GetTempDir(), + 'test_out.' + out_format) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath( + 'gtest_list_output_unittest_') + + command = ([ + gtest_prog_path, + '%s=%s:%s' % (GTEST_OUTPUT_FLAG, out_format, file_path), + '--gtest_list_tests' + ]) + environ_copy = os.environ.copy() + p = gtest_test_utils.Subprocess( + command, env=environ_copy, working_dir=gtest_test_utils.GetTempDir()) + + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + with open(file_path) as f: + result = f.read() + return result + + def _TestOutput(self, test_format, expected_output): + actual = self._GetOutput(test_format) + actual_lines = actual.splitlines() + expected_lines = expected_output.splitlines() + line_count = 0 + for actual_line in actual_lines: + expected_line = expected_lines[line_count] + expected_line_re = re.compile(expected_line.strip()) + self.assert_( + expected_line_re.match(actual_line.strip()), + ('actual output of "%s",\n' + 'which does not match expected regex of "%s"\n' + 'on line %d' % (actual, expected_output, line_count))) + line_count = line_count + 1 + + +if __name__ == '__main__': + os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/gtest_list_output_unittest_.cc b/3rdparty/gtest/test/gtest_list_output_unittest_.cc new file mode 100644 index 0000000..b1c7b4d --- /dev/null +++ b/3rdparty/gtest/test/gtest_list_output_unittest_.cc @@ -0,0 +1,51 @@ +// Copyright 2018, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: david.schuldenfrei@gmail.com (David Schuldenfrei) + +// Unit test for Google Test's --gtest_list_tests and --gtest_output flag. +// +// A user can ask Google Test to list all tests that will run, +// and have the output saved in a Json/Xml file. +// The tests will not be run after listing. +// +// This program will be invoked from a Python unit test. +// Don't run it directly. + +#include "gtest/gtest.h" + +TEST(FooTest, Test1) {} + +TEST(FooTest, Test2) {} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/gtest_main_unittest.cc b/3rdparty/gtest/test/gtest_main_unittest.cc new file mode 100644 index 0000000..eddedea --- /dev/null +++ b/3rdparty/gtest/test/gtest_main_unittest.cc @@ -0,0 +1,44 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include "gtest/gtest.h" + +// Tests that we don't have to define main() when we link to +// gtest_main instead of gtest. + +namespace { + +TEST(GTestMainTest, ShouldSucceed) { +} + +} // namespace + +// We are using the main() function defined in gtest_main.cc, so we +// don't define it here. diff --git a/3rdparty/gtest/test/gtest_no_test_unittest.cc b/3rdparty/gtest/test/gtest_no_test_unittest.cc new file mode 100644 index 0000000..d4f88db --- /dev/null +++ b/3rdparty/gtest/test/gtest_no_test_unittest.cc @@ -0,0 +1,54 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Tests that a Google Test program that has no test defined can run +// successfully. + +#include "gtest/gtest.h" + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // An ad-hoc assertion outside of all tests. + // + // This serves three purposes: + // + // 1. It verifies that an ad-hoc assertion can be executed even if + // no test is defined. + // 2. It verifies that a failed ad-hoc assertion causes the test + // program to fail. + // 3. We had a bug where the XML output won't be generated if an + // assertion is executed before RUN_ALL_TESTS() is called, even + // though --gtest_output=xml is specified. This makes sure the + // bug is fixed and doesn't regress. + EXPECT_EQ(1, 2); + + // The above EXPECT_EQ() should cause RUN_ALL_TESTS() to return non-zero. + return RUN_ALL_TESTS() ? 0 : 1; +} diff --git a/3rdparty/gtest/test/gtest_pred_impl_unittest.cc b/3rdparty/gtest/test/gtest_pred_impl_unittest.cc new file mode 100644 index 0000000..1afe5e2 --- /dev/null +++ b/3rdparty/gtest/test/gtest_pred_impl_unittest.cc @@ -0,0 +1,2427 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! + +// Regression test for gtest_pred_impl.h +// +// This file is generated by a script and quite long. If you intend to +// learn how Google Test works by reading its unit tests, read +// gtest_unittest.cc instead. +// +// This is intended as a regression test for the Google Test predicate +// assertions. We compile it as part of the gtest_unittest target +// only to keep the implementation tidy and compact, as it is quite +// involved to set up the stage for testing Google Test using Google +// Test itself. +// +// Currently, gtest_unittest takes ~11 seconds to run in the testing +// daemon. In the future, if it grows too large and needs much more +// time to finish, we should consider separating this file into a +// stand-alone regression test. + +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// A user-defined data type. +struct Bool { + explicit Bool(int val) : value(val != 0) {} + + bool operator>(int n) const { return value > Bool(n).value; } + + Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } + + bool operator==(const Bool& rhs) const { return value == rhs.value; } + + bool value; +}; + +// Enables Bool to be used in assertions. +std::ostream& operator<<(std::ostream& os, const Bool& x) { + return os << (x.value ? "true" : "false"); +} + +// Sample functions/functors for testing unary predicate assertions. + +// A unary predicate function. +template +bool PredFunction1(T1 v1) { + return v1 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction1Int(int v1) { + return v1 > 0; +} +bool PredFunction1Bool(Bool v1) { + return v1 > 0; +} + +// A unary predicate functor. +struct PredFunctor1 { + template + bool operator()(const T1& v1) { + return v1 > 0; + } +}; + +// A unary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction1(const char* e1, + const T1& v1) { + if (PredFunction1(v1)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 + << " is expected to be positive, but evaluates to " + << v1 << "."; +} + +// A unary predicate-formatter functor. +struct PredFormatFunctor1 { + template + testing::AssertionResult operator()(const char* e1, + const T1& v1) const { + return PredFormatFunction1(e1, v1); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT1. + +class Predicate1Test : public testing::Test { + protected: + void SetUp() override { + expected_to_finish_ = true; + finished_ = false; + n1_ = 0; + } + + void TearDown() override { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true if and only if the test function is expected to run to finish. + static bool expected_to_finish_; + + // true if and only if the test function did run to finish. + static bool finished_; + + static int n1_; +}; + +bool Predicate1Test::expected_to_finish_; +bool Predicate1Test::finished_; +int Predicate1Test::n1_; + +typedef Predicate1Test EXPECT_PRED_FORMAT1Test; +typedef Predicate1Test ASSERT_PRED_FORMAT1Test; +typedef Predicate1Test EXPECT_PRED1Test; +typedef Predicate1Test ASSERT_PRED1Test; + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing binary predicate assertions. + +// A binary predicate function. +template +bool PredFunction2(T1 v1, T2 v2) { + return v1 + v2 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction2Int(int v1, int v2) { + return v1 + v2 > 0; +} +bool PredFunction2Bool(Bool v1, Bool v2) { + return v1 + v2 > 0; +} + +// A binary predicate functor. +struct PredFunctor2 { + template + bool operator()(const T1& v1, + const T2& v2) { + return v1 + v2 > 0; + } +}; + +// A binary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction2(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) { + if (PredFunction2(v1, v2)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 + << " is expected to be positive, but evaluates to " + << v1 + v2 << "."; +} + +// A binary predicate-formatter functor. +struct PredFormatFunctor2 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) const { + return PredFormatFunction2(e1, e2, v1, v2); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT2. + +class Predicate2Test : public testing::Test { + protected: + void SetUp() override { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = 0; + } + + void TearDown() override { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true if and only if the test function is expected to run to finish. + static bool expected_to_finish_; + + // true if and only if the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; +}; + +bool Predicate2Test::expected_to_finish_; +bool Predicate2Test::finished_; +int Predicate2Test::n1_; +int Predicate2Test::n2_; + +typedef Predicate2Test EXPECT_PRED_FORMAT2Test; +typedef Predicate2Test ASSERT_PRED_FORMAT2Test; +typedef Predicate2Test EXPECT_PRED2Test; +typedef Predicate2Test ASSERT_PRED2Test; + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing ternary predicate assertions. + +// A ternary predicate function. +template +bool PredFunction3(T1 v1, T2 v2, T3 v3) { + return v1 + v2 + v3 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction3Int(int v1, int v2, int v3) { + return v1 + v2 + v3 > 0; +} +bool PredFunction3Bool(Bool v1, Bool v2, Bool v3) { + return v1 + v2 + v3 > 0; +} + +// A ternary predicate functor. +struct PredFunctor3 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3) { + return v1 + v2 + v3 > 0; + } +}; + +// A ternary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction3(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) { + if (PredFunction3(v1, v2, v3)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 << "."; +} + +// A ternary predicate-formatter functor. +struct PredFormatFunctor3 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) const { + return PredFormatFunction3(e1, e2, e3, v1, v2, v3); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT3. + +class Predicate3Test : public testing::Test { + protected: + void SetUp() override { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = 0; + } + + void TearDown() override { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true if and only if the test function is expected to run to finish. + static bool expected_to_finish_; + + // true if and only if the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; +}; + +bool Predicate3Test::expected_to_finish_; +bool Predicate3Test::finished_; +int Predicate3Test::n1_; +int Predicate3Test::n2_; +int Predicate3Test::n3_; + +typedef Predicate3Test EXPECT_PRED_FORMAT3Test; +typedef Predicate3Test ASSERT_PRED_FORMAT3Test; +typedef Predicate3Test EXPECT_PRED3Test; +typedef Predicate3Test ASSERT_PRED3Test; + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 4-ary predicate assertions. + +// A 4-ary predicate function. +template +bool PredFunction4(T1 v1, T2 v2, T3 v3, T4 v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction4Int(int v1, int v2, int v3, int v4) { + return v1 + v2 + v3 + v4 > 0; +} +bool PredFunction4Bool(Bool v1, Bool v2, Bool v3, Bool v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// A 4-ary predicate functor. +struct PredFunctor4 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + return v1 + v2 + v3 + v4 > 0; + } +}; + +// A 4-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction4(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (PredFunction4(v1, v2, v3, v4)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 << "."; +} + +// A 4-ary predicate-formatter functor. +struct PredFormatFunctor4 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) const { + return PredFormatFunction4(e1, e2, e3, e4, v1, v2, v3, v4); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT4. + +class Predicate4Test : public testing::Test { + protected: + void SetUp() override { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = 0; + } + + void TearDown() override { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true if and only if the test function is expected to run to finish. + static bool expected_to_finish_; + + // true if and only if the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; +}; + +bool Predicate4Test::expected_to_finish_; +bool Predicate4Test::finished_; +int Predicate4Test::n1_; +int Predicate4Test::n2_; +int Predicate4Test::n3_; +int Predicate4Test::n4_; + +typedef Predicate4Test EXPECT_PRED_FORMAT4Test; +typedef Predicate4Test ASSERT_PRED_FORMAT4Test; +typedef Predicate4Test EXPECT_PRED4Test; +typedef Predicate4Test ASSERT_PRED4Test; + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 5-ary predicate assertions. + +// A 5-ary predicate function. +template +bool PredFunction5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction5Int(int v1, int v2, int v3, int v4, int v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} +bool PredFunction5Bool(Bool v1, Bool v2, Bool v3, Bool v4, Bool v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// A 5-ary predicate functor. +struct PredFunctor5 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + return v1 + v2 + v3 + v4 + v5 > 0; + } +}; + +// A 5-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction5(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (PredFunction5(v1, v2, v3, v4, v5)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 + v5 << "."; +} + +// A 5-ary predicate-formatter functor. +struct PredFormatFunctor5 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) const { + return PredFormatFunction5(e1, e2, e3, e4, e5, v1, v2, v3, v4, v5); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT5. + +class Predicate5Test : public testing::Test { + protected: + void SetUp() override { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = n5_ = 0; + } + + void TearDown() override { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + EXPECT_EQ(1, n5_) << + "The predicate assertion didn't evaluate argument 6 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true if and only if the test function is expected to run to finish. + static bool expected_to_finish_; + + // true if and only if the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; + static int n5_; +}; + +bool Predicate5Test::expected_to_finish_; +bool Predicate5Test::finished_; +int Predicate5Test::n1_; +int Predicate5Test::n2_; +int Predicate5Test::n3_; +int Predicate5Test::n4_; +int Predicate5Test::n5_; + +typedef Predicate5Test EXPECT_PRED_FORMAT5Test; +typedef Predicate5Test ASSERT_PRED_FORMAT5Test; +typedef Predicate5Test EXPECT_PRED5Test; +typedef Predicate5Test ASSERT_PRED5Test; + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} diff --git a/3rdparty/gtest/test/gtest_premature_exit_test.cc b/3rdparty/gtest/test/gtest_premature_exit_test.cc new file mode 100644 index 0000000..1d1187e --- /dev/null +++ b/3rdparty/gtest/test/gtest_premature_exit_test.cc @@ -0,0 +1,126 @@ +// Copyright 2013, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests that Google Test manipulates the premature-exit-detection +// file correctly. + +#include + +#include "gtest/gtest.h" + +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::internal::posix::GetEnv; +using ::testing::internal::posix::Stat; +using ::testing::internal::posix::StatStruct; + +namespace { + +class PrematureExitTest : public Test { + public: + // Returns true if and only if the given file exists. + static bool FileExists(const char* filepath) { + StatStruct stat; + return Stat(filepath, &stat) == 0; + } + + protected: + PrematureExitTest() { + premature_exit_file_path_ = GetEnv("TEST_PREMATURE_EXIT_FILE"); + + // Normalize NULL to "" for ease of handling. + if (premature_exit_file_path_ == nullptr) { + premature_exit_file_path_ = ""; + } + } + + // Returns true if and only if the premature-exit file exists. + bool PrematureExitFileExists() const { + return FileExists(premature_exit_file_path_); + } + + const char* premature_exit_file_path_; +}; + +typedef PrematureExitTest PrematureExitDeathTest; + +// Tests that: +// - the premature-exit file exists during the execution of a +// death test (EXPECT_DEATH*), and +// - a death test doesn't interfere with the main test process's +// handling of the premature-exit file. +TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) { + if (*premature_exit_file_path_ == '\0') { + return; + } + + EXPECT_DEATH_IF_SUPPORTED({ + // If the file exists, crash the process such that the main test + // process will catch the (expected) crash and report a success; + // otherwise don't crash, which will cause the main test process + // to report that the death test has failed. + if (PrematureExitFileExists()) { + exit(1); + } + }, ""); +} + +// Tests that the premature-exit file exists during the execution of a +// normal (non-death) test. +TEST_F(PrematureExitTest, PrematureExitFileExistsDuringTestExecution) { + if (*premature_exit_file_path_ == '\0') { + return; + } + + EXPECT_TRUE(PrematureExitFileExists()) + << " file " << premature_exit_file_path_ + << " should exist during test execution, but doesn't."; +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + const int exit_code = RUN_ALL_TESTS(); + + // Test that the premature-exit file is deleted upon return from + // RUN_ALL_TESTS(). + const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); + if (filepath != nullptr && *filepath != '\0') { + if (PrematureExitTest::FileExists(filepath)) { + printf( + "File %s shouldn't exist after the test program finishes, but does.", + filepath); + return 1; + } + } + + return exit_code; +} diff --git a/3rdparty/gtest/test/gtest_prod_test.cc b/3rdparty/gtest/test/gtest_prod_test.cc new file mode 100644 index 0000000..ede81a0 --- /dev/null +++ b/3rdparty/gtest/test/gtest_prod_test.cc @@ -0,0 +1,56 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Unit test for gtest_prod.h. + +#include "production.h" +#include "gtest/gtest.h" + +// Tests that private members can be accessed from a TEST declared as +// a friend of the class. +TEST(PrivateCodeTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(1); + EXPECT_EQ(1, a.x_); +} + +typedef testing::Test PrivateCodeFixtureTest; + +// Tests that private members can be accessed from a TEST_F declared +// as a friend of the class. +TEST_F(PrivateCodeFixtureTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(2); + EXPECT_EQ(2, a.x_); +} diff --git a/3rdparty/gtest/test/gtest_repeat_test.cc b/3rdparty/gtest/test/gtest_repeat_test.cc new file mode 100644 index 0000000..7da4a15 --- /dev/null +++ b/3rdparty/gtest/test/gtest_repeat_test.cc @@ -0,0 +1,233 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Tests the --gtest_repeat=number flag. + +#include +#include +#include "gtest/gtest.h" +#include "src/gtest-internal-inl.h" + +namespace testing { + +GTEST_DECLARE_string_(death_test_style); +GTEST_DECLARE_string_(filter); +GTEST_DECLARE_int32_(repeat); + +} // namespace testing + +using testing::GTEST_FLAG(death_test_style); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(repeat); + +namespace { + +// We need this when we are testing Google Test itself and therefore +// cannot use Google Test assertions. +#define GTEST_CHECK_INT_EQ_(expected, actual) \ + do {\ + const int expected_val = (expected);\ + const int actual_val = (actual);\ + if (::testing::internal::IsTrue(expected_val != actual_val)) {\ + ::std::cout << "Value of: " #actual "\n"\ + << " Actual: " << actual_val << "\n"\ + << "Expected: " #expected "\n"\ + << "Which is: " << expected_val << "\n";\ + ::testing::internal::posix::Abort();\ + }\ + } while (::testing::internal::AlwaysFalse()) + + +// Used for verifying that global environment set-up and tear-down are +// inside the --gtest_repeat loop. + +int g_environment_set_up_count = 0; +int g_environment_tear_down_count = 0; + +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() {} + void SetUp() override { g_environment_set_up_count++; } + void TearDown() override { g_environment_tear_down_count++; } +}; + +// A test that should fail. + +int g_should_fail_count = 0; + +TEST(FooTest, ShouldFail) { + g_should_fail_count++; + EXPECT_EQ(0, 1) << "Expected failure."; +} + +// A test that should pass. + +int g_should_pass_count = 0; + +TEST(FooTest, ShouldPass) { + g_should_pass_count++; +} + +// A test that contains a thread-safe death test and a fast death +// test. It should pass. + +int g_death_test_count = 0; + +TEST(BarDeathTest, ThreadSafeAndFast) { + g_death_test_count++; + + GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); + + GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); +} + +int g_param_test_count = 0; + +const int kNumberOfParamTests = 10; + +class MyParamTest : public testing::TestWithParam {}; + +TEST_P(MyParamTest, ShouldPass) { + GTEST_CHECK_INT_EQ_(g_param_test_count % kNumberOfParamTests, GetParam()); + g_param_test_count++; +} +INSTANTIATE_TEST_SUITE_P(MyParamSequence, + MyParamTest, + testing::Range(0, kNumberOfParamTests)); + +// Resets the count for each test. +void ResetCounts() { + g_environment_set_up_count = 0; + g_environment_tear_down_count = 0; + g_should_fail_count = 0; + g_should_pass_count = 0; + g_death_test_count = 0; + g_param_test_count = 0; +} + +// Checks that the count for each test is expected. +void CheckCounts(int expected) { + GTEST_CHECK_INT_EQ_(expected, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(expected, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); + GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); + GTEST_CHECK_INT_EQ_(expected, g_death_test_count); + GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count); +} + +// Tests the behavior of Google Test when --gtest_repeat is not specified. +void TestRepeatUnspecified() { + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + CheckCounts(1); +} + +// Tests the behavior of Google Test when --gtest_repeat has the given value. +void TestRepeat(int repeat) { + GTEST_FLAG(repeat) = repeat; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(repeat > 0 ? 1 : 0, RUN_ALL_TESTS()); + CheckCounts(repeat); +} + +// Tests using --gtest_repeat when --gtest_filter specifies an empty +// set of tests. +void TestRepeatWithEmptyFilter(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "None"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + CheckCounts(0); +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// successful tests. +void TestRepeatWithFilterForSuccessfulTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*-*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(0, g_should_fail_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); + GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); + GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count); +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// failed tests. +void TestRepeatWithFilterForFailedTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); + GTEST_CHECK_INT_EQ_(0, g_should_pass_count); + GTEST_CHECK_INT_EQ_(0, g_death_test_count); + GTEST_CHECK_INT_EQ_(0, g_param_test_count); +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + testing::AddGlobalTestEnvironment(new MyEnvironment); + + TestRepeatUnspecified(); + TestRepeat(0); + TestRepeat(1); + TestRepeat(5); + + TestRepeatWithEmptyFilter(2); + TestRepeatWithEmptyFilter(3); + + TestRepeatWithFilterForSuccessfulTests(3); + + TestRepeatWithFilterForFailedTests(4); + + // It would be nice to verify that the tests indeed loop forever + // when GTEST_FLAG(repeat) is negative, but this test will be quite + // complicated to write. Since this flag is for interactive + // debugging only and doesn't affect the normal test result, such a + // test would be an overkill. + + printf("PASS\n"); + return 0; +} diff --git a/3rdparty/gtest/test/gtest_skip_environment_check_output_test.py b/3rdparty/gtest/test/gtest_skip_environment_check_output_test.py new file mode 100644 index 0000000..6e79155 --- /dev/null +++ b/3rdparty/gtest/test/gtest_skip_environment_check_output_test.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# +# Copyright 2019 Google LLC. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +"""Tests Google Test's gtest skip in environment setup behavior. + +This script invokes gtest_skip_in_environment_setup_test_ and verifies its +output. +""" + +import gtest_test_utils + +# Path to the gtest_skip_in_environment_setup_test binary +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_skip_in_environment_setup_test') + +OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output + + +# Test. +class SkipEntireEnvironmentTest(gtest_test_utils.TestCase): + + def testSkipEntireEnvironmentTest(self): + self.assertIn('Skipping the entire environment', OUTPUT) + self.assertNotIn('FAILED', OUTPUT) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/gtest_skip_in_environment_setup_test.cc b/3rdparty/gtest/test/gtest_skip_in_environment_setup_test.cc new file mode 100644 index 0000000..9372310 --- /dev/null +++ b/3rdparty/gtest/test/gtest_skip_in_environment_setup_test.cc @@ -0,0 +1,49 @@ +// Copyright 2019, Google LLC. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google LLC. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// This test verifies that skipping in the environment results in the +// testcases being skipped. + +#include +#include "gtest/gtest.h" + +class SetupEnvironment : public testing::Environment { + public: + void SetUp() override { GTEST_SKIP() << "Skipping the entire environment"; } +}; + +TEST(Test, AlwaysFails) { EXPECT_EQ(true, false); } + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + testing::AddGlobalTestEnvironment(new SetupEnvironment()); + + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/gtest_skip_test.cc b/3rdparty/gtest/test/gtest_skip_test.cc new file mode 100644 index 0000000..717e105 --- /dev/null +++ b/3rdparty/gtest/test/gtest_skip_test.cc @@ -0,0 +1,55 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: arseny.aprelev@gmail.com (Arseny Aprelev) +// + +#include "gtest/gtest.h" + +using ::testing::Test; + +TEST(SkipTest, DoesSkip) { + GTEST_SKIP(); + EXPECT_EQ(0, 1); +} + +class Fixture : public Test { + protected: + void SetUp() override { + GTEST_SKIP() << "skipping all tests for this fixture"; + } +}; + +TEST_F(Fixture, SkipsOneTest) { + EXPECT_EQ(5, 7); +} + +TEST_F(Fixture, SkipsAnotherTest) { + EXPECT_EQ(99, 100); +} diff --git a/3rdparty/gtest/test/gtest_sole_header_test.cc b/3rdparty/gtest/test/gtest_sole_header_test.cc new file mode 100644 index 0000000..1d94ac6 --- /dev/null +++ b/3rdparty/gtest/test/gtest_sole_header_test.cc @@ -0,0 +1,56 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// This test verifies that it's possible to use Google Test by including +// the gtest.h header file alone. + +#include "gtest/gtest.h" + +namespace { + +void Subroutine() { + EXPECT_EQ(42, 42); +} + +TEST(NoFatalFailureTest, ExpectNoFatalFailure) { + EXPECT_NO_FATAL_FAILURE(;); + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + EXPECT_NO_FATAL_FAILURE(Subroutine()); + EXPECT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +TEST(NoFatalFailureTest, AssertNoFatalFailure) { + ASSERT_NO_FATAL_FAILURE(;); + ASSERT_NO_FATAL_FAILURE(SUCCEED()); + ASSERT_NO_FATAL_FAILURE(Subroutine()); + ASSERT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +} // namespace diff --git a/3rdparty/gtest/test/gtest_stress_test.cc b/3rdparty/gtest/test/gtest_stress_test.cc new file mode 100644 index 0000000..8434819 --- /dev/null +++ b/3rdparty/gtest/test/gtest_stress_test.cc @@ -0,0 +1,248 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Tests that SCOPED_TRACE() and various Google Test assertions can be +// used in a large number of threads concurrently. + +#include "gtest/gtest.h" + +#include + +#include "src/gtest-internal-inl.h" + +#if GTEST_IS_THREADSAFE + +namespace testing { +namespace { + +using internal::Notification; +using internal::TestPropertyKeyIs; +using internal::ThreadWithParam; + +// In order to run tests in this file, for platforms where Google Test is +// thread safe, implement ThreadWithParam. See the description of its API +// in gtest-port.h, where it is defined for already supported platforms. + +// How many threads to create? +const int kThreadCount = 50; + +std::string IdToKey(int id, const char* suffix) { + Message key; + key << "key_" << id << "_" << suffix; + return key.GetString(); +} + +std::string IdToString(int id) { + Message id_message; + id_message << id; + return id_message.GetString(); +} + +void ExpectKeyAndValueWereRecordedForId( + const std::vector& properties, + int id, const char* suffix) { + TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); + const std::vector::const_iterator property = + std::find_if(properties.begin(), properties.end(), matches_key); + ASSERT_TRUE(property != properties.end()) + << "expecting " << suffix << " value for id " << id; + EXPECT_STREQ(IdToString(id).c_str(), property->value()); +} + +// Calls a large number of Google Test assertions, where exactly one of them +// will fail. +void ManyAsserts(int id) { + GTEST_LOG_(INFO) << "Thread #" << id << " running..."; + + SCOPED_TRACE(Message() << "Thread #" << id); + + for (int i = 0; i < kThreadCount; i++) { + SCOPED_TRACE(Message() << "Iteration #" << i); + + // A bunch of assertions that should succeed. + EXPECT_TRUE(true); + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_STREQ("a", "a"); + ASSERT_LE(5, 6); + EXPECT_EQ(i, i) << "This shouldn't fail."; + + // RecordProperty() should interact safely with other threads as well. + // The shared_key forces property updates. + Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str()); + Test::RecordProperty(IdToKey(id, "int").c_str(), id); + Test::RecordProperty("shared_key", IdToString(id).c_str()); + + // This assertion should fail kThreadCount times per thread. It + // is for testing whether Google Test can handle failed assertions in a + // multi-threaded context. + EXPECT_LT(i, 0) << "This should always fail."; + } +} + +void CheckTestFailureCount(int expected_failures) { + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + GTEST_CHECK_(expected_failures == result->total_part_count()) + << "Logged " << result->total_part_count() << " failures " + << " vs. " << expected_failures << " expected"; +} + +// Tests using SCOPED_TRACE() and Google Test assertions in many threads +// concurrently. +TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { + { + std::unique_ptr > threads[kThreadCount]; + Notification threads_can_start; + for (int i = 0; i != kThreadCount; i++) + threads[i].reset(new ThreadWithParam(&ManyAsserts, + i, + &threads_can_start)); + + threads_can_start.Notify(); + + // Blocks until all the threads are done. + for (int i = 0; i != kThreadCount; i++) + threads[i]->Join(); + } + + // Ensures that kThreadCount*kThreadCount failures have been reported. + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + + std::vector properties; + // We have no access to the TestResult's list of properties but we can + // copy them one by one. + for (int i = 0; i < result->test_property_count(); ++i) + properties.push_back(result->GetTestProperty(i)); + + EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count()) + << "String and int values recorded on each thread, " + << "as well as one shared_key"; + for (int i = 0; i < kThreadCount; ++i) { + ExpectKeyAndValueWereRecordedForId(properties, i, "string"); + ExpectKeyAndValueWereRecordedForId(properties, i, "int"); + } + CheckTestFailureCount(kThreadCount*kThreadCount); +} + +void FailingThread(bool is_fatal) { + if (is_fatal) + FAIL() << "Fatal failure in some other thread. " + << "(This failure is expected.)"; + else + ADD_FAILURE() << "Non-fatal failure in some other thread. " + << "(This failure is expected.)"; +} + +void GenerateFatalFailureInAnotherThread(bool is_fatal) { + ThreadWithParam thread(&FailingThread, is_fatal, nullptr); + thread.Join(); +} + +TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) { + EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); +} + +void AssertNoFatalFailureIgnoresFailuresInOtherThreads() { + ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); +} +TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) { + // Using a subroutine, to make sure, that the test continues. + AssertNoFatalFailureIgnoresFailuresInOtherThreads(); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); +} + +TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) { + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(2); +} + +TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) { + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_FATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures. + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; +} + +TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) { + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false), + "expected"); + CheckTestFailureCount(2); +} + +TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(false), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures, + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; +} + +} // namespace +} // namespace testing + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + const int result = RUN_ALL_TESTS(); // Expected to fail. + GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected"; + + printf("\nPASS\n"); + return 0; +} + +#else +TEST(StressTest, + DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) { +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif // GTEST_IS_THREADSAFE diff --git a/3rdparty/gtest/test/gtest_test_macro_stack_footprint_test.cc b/3rdparty/gtest/test/gtest_test_macro_stack_footprint_test.cc new file mode 100644 index 0000000..a48db05 --- /dev/null +++ b/3rdparty/gtest/test/gtest_test_macro_stack_footprint_test.cc @@ -0,0 +1,89 @@ +// Copyright 2013, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Each TEST() expands to some static registration logic. GCC puts all +// such static initialization logic for a translation unit in a common, +// internal function. Since Google's build system restricts how much +// stack space a function can use, there's a limit on how many TEST()s +// one can put in a single C++ test file. This test ensures that a large +// number of TEST()s can be defined in the same translation unit. + +#include "gtest/gtest.h" + +// This macro defines 10 dummy tests. +#define TEN_TESTS_(test_case_name) \ + TEST(test_case_name, T0) {} \ + TEST(test_case_name, T1) {} \ + TEST(test_case_name, T2) {} \ + TEST(test_case_name, T3) {} \ + TEST(test_case_name, T4) {} \ + TEST(test_case_name, T5) {} \ + TEST(test_case_name, T6) {} \ + TEST(test_case_name, T7) {} \ + TEST(test_case_name, T8) {} \ + TEST(test_case_name, T9) {} + +// This macro defines 100 dummy tests. +#define HUNDRED_TESTS_(test_case_name_prefix) \ + TEN_TESTS_(test_case_name_prefix ## 0) \ + TEN_TESTS_(test_case_name_prefix ## 1) \ + TEN_TESTS_(test_case_name_prefix ## 2) \ + TEN_TESTS_(test_case_name_prefix ## 3) \ + TEN_TESTS_(test_case_name_prefix ## 4) \ + TEN_TESTS_(test_case_name_prefix ## 5) \ + TEN_TESTS_(test_case_name_prefix ## 6) \ + TEN_TESTS_(test_case_name_prefix ## 7) \ + TEN_TESTS_(test_case_name_prefix ## 8) \ + TEN_TESTS_(test_case_name_prefix ## 9) + +// This macro defines 1000 dummy tests. +#define THOUSAND_TESTS_(test_case_name_prefix) \ + HUNDRED_TESTS_(test_case_name_prefix ## 0) \ + HUNDRED_TESTS_(test_case_name_prefix ## 1) \ + HUNDRED_TESTS_(test_case_name_prefix ## 2) \ + HUNDRED_TESTS_(test_case_name_prefix ## 3) \ + HUNDRED_TESTS_(test_case_name_prefix ## 4) \ + HUNDRED_TESTS_(test_case_name_prefix ## 5) \ + HUNDRED_TESTS_(test_case_name_prefix ## 6) \ + HUNDRED_TESTS_(test_case_name_prefix ## 7) \ + HUNDRED_TESTS_(test_case_name_prefix ## 8) \ + HUNDRED_TESTS_(test_case_name_prefix ## 9) + +// Ensures that we can define 1000 TEST()s in the same translation +// unit. +THOUSAND_TESTS_(T) + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // We don't actually need to run the dummy tests - the purpose is to + // ensure that they compile. + return 0; +} diff --git a/3rdparty/gtest/test/gtest_test_utils.py b/3rdparty/gtest/test/gtest_test_utils.py new file mode 100644 index 0000000..ef9363c --- /dev/null +++ b/3rdparty/gtest/test/gtest_test_utils.py @@ -0,0 +1,314 @@ +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test utilities for Google C++ Testing and Mocking Framework.""" +# Suppresses the 'Import not at the top of the file' lint complaint. +# pylint: disable-msg=C6204 + +import os +import sys + +IS_WINDOWS = os.name == 'nt' +IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] +IS_OS2 = os.name == 'os2' + +import atexit +import shutil +import tempfile +import unittest as _test_module + +try: + import subprocess + _SUBPROCESS_MODULE_AVAILABLE = True +except: + import popen2 + _SUBPROCESS_MODULE_AVAILABLE = False +# pylint: enable-msg=C6204 + +GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT' + +# The environment variable for specifying the path to the premature-exit file. +PREMATURE_EXIT_FILE_ENV_VAR = 'TEST_PREMATURE_EXIT_FILE' + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets/unsets an environment variable to a given value.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +# Here we expose a class from a particular module, depending on the +# environment. The comment suppresses the 'Invalid variable name' lint +# complaint. +TestCase = _test_module.TestCase # pylint: disable=C6409 + +# Initially maps a flag to its default value. After +# _ParseAndStripGTestFlags() is called, maps a flag to its actual value. +_flag_map = {'source_dir': os.path.dirname(sys.argv[0]), + 'build_dir': os.path.dirname(sys.argv[0])} +_gtest_flags_are_parsed = False + + +def _ParseAndStripGTestFlags(argv): + """Parses and strips Google Test flags from argv. This is idempotent.""" + + # Suppresses the lint complaint about a global variable since we need it + # here to maintain module-wide state. + global _gtest_flags_are_parsed # pylint: disable=W0603 + if _gtest_flags_are_parsed: + return + + _gtest_flags_are_parsed = True + for flag in _flag_map: + # The environment variable overrides the default value. + if flag.upper() in os.environ: + _flag_map[flag] = os.environ[flag.upper()] + + # The command line flag overrides the environment variable. + i = 1 # Skips the program name. + while i < len(argv): + prefix = '--' + flag + '=' + if argv[i].startswith(prefix): + _flag_map[flag] = argv[i][len(prefix):] + del argv[i] + break + else: + # We don't increment i in case we just found a --gtest_* flag + # and removed it from argv. + i += 1 + + +def GetFlag(flag): + """Returns the value of the given flag.""" + + # In case GetFlag() is called before Main(), we always call + # _ParseAndStripGTestFlags() here to make sure the --gtest_* flags + # are parsed. + _ParseAndStripGTestFlags(sys.argv) + + return _flag_map[flag] + + +def GetSourceDir(): + """Returns the absolute path of the directory where the .py files are.""" + + return os.path.abspath(GetFlag('source_dir')) + + +def GetBuildDir(): + """Returns the absolute path of the directory where the test binaries are.""" + + return os.path.abspath(GetFlag('build_dir')) + + +_temp_dir = None + +def _RemoveTempDir(): + if _temp_dir: + shutil.rmtree(_temp_dir, ignore_errors=True) + +atexit.register(_RemoveTempDir) + + +def GetTempDir(): + global _temp_dir + if not _temp_dir: + _temp_dir = tempfile.mkdtemp() + return _temp_dir + + +def GetTestExecutablePath(executable_name, build_dir=None): + """Returns the absolute path of the test binary given its name. + + The function will print a message and abort the program if the resulting file + doesn't exist. + + Args: + executable_name: name of the test binary that the test script runs. + build_dir: directory where to look for executables, by default + the result of GetBuildDir(). + + Returns: + The absolute path of the test binary. + """ + + path = os.path.abspath(os.path.join(build_dir or GetBuildDir(), + executable_name)) + if (IS_WINDOWS or IS_CYGWIN or IS_OS2) and not path.endswith('.exe'): + path += '.exe' + + if not os.path.exists(path): + message = ( + 'Unable to find the test binary "%s". Please make sure to provide\n' + 'a path to the binary via the --build_dir flag or the BUILD_DIR\n' + 'environment variable.' % path) + print >> sys.stderr, message + sys.exit(1) + + return path + + +def GetExitStatus(exit_code): + """Returns the argument to exit(), or -1 if exit() wasn't called. + + Args: + exit_code: the result value of os.system(command). + """ + + if os.name == 'nt': + # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns + # the argument to exit() directly. + return exit_code + else: + # On Unix, os.WEXITSTATUS() must be used to extract the exit status + # from the result of os.system(). + if os.WIFEXITED(exit_code): + return os.WEXITSTATUS(exit_code) + else: + return -1 + + +class Subprocess: + def __init__(self, command, working_dir=None, capture_stderr=True, env=None): + """Changes into a specified directory, if provided, and executes a command. + + Restores the old directory afterwards. + + Args: + command: The command to run, in the form of sys.argv. + working_dir: The directory to change into. + capture_stderr: Determines whether to capture stderr in the output member + or to discard it. + env: Dictionary with environment to pass to the subprocess. + + Returns: + An object that represents outcome of the executed process. It has the + following attributes: + terminated_by_signal True if and only if the child process has been + terminated by a signal. + signal Sygnal that terminated the child process. + exited True if and only if the child process exited + normally. + exit_code The code with which the child process exited. + output Child process's stdout and stderr output + combined in a string. + """ + + # The subprocess module is the preferrable way of running programs + # since it is available and behaves consistently on all platforms, + # including Windows. But it is only available starting in python 2.4. + # In earlier python versions, we revert to the popen2 module, which is + # available in python 2.0 and later but doesn't provide required + # functionality (Popen4) under Windows. This allows us to support Mac + # OS X 10.4 Tiger, which has python 2.3 installed. + if _SUBPROCESS_MODULE_AVAILABLE: + if capture_stderr: + stderr = subprocess.STDOUT + else: + stderr = subprocess.PIPE + + p = subprocess.Popen(command, + stdout=subprocess.PIPE, stderr=stderr, + cwd=working_dir, universal_newlines=True, env=env) + # communicate returns a tuple with the file object for the child's + # output. + self.output = p.communicate()[0] + self._return_code = p.returncode + else: + old_dir = os.getcwd() + + def _ReplaceEnvDict(dest, src): + # Changes made by os.environ.clear are not inheritable by child + # processes until Python 2.6. To produce inheritable changes we have + # to delete environment items with the del statement. + for key in dest.keys(): + del dest[key] + dest.update(src) + + # When 'env' is not None, backup the environment variables and replace + # them with the passed 'env'. When 'env' is None, we simply use the + # current 'os.environ' for compatibility with the subprocess.Popen + # semantics used above. + if env is not None: + old_environ = os.environ.copy() + _ReplaceEnvDict(os.environ, env) + + try: + if working_dir is not None: + os.chdir(working_dir) + if capture_stderr: + p = popen2.Popen4(command) + else: + p = popen2.Popen3(command) + p.tochild.close() + self.output = p.fromchild.read() + ret_code = p.wait() + finally: + os.chdir(old_dir) + + # Restore the old environment variables + # if they were replaced. + if env is not None: + _ReplaceEnvDict(os.environ, old_environ) + + # Converts ret_code to match the semantics of + # subprocess.Popen.returncode. + if os.WIFSIGNALED(ret_code): + self._return_code = -os.WTERMSIG(ret_code) + else: # os.WIFEXITED(ret_code) should return True here. + self._return_code = os.WEXITSTATUS(ret_code) + + if self._return_code < 0: + self.terminated_by_signal = True + self.exited = False + self.signal = -self._return_code + else: + self.terminated_by_signal = False + self.exited = True + self.exit_code = self._return_code + + +def Main(): + """Runs the unit test.""" + + # We must call _ParseAndStripGTestFlags() before calling + # unittest.main(). Otherwise the latter will be confused by the + # --gtest_* flags. + _ParseAndStripGTestFlags(sys.argv) + # The tested binaries should not be writing XML output files unless the + # script explicitly instructs them to. + if GTEST_OUTPUT_VAR_NAME in os.environ: + del os.environ[GTEST_OUTPUT_VAR_NAME] + + _test_module.main() diff --git a/3rdparty/gtest/test/gtest_testbridge_test.py b/3rdparty/gtest/test/gtest_testbridge_test.py new file mode 100644 index 0000000..87ffad7 --- /dev/null +++ b/3rdparty/gtest/test/gtest_testbridge_test.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# +# Copyright 2018 Google LLC. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +"""Verifies that Google Test uses filter provided via testbridge.""" + +import os + +import gtest_test_utils + +binary_name = 'gtest_testbridge_test_' +COMMAND = gtest_test_utils.GetTestExecutablePath(binary_name) +TESTBRIDGE_NAME = 'TESTBRIDGE_TEST_ONLY' + + +def Assert(condition): + if not condition: + raise AssertionError + + +class GTestTestFilterTest(gtest_test_utils.TestCase): + + def testTestExecutionIsFiltered(self): + """Tests that the test filter is picked up from the testbridge env var.""" + subprocess_env = os.environ.copy() + + subprocess_env[TESTBRIDGE_NAME] = '*.TestThatSucceeds' + p = gtest_test_utils.Subprocess(COMMAND, env=subprocess_env) + + self.assertEquals(0, p.exit_code) + + Assert('filter = *.TestThatSucceeds' in p.output) + Assert('[ OK ] TestFilterTest.TestThatSucceeds' in p.output) + Assert('[ PASSED ] 1 test.' in p.output) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/gtest_testbridge_test_.cc b/3rdparty/gtest/test/gtest_testbridge_test_.cc new file mode 100644 index 0000000..24617b2 --- /dev/null +++ b/3rdparty/gtest/test/gtest_testbridge_test_.cc @@ -0,0 +1,43 @@ +// Copyright 2018, Google LLC. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// This program is meant to be run by gtest_test_filter_test.py. Do not run +// it directly. + +#include "gtest/gtest.h" + +// These tests are used to detect if filtering is working. Only +// 'TestThatSucceeds' should ever run. + +TEST(TestFilterTest, TestThatSucceeds) {} + +TEST(TestFilterTest, TestThatFails) { + ASSERT_TRUE(false) << "This test should never be run."; +} diff --git a/3rdparty/gtest/test/gtest_throw_on_failure_ex_test.cc b/3rdparty/gtest/test/gtest_throw_on_failure_ex_test.cc new file mode 100644 index 0000000..1d95adb --- /dev/null +++ b/3rdparty/gtest/test/gtest_throw_on_failure_ex_test.cc @@ -0,0 +1,90 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Tests Google Test's throw-on-failure mode with exceptions enabled. + +#include "gtest/gtest.h" + +#include +#include +#include +#include + +// Prints the given failure message and exits the program with +// non-zero. We use this instead of a Google Test assertion to +// indicate a failure, as the latter is been tested and cannot be +// relied on. +void Fail(const char* msg) { + printf("FAILURE: %s\n", msg); + fflush(stdout); + exit(1); +} + +// Tests that an assertion failure throws a subclass of +// std::runtime_error. +void TestFailureThrowsRuntimeError() { + testing::GTEST_FLAG(throw_on_failure) = true; + + // A successful assertion shouldn't throw. + try { + EXPECT_EQ(3, 3); + } catch(...) { + Fail("A successful assertion wrongfully threw."); + } + + // A failed assertion should throw a subclass of std::runtime_error. + try { + EXPECT_EQ(2, 3) << "Expected failure"; + } catch(const std::runtime_error& e) { + if (strstr(e.what(), "Expected failure") != nullptr) return; + + printf("%s", + "A failed assertion did throw an exception of the right type, " + "but the message is incorrect. Instead of containing \"Expected " + "failure\", it is:\n"); + Fail(e.what()); + } catch(...) { + Fail("A failed assertion threw the wrong type of exception."); + } + Fail("A failed assertion should've thrown but didn't."); +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the thrown-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + TestFailureThrowsRuntimeError(); + return 0; +} diff --git a/3rdparty/gtest/test/gtest_unittest.cc b/3rdparty/gtest/test/gtest_unittest.cc new file mode 100644 index 0000000..39749b7 --- /dev/null +++ b/3rdparty/gtest/test/gtest_unittest.cc @@ -0,0 +1,7488 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include "gtest/gtest.h" + +// Verifies that the command line flag variables can be accessed in +// code once "gtest.h" has been #included. +// Do not move it after other gtest #includes. +TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { + bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) + || testing::GTEST_FLAG(break_on_failure) + || testing::GTEST_FLAG(catch_exceptions) + || testing::GTEST_FLAG(color) != "unknown" + || testing::GTEST_FLAG(filter) != "unknown" + || testing::GTEST_FLAG(list_tests) + || testing::GTEST_FLAG(output) != "unknown" + || testing::GTEST_FLAG(print_time) + || testing::GTEST_FLAG(random_seed) + || testing::GTEST_FLAG(repeat) > 0 + || testing::GTEST_FLAG(show_internal_stack_frames) + || testing::GTEST_FLAG(shuffle) + || testing::GTEST_FLAG(stack_trace_depth) > 0 + || testing::GTEST_FLAG(stream_result_to) != "unknown" + || testing::GTEST_FLAG(throw_on_failure); + EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. +} + +#include // For INT_MAX. +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "gtest/gtest-spi.h" +#include "src/gtest-internal-inl.h" + +namespace testing { +namespace internal { + +#if GTEST_CAN_STREAM_RESULTS_ + +class StreamingListenerTest : public Test { + public: + class FakeSocketWriter : public StreamingListener::AbstractSocketWriter { + public: + // Sends a string to the socket. + void Send(const std::string& message) override { output_ += message; } + + std::string output_; + }; + + StreamingListenerTest() + : fake_sock_writer_(new FakeSocketWriter), + streamer_(fake_sock_writer_), + test_info_obj_("FooTest", "Bar", nullptr, nullptr, + CodeLocation(__FILE__, __LINE__), nullptr, nullptr) {} + + protected: + std::string* output() { return &(fake_sock_writer_->output_); } + + FakeSocketWriter* const fake_sock_writer_; + StreamingListener streamer_; + UnitTest unit_test_; + TestInfo test_info_obj_; // The name test_info_ was taken by testing::Test. +}; + +TEST_F(StreamingListenerTest, OnTestProgramEnd) { + *output() = ""; + streamer_.OnTestProgramEnd(unit_test_); + EXPECT_EQ("event=TestProgramEnd&passed=1\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestIterationEnd) { + *output() = ""; + streamer_.OnTestIterationEnd(unit_test_, 42); + EXPECT_EQ("event=TestIterationEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestCaseStart) { + *output() = ""; + streamer_.OnTestCaseStart(TestCase("FooTest", "Bar", nullptr, nullptr)); + EXPECT_EQ("event=TestCaseStart&name=FooTest\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestCaseEnd) { + *output() = ""; + streamer_.OnTestCaseEnd(TestCase("FooTest", "Bar", nullptr, nullptr)); + EXPECT_EQ("event=TestCaseEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestStart) { + *output() = ""; + streamer_.OnTestStart(test_info_obj_); + EXPECT_EQ("event=TestStart&name=Bar\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestEnd) { + *output() = ""; + streamer_.OnTestEnd(test_info_obj_); + EXPECT_EQ("event=TestEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestPartResult) { + *output() = ""; + streamer_.OnTestPartResult(TestPartResult( + TestPartResult::kFatalFailure, "foo.cc", 42, "failed=\n&%")); + + // Meta characters in the failure message should be properly escaped. + EXPECT_EQ( + "event=TestPartResult&file=foo.cc&line=42&message=failed%3D%0A%26%25\n", + *output()); +} + +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Provides access to otherwise private parts of the TestEventListeners class +// that are needed to test it. +class TestEventListenersAccessor { + public: + static TestEventListener* GetRepeater(TestEventListeners* listeners) { + return listeners->repeater(); + } + + static void SetDefaultResultPrinter(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultResultPrinter(listener); + } + static void SetDefaultXmlGenerator(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultXmlGenerator(listener); + } + + static bool EventForwardingEnabled(const TestEventListeners& listeners) { + return listeners.EventForwardingEnabled(); + } + + static void SuppressEventForwarding(TestEventListeners* listeners) { + listeners->SuppressEventForwarding(); + } +}; + +class UnitTestRecordPropertyTestHelper : public Test { + protected: + UnitTestRecordPropertyTestHelper() {} + + // Forwards to UnitTest::RecordProperty() to bypass access controls. + void UnitTestRecordProperty(const char* key, const std::string& value) { + unit_test_.RecordProperty(key, value); + } + + UnitTest unit_test_; +}; + +} // namespace internal +} // namespace testing + +using testing::AssertionFailure; +using testing::AssertionResult; +using testing::AssertionSuccess; +using testing::DoubleLE; +using testing::EmptyTestEventListener; +using testing::Environment; +using testing::FloatLE; +using testing::GTEST_FLAG(also_run_disabled_tests); +using testing::GTEST_FLAG(break_on_failure); +using testing::GTEST_FLAG(catch_exceptions); +using testing::GTEST_FLAG(color); +using testing::GTEST_FLAG(death_test_use_fork); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(list_tests); +using testing::GTEST_FLAG(output); +using testing::GTEST_FLAG(print_time); +using testing::GTEST_FLAG(random_seed); +using testing::GTEST_FLAG(repeat); +using testing::GTEST_FLAG(show_internal_stack_frames); +using testing::GTEST_FLAG(shuffle); +using testing::GTEST_FLAG(stack_trace_depth); +using testing::GTEST_FLAG(stream_result_to); +using testing::GTEST_FLAG(throw_on_failure); +using testing::IsNotSubstring; +using testing::IsSubstring; +using testing::Message; +using testing::ScopedFakeTestPartResultReporter; +using testing::StaticAssertTypeEq; +using testing::Test; +using testing::TestCase; +using testing::TestEventListeners; +using testing::TestInfo; +using testing::TestPartResult; +using testing::TestPartResultArray; +using testing::TestProperty; +using testing::TestResult; +using testing::TimeInMillis; +using testing::UnitTest; +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; +using testing::internal::AppendUserMessage; +using testing::internal::ArrayAwareFind; +using testing::internal::ArrayEq; +using testing::internal::CodePointToUtf8; +using testing::internal::CopyArray; +using testing::internal::CountIf; +using testing::internal::EqFailure; +using testing::internal::FloatingPoint; +using testing::internal::ForEach; +using testing::internal::FormatEpochTimeInMillisAsIso8601; +using testing::internal::FormatTimeInMillisAsSeconds; +using testing::internal::GTestFlagSaver; +using testing::internal::GetCurrentOsStackTraceExceptTop; +using testing::internal::GetElementOr; +using testing::internal::GetNextRandomSeed; +using testing::internal::GetRandomSeedFromFlag; +using testing::internal::GetTestTypeId; +using testing::internal::GetTimeInMillis; +using testing::internal::GetTypeId; +using testing::internal::GetUnitTestImpl; +using testing::internal::Int32; +using testing::internal::Int32FromEnvOrDie; +using testing::internal::IsAProtocolMessage; +using testing::internal::IsContainer; +using testing::internal::IsContainerTest; +using testing::internal::IsNotContainer; +using testing::internal::NativeArray; +using testing::internal::OsStackTraceGetter; +using testing::internal::OsStackTraceGetterInterface; +using testing::internal::ParseInt32Flag; +using testing::internal::RelationToSourceCopy; +using testing::internal::RelationToSourceReference; +using testing::internal::ShouldRunTestOnShard; +using testing::internal::ShouldShard; +using testing::internal::ShouldUseColor; +using testing::internal::Shuffle; +using testing::internal::ShuffleRange; +using testing::internal::SkipPrefix; +using testing::internal::StreamableToString; +using testing::internal::String; +using testing::internal::TestEventListenersAccessor; +using testing::internal::TestResultAccessor; +using testing::internal::UInt32; +using testing::internal::UnitTestImpl; +using testing::internal::WideStringToUtf8; +using testing::internal::edit_distance::CalculateOptimalEdits; +using testing::internal::edit_distance::CreateUnifiedDiff; +using testing::internal::edit_distance::EditType; +using testing::internal::kMaxRandomSeed; +using testing::internal::kTestTypeIdInGoogleTest; +using testing::kMaxStackTraceDepth; + +#if GTEST_HAS_STREAM_REDIRECTION +using testing::internal::CaptureStdout; +using testing::internal::GetCapturedStdout; +#endif + +#if GTEST_IS_THREADSAFE +using testing::internal::ThreadWithParam; +#endif + +class TestingVector : public std::vector { +}; + +::std::ostream& operator<<(::std::ostream& os, + const TestingVector& vector) { + os << "{ "; + for (size_t i = 0; i < vector.size(); i++) { + os << vector[i] << " "; + } + os << "}"; + return os; +} + +// This line tests that we can define tests in an unnamed namespace. +namespace { + +TEST(GetRandomSeedFromFlagTest, HandlesZero) { + const int seed = GetRandomSeedFromFlag(0); + EXPECT_LE(1, seed); + EXPECT_LE(seed, static_cast(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, PreservesValidSeed) { + EXPECT_EQ(1, GetRandomSeedFromFlag(1)); + EXPECT_EQ(2, GetRandomSeedFromFlag(2)); + EXPECT_EQ(kMaxRandomSeed - 1, GetRandomSeedFromFlag(kMaxRandomSeed - 1)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetRandomSeedFromFlag(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, NormalizesInvalidSeed) { + const int seed1 = GetRandomSeedFromFlag(-1); + EXPECT_LE(1, seed1); + EXPECT_LE(seed1, static_cast(kMaxRandomSeed)); + + const int seed2 = GetRandomSeedFromFlag(kMaxRandomSeed + 1); + EXPECT_LE(1, seed2); + EXPECT_LE(seed2, static_cast(kMaxRandomSeed)); +} + +TEST(GetNextRandomSeedTest, WorksForValidInput) { + EXPECT_EQ(2, GetNextRandomSeed(1)); + EXPECT_EQ(3, GetNextRandomSeed(2)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetNextRandomSeed(kMaxRandomSeed - 1)); + EXPECT_EQ(1, GetNextRandomSeed(kMaxRandomSeed)); + + // We deliberately don't test GetNextRandomSeed() with invalid + // inputs, as that requires death tests, which are expensive. This + // is fine as GetNextRandomSeed() is internal and has a + // straightforward definition. +} + +static void ClearCurrentTestPartResults() { + TestResultAccessor::ClearTestPartResults( + GetUnitTestImpl()->current_test_result()); +} + +// Tests GetTypeId. + +TEST(GetTypeIdTest, ReturnsSameValueForSameType) { + EXPECT_EQ(GetTypeId(), GetTypeId()); + EXPECT_EQ(GetTypeId(), GetTypeId()); +} + +class SubClassOfTest : public Test {}; +class AnotherSubClassOfTest : public Test {}; + +TEST(GetTypeIdTest, ReturnsDifferentValuesForDifferentTypes) { + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); +} + +// Verifies that GetTestTypeId() returns the same value, no matter it +// is called from inside Google Test or outside of it. +TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) { + EXPECT_EQ(kTestTypeIdInGoogleTest, GetTestTypeId()); +} + +// Tests CanonicalizeForStdLibVersioning. + +using ::testing::internal::CanonicalizeForStdLibVersioning; + +TEST(CanonicalizeForStdLibVersioning, LeavesUnversionedNamesUnchanged) { + EXPECT_EQ("std::bind", CanonicalizeForStdLibVersioning("std::bind")); + EXPECT_EQ("std::_", CanonicalizeForStdLibVersioning("std::_")); + EXPECT_EQ("std::__foo", CanonicalizeForStdLibVersioning("std::__foo")); + EXPECT_EQ("gtl::__1::x", CanonicalizeForStdLibVersioning("gtl::__1::x")); + EXPECT_EQ("__1::x", CanonicalizeForStdLibVersioning("__1::x")); + EXPECT_EQ("::__1::x", CanonicalizeForStdLibVersioning("::__1::x")); +} + +TEST(CanonicalizeForStdLibVersioning, ElidesDoubleUnderNames) { + EXPECT_EQ("std::bind", CanonicalizeForStdLibVersioning("std::__1::bind")); + EXPECT_EQ("std::_", CanonicalizeForStdLibVersioning("std::__1::_")); + + EXPECT_EQ("std::bind", CanonicalizeForStdLibVersioning("std::__g::bind")); + EXPECT_EQ("std::_", CanonicalizeForStdLibVersioning("std::__g::_")); + + EXPECT_EQ("std::bind", + CanonicalizeForStdLibVersioning("std::__google::bind")); + EXPECT_EQ("std::_", CanonicalizeForStdLibVersioning("std::__google::_")); +} + +// Tests FormatTimeInMillisAsSeconds(). + +TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { + EXPECT_EQ("0", FormatTimeInMillisAsSeconds(0)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) { + EXPECT_EQ("0.003", FormatTimeInMillisAsSeconds(3)); + EXPECT_EQ("0.01", FormatTimeInMillisAsSeconds(10)); + EXPECT_EQ("0.2", FormatTimeInMillisAsSeconds(200)); + EXPECT_EQ("1.2", FormatTimeInMillisAsSeconds(1200)); + EXPECT_EQ("3", FormatTimeInMillisAsSeconds(3000)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { + EXPECT_EQ("-0.003", FormatTimeInMillisAsSeconds(-3)); + EXPECT_EQ("-0.01", FormatTimeInMillisAsSeconds(-10)); + EXPECT_EQ("-0.2", FormatTimeInMillisAsSeconds(-200)); + EXPECT_EQ("-1.2", FormatTimeInMillisAsSeconds(-1200)); + EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000)); +} + +// Tests FormatEpochTimeInMillisAsIso8601(). The correctness of conversion +// for particular dates below was verified in Python using +// datetime.datetime.fromutctimestamp(/1000). + +// FormatEpochTimeInMillisAsIso8601 depends on the current timezone, so we +// have to set up a particular timezone to obtain predictable results. +class FormatEpochTimeInMillisAsIso8601Test : public Test { + public: + // On Cygwin, GCC doesn't allow unqualified integer literals to exceed + // 32 bits, even when 64-bit integer types are available. We have to + // force the constants to have a 64-bit type here. + static const TimeInMillis kMillisPerSec = 1000; + + private: + void SetUp() override { + saved_tz_ = nullptr; + + GTEST_DISABLE_MSC_DEPRECATED_PUSH_(/* getenv, strdup: deprecated */) + if (getenv("TZ")) + saved_tz_ = strdup(getenv("TZ")); + GTEST_DISABLE_MSC_DEPRECATED_POP_() + + // Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We + // cannot use the local time zone because the function's output depends + // on the time zone. + SetTimeZone("UTC+00"); + } + + void TearDown() override { + SetTimeZone(saved_tz_); + free(const_cast(saved_tz_)); + saved_tz_ = nullptr; + } + + static void SetTimeZone(const char* time_zone) { + // tzset() distinguishes between the TZ variable being present and empty + // and not being present, so we have to consider the case of time_zone + // being NULL. +#if _MSC_VER || GTEST_OS_WINDOWS_MINGW + // ...Unless it's MSVC, whose standard library's _putenv doesn't + // distinguish between an empty and a missing variable. + const std::string env_var = + std::string("TZ=") + (time_zone ? time_zone : ""); + _putenv(env_var.c_str()); + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */) + tzset(); + GTEST_DISABLE_MSC_WARNINGS_POP_() +#else + if (time_zone) { + setenv(("TZ"), time_zone, 1); + } else { + unsetenv("TZ"); + } + tzset(); +#endif + } + + const char* saved_tz_; +}; + +const TimeInMillis FormatEpochTimeInMillisAsIso8601Test::kMillisPerSec; + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsTwoDigitSegments) { + EXPECT_EQ("2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, MillisecondsDoNotAffectResult) { + EXPECT_EQ( + "2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec + 234)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsLeadingZeroes) { + EXPECT_EQ("2011-09-03T05:07:02", + FormatEpochTimeInMillisAsIso8601(1315026422 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, Prints24HourTime) { + EXPECT_EQ("2011-09-28T17:08:22", + FormatEpochTimeInMillisAsIso8601(1317229702 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) { + EXPECT_EQ("1970-01-01T00:00:00", FormatEpochTimeInMillisAsIso8601(0)); +} + +# ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +# endif + +// Tests that the LHS of EXPECT_EQ or ASSERT_EQ can be used as a null literal +// when the RHS is a pointer type. +TEST(NullLiteralTest, LHSAllowsNullLiterals) { + EXPECT_EQ(0, static_cast(nullptr)); // NOLINT + ASSERT_EQ(0, static_cast(nullptr)); // NOLINT + EXPECT_EQ(NULL, static_cast(nullptr)); // NOLINT + ASSERT_EQ(NULL, static_cast(nullptr)); // NOLINT + EXPECT_EQ(nullptr, static_cast(nullptr)); + ASSERT_EQ(nullptr, static_cast(nullptr)); + + const int* const p = nullptr; + EXPECT_EQ(0, p); // NOLINT + ASSERT_EQ(0, p); // NOLINT + EXPECT_EQ(NULL, p); // NOLINT + ASSERT_EQ(NULL, p); // NOLINT + EXPECT_EQ(nullptr, p); + ASSERT_EQ(nullptr, p); +} + +struct ConvertToAll { + template + operator T() const { // NOLINT + return T(); + } +}; + +struct ConvertToPointer { + template + operator T*() const { // NOLINT + return nullptr; + } +}; + +struct ConvertToAllButNoPointers { + template ::value, int>::type = 0> + operator T() const { // NOLINT + return T(); + } +}; + +struct MyType {}; +inline bool operator==(MyType const&, MyType const&) { return true; } + +TEST(NullLiteralTest, ImplicitConversion) { + EXPECT_EQ(ConvertToPointer{}, static_cast(nullptr)); +#if !defined(__GNUC__) || defined(__clang__) + // Disabled due to GCC bug gcc.gnu.org/PR89580 + EXPECT_EQ(ConvertToAll{}, static_cast(nullptr)); +#endif + EXPECT_EQ(ConvertToAll{}, MyType{}); + EXPECT_EQ(ConvertToAllButNoPointers{}, MyType{}); +} + +#ifdef __clang__ +#pragma clang diagnostic push +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic error "-Wzero-as-null-pointer-constant" +#endif +#endif + +TEST(NullLiteralTest, NoConversionNoWarning) { + // Test that gtests detection and handling of null pointer constants + // doesn't trigger a warning when '0' isn't actually used as null. + EXPECT_EQ(0, 0); + ASSERT_EQ(0, 0); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +# ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them. +# pragma option pop +# endif + +// +// Tests CodePointToUtf8(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(CodePointToUtf8Test, CanEncodeNul) { + EXPECT_EQ("", CodePointToUtf8(L'\0')); +} + +// Tests that ASCII characters are encoded correctly. +TEST(CodePointToUtf8Test, CanEncodeAscii) { + EXPECT_EQ("a", CodePointToUtf8(L'a')); + EXPECT_EQ("Z", CodePointToUtf8(L'Z')); + EXPECT_EQ("&", CodePointToUtf8(L'&')); + EXPECT_EQ("\x7F", CodePointToUtf8(L'\x7F')); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode8To11Bits) { + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_EQ("\xC3\x93", CodePointToUtf8(L'\xD3')); + + // 101 0111 0110 => 110-10101 10-110110 + // Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints + // in wide strings and wide chars. In order to accommodate them, we have to + // introduce such character constants as integers. + EXPECT_EQ("\xD5\xB6", + CodePointToUtf8(static_cast(0x576))); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode12To16Bits) { + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + EXPECT_EQ("\xE0\xA3\x93", + CodePointToUtf8(static_cast(0x8D3))); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + EXPECT_EQ("\xEC\x9D\x8D", + CodePointToUtf8(static_cast(0xC74D))); +} + +#if !GTEST_WIDE_STRING_USES_UTF16_ +// Tests in this group require a wchar_t to hold > 16 bits, and thus +// are skipped on Windows, and Cygwin, where a wchar_t is +// 16-bit wide. This code may not compile on those systems. + +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode17To21Bits) { + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_EQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3')); + + // 0 0001 0000 0100 0000 0000 => 11110-000 10-010000 10-010000 10-000000 + EXPECT_EQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400')); + + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_EQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634')); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) { + EXPECT_EQ("(Invalid Unicode 0x1234ABCD)", CodePointToUtf8(L'\x1234ABCD')); +} + +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests WideStringToUtf8(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeNul) { + EXPECT_STREQ("", WideStringToUtf8(L"", 0).c_str()); + EXPECT_STREQ("", WideStringToUtf8(L"", -1).c_str()); +} + +// Tests that ASCII strings are encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeAscii) { + EXPECT_STREQ("a", WideStringToUtf8(L"a", 1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", 2).c_str()); + EXPECT_STREQ("a", WideStringToUtf8(L"a", -1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", -1).c_str()); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode8To11Bits) { + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", 1).c_str()); + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", -1).c_str()); + + // 101 0111 0110 => 110-10101 10-110110 + const wchar_t s[] = { 0x576, '\0' }; + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, 1).c_str()); + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, -1).c_str()); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode12To16Bits) { + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + const wchar_t s1[] = { 0x8D3, '\0' }; + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, 1).c_str()); + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, -1).c_str()); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + const wchar_t s2[] = { 0xC74D, '\0' }; + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, 1).c_str()); + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, -1).c_str()); +} + +// Tests that the conversion stops when the function encounters \0 character. +TEST(WideStringToUtf8Test, StopsOnNulCharacter) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABC\0XYZ", 100).c_str()); +} + +// Tests that the conversion stops when the function reaches the limit +// specified by the 'length' parameter. +TEST(WideStringToUtf8Test, StopsWhenLengthLimitReached) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABCDEF", 3).c_str()); +} + +#if !GTEST_WIDE_STRING_USES_UTF16_ +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. This code may not compile +// on the systems using UTF-16 encoding. +TEST(WideStringToUtf8Test, CanEncode17To21Bits) { + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", 1).c_str()); + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", -1).c_str()); + + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", 1).c_str()); + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", -1).c_str()); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidCodePoint) { + EXPECT_STREQ("(Invalid Unicode 0xABCDFF)", + WideStringToUtf8(L"\xABCDFF", -1).c_str()); +} +#else // !GTEST_WIDE_STRING_USES_UTF16_ +// Tests that surrogate pairs are encoded correctly on the systems using +// UTF-16 encoding in the wide strings. +TEST(WideStringToUtf8Test, CanEncodeValidUtf16SUrrogatePairs) { + const wchar_t s[] = { 0xD801, 0xDC00, '\0' }; + EXPECT_STREQ("\xF0\x90\x90\x80", WideStringToUtf8(s, -1).c_str()); +} + +// Tests that encoding an invalid UTF-16 surrogate pair +// generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidUtf16SurrogatePair) { + // Leading surrogate is at the end of the string. + const wchar_t s1[] = { 0xD800, '\0' }; + EXPECT_STREQ("\xED\xA0\x80", WideStringToUtf8(s1, -1).c_str()); + // Leading surrogate is not followed by the trailing surrogate. + const wchar_t s2[] = { 0xD800, 'M', '\0' }; + EXPECT_STREQ("\xED\xA0\x80M", WideStringToUtf8(s2, -1).c_str()); + // Trailing surrogate appearas without a leading surrogate. + const wchar_t s3[] = { 0xDC00, 'P', 'Q', 'R', '\0' }; + EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(s3, -1).c_str()); +} +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests that codepoint concatenation works correctly. +#if !GTEST_WIDE_STRING_USES_UTF16_ +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0x108634, 0xC74D, '\n', 0x576, 0x8D3, 0x108634, '\0'}; + EXPECT_STREQ( + "\xF4\x88\x98\xB4" + "\xEC\x9D\x8D" + "\n" + "\xD5\xB6" + "\xE0\xA3\x93" + "\xF4\x88\x98\xB4", + WideStringToUtf8(s, -1).c_str()); +} +#else +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0xC74D, '\n', 0x576, 0x8D3, '\0'}; + EXPECT_STREQ( + "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93", + WideStringToUtf8(s, -1).c_str()); +} +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests the Random class. + +TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) { + testing::internal::Random random(42); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(0), + "Cannot generate a number in the range \\[0, 0\\)"); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(testing::internal::Random::kMaxRange + 1), + "Generation of a number in \\[0, 2147483649\\) was requested, " + "but this can only generate numbers in \\[0, 2147483648\\)"); +} + +TEST(RandomTest, GeneratesNumbersWithinRange) { + const UInt32 kRange = 10000; + testing::internal::Random random(12345); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i; + } + + testing::internal::Random random2(testing::internal::Random::kMaxRange); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random2.Generate(kRange), kRange) << " for iteration " << i; + } +} + +TEST(RandomTest, RepeatsWhenReseeded) { + const int kSeed = 123; + const int kArraySize = 10; + const UInt32 kRange = 10000; + UInt32 values[kArraySize]; + + testing::internal::Random random(kSeed); + for (int i = 0; i < kArraySize; i++) { + values[i] = random.Generate(kRange); + } + + random.Reseed(kSeed); + for (int i = 0; i < kArraySize; i++) { + EXPECT_EQ(values[i], random.Generate(kRange)) << " for iteration " << i; + } +} + +// Tests STL container utilities. + +// Tests CountIf(). + +static bool IsPositive(int n) { return n > 0; } + +TEST(ContainerUtilityTest, CountIf) { + std::vector v; + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works for an empty container. + + v.push_back(-1); + v.push_back(0); + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works when no value satisfies. + + v.push_back(2); + v.push_back(-10); + v.push_back(10); + EXPECT_EQ(2, CountIf(v, IsPositive)); +} + +// Tests ForEach(). + +static int g_sum = 0; +static void Accumulate(int n) { g_sum += n; } + +TEST(ContainerUtilityTest, ForEach) { + std::vector v; + g_sum = 0; + ForEach(v, Accumulate); + EXPECT_EQ(0, g_sum); // Works for an empty container; + + g_sum = 0; + v.push_back(1); + ForEach(v, Accumulate); + EXPECT_EQ(1, g_sum); // Works for a container with one element. + + g_sum = 0; + v.push_back(20); + v.push_back(300); + ForEach(v, Accumulate); + EXPECT_EQ(321, g_sum); +} + +// Tests GetElementOr(). +TEST(ContainerUtilityTest, GetElementOr) { + std::vector a; + EXPECT_EQ('x', GetElementOr(a, 0, 'x')); + + a.push_back('a'); + a.push_back('b'); + EXPECT_EQ('a', GetElementOr(a, 0, 'x')); + EXPECT_EQ('b', GetElementOr(a, 1, 'x')); + EXPECT_EQ('x', GetElementOr(a, -2, 'x')); + EXPECT_EQ('x', GetElementOr(a, 2, 'x')); +} + +TEST(ContainerUtilityDeathTest, ShuffleRange) { + std::vector a; + a.push_back(0); + a.push_back(1); + a.push_back(2); + testing::internal::Random random(1); + + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, -1, 1, &a), + "Invalid shuffle range start -1: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 4, 4, &a), + "Invalid shuffle range start 4: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 3, 2, &a), + "Invalid shuffle range finish 2: must be in range \\[3, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 3, 4, &a), + "Invalid shuffle range finish 4: must be in range \\[3, 3\\]"); +} + +class VectorShuffleTest : public Test { + protected: + static const size_t kVectorSize = 20; + + VectorShuffleTest() : random_(1) { + for (int i = 0; i < static_cast(kVectorSize); i++) { + vector_.push_back(i); + } + } + + static bool VectorIsCorrupt(const TestingVector& vector) { + if (kVectorSize != vector.size()) { + return true; + } + + bool found_in_vector[kVectorSize] = { false }; + for (size_t i = 0; i < vector.size(); i++) { + const int e = vector[i]; + if (e < 0 || e >= static_cast(kVectorSize) || found_in_vector[e]) { + return true; + } + found_in_vector[e] = true; + } + + // Vector size is correct, elements' range is correct, no + // duplicate elements. Therefore no corruption has occurred. + return false; + } + + static bool VectorIsNotCorrupt(const TestingVector& vector) { + return !VectorIsCorrupt(vector); + } + + static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) { + for (int i = begin; i < end; i++) { + if (i != vector[static_cast(i)]) { + return true; + } + } + return false; + } + + static bool RangeIsUnshuffled( + const TestingVector& vector, int begin, int end) { + return !RangeIsShuffled(vector, begin, end); + } + + static bool VectorIsShuffled(const TestingVector& vector) { + return RangeIsShuffled(vector, 0, static_cast(vector.size())); + } + + static bool VectorIsUnshuffled(const TestingVector& vector) { + return !VectorIsShuffled(vector); + } + + testing::internal::Random random_; + TestingVector vector_; +}; // class VectorShuffleTest + +const size_t VectorShuffleTest::kVectorSize; + +TEST_F(VectorShuffleTest, HandlesEmptyRange) { + // Tests an empty range at the beginning... + ShuffleRange(&random_, 0, 0, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...at the end... + ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and past the end. + ShuffleRange(&random_, kVectorSize, kVectorSize, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) { + // Tests a size one range at the beginning... + ShuffleRange(&random_, 0, 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and at the end. + ShuffleRange(&random_, kVectorSize - 1, kVectorSize, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +// Because we use our own random number generator and a fixed seed, +// we can guarantee that the following "random" tests will succeed. + +TEST_F(VectorShuffleTest, ShufflesEntireVector) { + Shuffle(&random_, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_; + + // Tests the first and last elements in particular to ensure that + // there are no off-by-one problems in our shuffle algorithm. + EXPECT_NE(0, vector_[0]); + EXPECT_NE(static_cast(kVectorSize - 1), vector_[kVectorSize - 1]); +} + +TEST_F(VectorShuffleTest, ShufflesStartOfVector) { + const int kRangeSize = kVectorSize/2; + + ShuffleRange(&random_, 0, kRangeSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, kRangeSize, + static_cast(kVectorSize)); +} + +TEST_F(VectorShuffleTest, ShufflesEndOfVector) { + const int kRangeSize = kVectorSize / 2; + ShuffleRange(&random_, kRangeSize, kVectorSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, + static_cast(kVectorSize)); +} + +TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) { + const int kRangeSize = static_cast(kVectorSize) / 3; + ShuffleRange(&random_, kRangeSize, 2*kRangeSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, 2*kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 2 * kRangeSize, + static_cast(kVectorSize)); +} + +TEST_F(VectorShuffleTest, ShufflesRepeatably) { + TestingVector vector2; + for (size_t i = 0; i < kVectorSize; i++) { + vector2.push_back(static_cast(i)); + } + + random_.Reseed(1234); + Shuffle(&random_, &vector_); + random_.Reseed(1234); + Shuffle(&random_, &vector2); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector2); + + for (size_t i = 0; i < kVectorSize; i++) { + EXPECT_EQ(vector_[i], vector2[i]) << " where i is " << i; + } +} + +// Tests the size of the AssertHelper class. + +TEST(AssertHelperTest, AssertHelperIsSmall) { + // To avoid breaking clients that use lots of assertions in one + // function, we cannot grow the size of AssertHelper. + EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*)); +} + +// Tests String::EndsWithCaseInsensitive(). +TEST(StringTest, EndsWithCaseInsensitive) { + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "BAR")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobaR", "bar")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("", "")); + + EXPECT_FALSE(String::EndsWithCaseInsensitive("Foobar", "foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("foobar", "Foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("", "foo")); +} + +// C++Builder's preprocessor is buggy; it fails to expand macros that +// appear in macro parameters after wide char literals. Provide an alias +// for NULL as a workaround. +static const wchar_t* const kNull = nullptr; + +// Tests String::CaseInsensitiveWideCStringEquals +TEST(StringTest, CaseInsensitiveWideCStringEquals) { + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(nullptr, nullptr)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", kNull)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"foobar")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", kNull)); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); +} + +#if GTEST_OS_WINDOWS + +// Tests String::ShowWideCString(). +TEST(StringTest, ShowWideCString) { + EXPECT_STREQ("(null)", + String::ShowWideCString(NULL).c_str()); + EXPECT_STREQ("", String::ShowWideCString(L"").c_str()); + EXPECT_STREQ("foo", String::ShowWideCString(L"foo").c_str()); +} + +# if GTEST_OS_WINDOWS_MOBILE +TEST(StringTest, AnsiAndUtf16Null) { + EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); + EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL)); +} + +TEST(StringTest, AnsiAndUtf16ConvertBasic) { + const char* ansi = String::Utf16ToAnsi(L"str"); + EXPECT_STREQ("str", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16("str"); + EXPECT_EQ(0, wcsncmp(L"str", utf16, 3)); + delete [] utf16; +} + +TEST(StringTest, AnsiAndUtf16ConvertPathChars) { + const char* ansi = String::Utf16ToAnsi(L".:\\ \"*?"); + EXPECT_STREQ(".:\\ \"*?", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16(".:\\ \"*?"); + EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3)); + delete [] utf16; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#endif // GTEST_OS_WINDOWS + +// Tests TestProperty construction. +TEST(TestPropertyTest, StringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("1", property.value()); +} + +// Tests TestProperty replacing a value. +TEST(TestPropertyTest, ReplaceStringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("1", property.value()); + property.SetValue("2"); + EXPECT_STREQ("2", property.value()); +} + +// AddFatalFailure() and AddNonfatalFailure() must be stand-alone +// functions (i.e. their definitions cannot be inlined at the call +// sites), or C++Builder won't compile the code. +static void AddFatalFailure() { + FAIL() << "Expected fatal failure."; +} + +static void AddNonfatalFailure() { + ADD_FAILURE() << "Expected non-fatal failure."; +} + +class ScopedFakeTestPartResultReporterTest : public Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + AddFatalFailure(); + } else { + AddNonfatalFailure(); + } + } +}; + +// Tests that ScopedFakeTestPartResultReporter intercepts test +// failures. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + } + + EXPECT_EQ(2, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); +} + +TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) { + TestPartResultArray results; + { + // Tests, that the deprecated constructor still works. + ScopedFakeTestPartResultReporter reporter(&results); + AddFailure(NONFATAL_FAILURE); + } + EXPECT_EQ(1, results.size()); +} + +#if GTEST_IS_THREADSAFE + +class ScopedFakeTestPartResultReporterWithThreadsTest + : public ScopedFakeTestPartResultReporterTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + ThreadWithParam thread(&AddFailure, failure, nullptr); + thread.Join(); + } +}; + +TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, + InterceptsTestFailuresInAllThreads) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + AddFailureInOtherThread(FATAL_FAILURE); + } + + EXPECT_EQ(4, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(2).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed()); +} + +#endif // GTEST_IS_THREADSAFE + +// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they +// work even if the failure is generated in a called function rather than +// the current context. + +typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest; + +TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), "Expected fatal failure."); +} + +TEST_F(ExpectFatalFailureTest, AcceptsStdStringObject) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), + ::std::string("Expected fatal failure.")); +} + +TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches fatal + // failures generated on another thread. + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFatalFailure(), + "Expected fatal failure."); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true" +# pragma option push -w-ccc +#endif + +// Tests that EXPECT_FATAL_FAILURE() can be used in a non-void +// function even when the statement in it contains ASSERT_*. + +int NonVoidFunction() { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + return 0; +} + +TEST_F(ExpectFatalFailureTest, CanBeUsedInNonVoidFunction) { + NonVoidFunction(); +} + +// Tests that EXPECT_FATAL_FAILURE(statement, ...) doesn't abort the +// current function even though 'statement' generates a fatal failure. + +void DoesNotAbortHelper(bool* aborted) { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + + *aborted = false; +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them. +# pragma option pop +#endif + +TEST_F(ExpectFatalFailureTest, DoesNotAbort) { + bool aborted = true; + DoesNotAbortHelper(&aborted); + EXPECT_FALSE(aborted); +} + +// Tests that the EXPECT_FATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. + +static int global_var = 0; +#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ + +TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFatalFailure(); + }, ""); +#endif + + EXPECT_FATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFatalFailure(); + }, ""); +} + +// Tests EXPECT_NONFATAL_FAILURE{,ON_ALL_THREADS}. + +typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest; + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + "Expected non-fatal failure."); +} + +TEST_F(ExpectNonfatalFailureTest, AcceptsStdStringObject) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + ::std::string("Expected non-fatal failure.")); +} + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches + // non-fatal failures generated on another thread. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddNonfatalFailure(), + "Expected non-fatal failure."); +} + +// Tests that the EXPECT_NONFATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. +TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { + EXPECT_NONFATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddNonfatalFailure(); + }, ""); + + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddNonfatalFailure(); + }, ""); +} + +#if GTEST_IS_THREADSAFE + +typedef ScopedFakeTestPartResultReporterWithThreadsTest + ExpectFailureWithThreadsTest; + +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailureOnAllThreads) { + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) { + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure."); +} + +#endif // GTEST_IS_THREADSAFE + +// Tests the TestProperty class. + +TEST(TestPropertyTest, ConstructorWorks) { + const TestProperty property("key", "value"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); +} + +TEST(TestPropertyTest, SetValue) { + TestProperty property("key", "value_1"); + EXPECT_STREQ("key", property.key()); + property.SetValue("value_2"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value_2", property.value()); +} + +// Tests the TestResult class + +// The test fixture for testing TestResult. +class TestResultTest : public Test { + protected: + typedef std::vector TPRVector; + + // We make use of 2 TestPartResult objects, + TestPartResult * pr1, * pr2; + + // ... and 3 TestResult objects. + TestResult * r0, * r1, * r2; + + void SetUp() override { + // pr1 is for success. + pr1 = new TestPartResult(TestPartResult::kSuccess, + "foo/bar.cc", + 10, + "Success!"); + + // pr2 is for fatal failure. + pr2 = new TestPartResult(TestPartResult::kFatalFailure, + "foo/bar.cc", + -1, // This line number means "unknown" + "Failure!"); + + // Creates the TestResult objects. + r0 = new TestResult(); + r1 = new TestResult(); + r2 = new TestResult(); + + // In order to test TestResult, we need to modify its internal + // state, in particular the TestPartResult vector it holds. + // test_part_results() returns a const reference to this vector. + // We cast it to a non-const object s.t. it can be modified + TPRVector* results1 = const_cast( + &TestResultAccessor::test_part_results(*r1)); + TPRVector* results2 = const_cast( + &TestResultAccessor::test_part_results(*r2)); + + // r0 is an empty TestResult. + + // r1 contains a single SUCCESS TestPartResult. + results1->push_back(*pr1); + + // r2 contains a SUCCESS, and a FAILURE. + results2->push_back(*pr1); + results2->push_back(*pr2); + } + + void TearDown() override { + delete pr1; + delete pr2; + + delete r0; + delete r1; + delete r2; + } + + // Helper that compares two TestPartResults. + static void CompareTestPartResult(const TestPartResult& expected, + const TestPartResult& actual) { + EXPECT_EQ(expected.type(), actual.type()); + EXPECT_STREQ(expected.file_name(), actual.file_name()); + EXPECT_EQ(expected.line_number(), actual.line_number()); + EXPECT_STREQ(expected.summary(), actual.summary()); + EXPECT_STREQ(expected.message(), actual.message()); + EXPECT_EQ(expected.passed(), actual.passed()); + EXPECT_EQ(expected.failed(), actual.failed()); + EXPECT_EQ(expected.nonfatally_failed(), actual.nonfatally_failed()); + EXPECT_EQ(expected.fatally_failed(), actual.fatally_failed()); + } +}; + +// Tests TestResult::total_part_count(). +TEST_F(TestResultTest, total_part_count) { + ASSERT_EQ(0, r0->total_part_count()); + ASSERT_EQ(1, r1->total_part_count()); + ASSERT_EQ(2, r2->total_part_count()); +} + +// Tests TestResult::Passed(). +TEST_F(TestResultTest, Passed) { + ASSERT_TRUE(r0->Passed()); + ASSERT_TRUE(r1->Passed()); + ASSERT_FALSE(r2->Passed()); +} + +// Tests TestResult::Failed(). +TEST_F(TestResultTest, Failed) { + ASSERT_FALSE(r0->Failed()); + ASSERT_FALSE(r1->Failed()); + ASSERT_TRUE(r2->Failed()); +} + +// Tests TestResult::GetTestPartResult(). + +typedef TestResultTest TestResultDeathTest; + +TEST_F(TestResultDeathTest, GetTestPartResult) { + CompareTestPartResult(*pr1, r2->GetTestPartResult(0)); + CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(2), ""); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(-1), ""); +} + +// Tests TestResult has no properties when none are added. +TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { + TestResult test_result; + ASSERT_EQ(0, test_result.test_property_count()); +} + +// Tests TestResult has the expected property when added. +TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) { + TestResult test_result; + TestProperty property("key_1", "1"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property); + ASSERT_EQ(1, test_result.test_property_count()); + const TestProperty& actual_property = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property.key()); + EXPECT_STREQ("1", actual_property.value()); +} + +// Tests TestResult has multiple properties when added. +TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); + ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("1", actual_property_1.value()); + + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("2", actual_property_2.value()); +} + +// Tests TestResult::RecordProperty() overrides values for duplicate keys. +TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { + TestResult test_result; + TestProperty property_1_1("key_1", "1"); + TestProperty property_2_1("key_2", "2"); + TestProperty property_1_2("key_1", "12"); + TestProperty property_2_2("key_2", "22"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_2); + + ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("12", actual_property_1.value()); + + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("22", actual_property_2.value()); +} + +// Tests TestResult::GetTestProperty(). +TEST(TestResultPropertyTest, GetTestProperty) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + TestProperty property_3("key_3", "3"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_3); + + const TestProperty& fetched_property_1 = test_result.GetTestProperty(0); + const TestProperty& fetched_property_2 = test_result.GetTestProperty(1); + const TestProperty& fetched_property_3 = test_result.GetTestProperty(2); + + EXPECT_STREQ("key_1", fetched_property_1.key()); + EXPECT_STREQ("1", fetched_property_1.value()); + + EXPECT_STREQ("key_2", fetched_property_2.key()); + EXPECT_STREQ("2", fetched_property_2.value()); + + EXPECT_STREQ("key_3", fetched_property_3.key()); + EXPECT_STREQ("3", fetched_property_3.value()); + + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(3), ""); + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), ""); +} + +// Tests the Test class. +// +// It's difficult to test every public method of this class (we are +// already stretching the limit of Google Test by using it to test itself!). +// Fortunately, we don't have to do that, as we are already testing +// the functionalities of the Test class extensively by using Google Test +// alone. +// +// Therefore, this section only contains one test. + +// Tests that GTestFlagSaver works on Windows and Mac. + +class GTestFlagSaverTest : public Test { + protected: + // Saves the Google Test flags such that we can restore them later, and + // then sets them to their default values. This will be called + // before the first test in this test case is run. + static void SetUpTestSuite() { + saver_ = new GTestFlagSaver; + + GTEST_FLAG(also_run_disabled_tests) = false; + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(color) = "auto"; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; + GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; + GTEST_FLAG(throw_on_failure) = false; + } + + // Restores the Google Test flags that the tests have modified. This will + // be called after the last test in this test case is run. + static void TearDownTestSuite() { + delete saver_; + saver_ = nullptr; + } + + // Verifies that the Google Test flags have their default values, and then + // modifies each of them. + void VerifyAndModifyFlags() { + EXPECT_FALSE(GTEST_FLAG(also_run_disabled_tests)); + EXPECT_FALSE(GTEST_FLAG(break_on_failure)); + EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); + EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); + EXPECT_FALSE(GTEST_FLAG(death_test_use_fork)); + EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); + EXPECT_FALSE(GTEST_FLAG(list_tests)); + EXPECT_STREQ("", GTEST_FLAG(output).c_str()); + EXPECT_TRUE(GTEST_FLAG(print_time)); + EXPECT_EQ(0, GTEST_FLAG(random_seed)); + EXPECT_EQ(1, GTEST_FLAG(repeat)); + EXPECT_FALSE(GTEST_FLAG(shuffle)); + EXPECT_EQ(kMaxStackTraceDepth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ("", GTEST_FLAG(stream_result_to).c_str()); + EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); + + GTEST_FLAG(also_run_disabled_tests) = true; + GTEST_FLAG(break_on_failure) = true; + GTEST_FLAG(catch_exceptions) = true; + GTEST_FLAG(color) = "no"; + GTEST_FLAG(death_test_use_fork) = true; + GTEST_FLAG(filter) = "abc"; + GTEST_FLAG(list_tests) = true; + GTEST_FLAG(output) = "xml:foo.xml"; + GTEST_FLAG(print_time) = false; + GTEST_FLAG(random_seed) = 1; + GTEST_FLAG(repeat) = 100; + GTEST_FLAG(shuffle) = true; + GTEST_FLAG(stack_trace_depth) = 1; + GTEST_FLAG(stream_result_to) = "localhost:1234"; + GTEST_FLAG(throw_on_failure) = true; + } + + private: + // For saving Google Test flags during this test case. + static GTestFlagSaver* saver_; +}; + +GTestFlagSaver* GTestFlagSaverTest::saver_ = nullptr; + +// Google Test doesn't guarantee the order of tests. The following two +// tests are designed to work regardless of their order. + +// Modifies the Google Test flags in the test body. +TEST_F(GTestFlagSaverTest, ModifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Verifies that the Google Test flags in the body of the previous test were +// restored to their original values. +TEST_F(GTestFlagSaverTest, VerifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Sets an environment variable with the given name to the given +// value. If the value argument is "", unsets the environment +// variable. The caller must ensure that both arguments are not NULL. +static void SetEnv(const char* name, const char* value) { +#if GTEST_OS_WINDOWS_MOBILE + // Environment variables are not supported on Windows CE. + return; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // C++Builder's putenv only stores a pointer to its parameter; we have to + // ensure that the string remains valid as long as it might be needed. + // We use an std::map to do so. + static std::map added_env; + + // Because putenv stores a pointer to the string buffer, we can't delete the + // previous string (if present) until after it's replaced. + std::string *prev_env = NULL; + if (added_env.find(name) != added_env.end()) { + prev_env = added_env[name]; + } + added_env[name] = new std::string( + (Message() << name << "=" << value).GetString()); + + // The standard signature of putenv accepts a 'char*' argument. Other + // implementations, like C++Builder's, accept a 'const char*'. + // We cast away the 'const' since that would work for both variants. + putenv(const_cast(added_env[name]->c_str())); + delete prev_env; +#elif GTEST_OS_WINDOWS // If we are on Windows proper. + _putenv((Message() << name << "=" << value).GetString().c_str()); +#else + if (*value == '\0') { + unsetenv(name); + } else { + setenv(name, value, 1); + } +#endif // GTEST_OS_WINDOWS_MOBILE +} + +#if !GTEST_OS_WINDOWS_MOBILE +// Environment variables are not supported on Windows CE. + +using testing::internal::Int32FromGTestEnv; + +// Tests Int32FromGTestEnv(). + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable is not set. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", ""); + EXPECT_EQ(10, Int32FromGTestEnv("temp", 10)); +} + +# if !defined(GTEST_GET_INT32_FROM_ENV_) + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable overflows as an Int32. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12345678987654321"); + EXPECT_EQ(20, Int32FromGTestEnv("temp", 20)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-12345678987654321"); + EXPECT_EQ(30, Int32FromGTestEnv("temp", 30)); +} + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable does not represent a valid decimal integer. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "A1"); + EXPECT_EQ(40, Int32FromGTestEnv("temp", 40)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12X"); + EXPECT_EQ(50, Int32FromGTestEnv("temp", 50)); +} + +# endif // !defined(GTEST_GET_INT32_FROM_ENV_) + +// Tests that Int32FromGTestEnv() parses and returns the value of the +// environment variable when it represents a valid decimal integer in +// the range of an Int32. +TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "123"); + EXPECT_EQ(123, Int32FromGTestEnv("temp", 0)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-321"); + EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests ParseInt32Flag(). + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag has wrong format +TEST(ParseInt32FlagTest, ReturnsFalseForInvalidFlag) { + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--a=100", "b", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("a=100", "a", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag overflows as an Int32. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=-12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag does not represent a valid decimal +// integer. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=A1", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=12X", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() parses the value of the flag and +// returns true when the flag represents a valid decimal integer in +// the range of an Int32. +TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { + Int32 value = 123; + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value)); + EXPECT_EQ(456, value); + + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", + "abc", &value)); + EXPECT_EQ(-789, value); +} + +// Tests that Int32FromEnvOrDie() parses the value of the var or +// returns the correct default. +// Environment variables are not supported on Windows CE. +#if !GTEST_OS_WINDOWS_MOBILE +TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { + EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123"); + EXPECT_EQ(123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); + EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable is not an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); + EXPECT_DEATH_IF_SUPPORTED( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); +} + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable cannot be represented by an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); + EXPECT_DEATH_IF_SUPPORTED( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); +} + +// Tests that ShouldRunTestOnShard() selects all tests +// where there is 1 shard. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) { + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 0)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 1)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 2)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 3)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 4)); +} + +class ShouldShardTest : public testing::Test { + protected: + void SetUp() override { + index_var_ = GTEST_FLAG_PREFIX_UPPER_ "INDEX"; + total_var_ = GTEST_FLAG_PREFIX_UPPER_ "TOTAL"; + } + + void TearDown() override { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + } + + const char* index_var_; + const char* total_var_; +}; + +// Tests that sharding is disabled if neither of the environment variables +// are set. +TEST_F(ShouldShardTest, ReturnsFalseWhenNeitherEnvVarIsSet) { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is not enabled if total_shards == 1. +TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) { + SetEnv(index_var_, "0"); + SetEnv(total_var_, "1"); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is enabled if total_shards > 1 and +// we are not in a death test subprocess. +// Environment variables are not supported on Windows CE. +#if !GTEST_OS_WINDOWS_MOBILE +TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "22"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "8"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "0"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests that we exit in error if the sharding values are not valid. + +typedef ShouldShardTest ShouldShardDeathTest; + +TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "4"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, "4"); + SetEnv(total_var_, "-2"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, "5"); + SetEnv(total_var_, ""); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, ""); + SetEnv(total_var_, "5"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); +} + +// Tests that ShouldRunTestOnShard is a partition when 5 +// shards are used. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) { + // Choose an arbitrary number of tests and shards. + const int num_tests = 17; + const int num_shards = 5; + + // Check partitioning: each test should be on exactly 1 shard. + for (int test_id = 0; test_id < num_tests; test_id++) { + int prev_selected_shard_index = -1; + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + if (ShouldRunTestOnShard(num_shards, shard_index, test_id)) { + if (prev_selected_shard_index < 0) { + prev_selected_shard_index = shard_index; + } else { + ADD_FAILURE() << "Shard " << prev_selected_shard_index << " and " + << shard_index << " are both selected to run test " << test_id; + } + } + } + } + + // Check balance: This is not required by the sharding protocol, but is a + // desirable property for performance. + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + int num_tests_on_shard = 0; + for (int test_id = 0; test_id < num_tests; test_id++) { + num_tests_on_shard += + ShouldRunTestOnShard(num_shards, shard_index, test_id); + } + EXPECT_GE(num_tests_on_shard, num_tests / num_shards); + } +} + +// For the same reason we are not explicitly testing everything in the +// Test class, there are no separate tests for the following classes +// (except for some trivial cases): +// +// TestSuite, UnitTest, UnitTestResultPrinter. +// +// Similarly, there are no separate tests for the following macros: +// +// TEST, TEST_F, RUN_ALL_TESTS + +TEST(UnitTestTest, CanGetOriginalWorkingDir) { + ASSERT_TRUE(UnitTest::GetInstance()->original_working_dir() != nullptr); + EXPECT_STRNE(UnitTest::GetInstance()->original_working_dir(), ""); +} + +TEST(UnitTestTest, ReturnsPlausibleTimestamp) { + EXPECT_LT(0, UnitTest::GetInstance()->start_timestamp()); + EXPECT_LE(UnitTest::GetInstance()->start_timestamp(), GetTimeInMillis()); +} + +// When a property using a reserved key is supplied to this function, it +// tests that a non-fatal failure is added, a fatal failure is not added, +// and that the property is not recorded. +void ExpectNonFatalFailureRecordingPropertyWithReservedKey( + const TestResult& test_result, const char* key) { + EXPECT_NONFATAL_FAILURE(Test::RecordProperty(key, "1"), "Reserved key"); + ASSERT_EQ(0, test_result.test_property_count()) << "Property for key '" << key + << "' recorded unexpectedly."; +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + const char* key) { + const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(test_info != nullptr); + ExpectNonFatalFailureRecordingPropertyWithReservedKey(*test_info->result(), + key); +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestSuite( + const char* key) { + const testing::TestSuite* test_suite = + UnitTest::GetInstance()->current_test_suite(); + ASSERT_TRUE(test_suite != nullptr); + ExpectNonFatalFailureRecordingPropertyWithReservedKey( + test_suite->ad_hoc_test_result(), key); +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestSuite( + const char* key) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey( + UnitTest::GetInstance()->ad_hoc_test_result(), key); +} + +// Tests that property recording functions in UnitTest outside of tests +// functions correcly. Creating a separate instance of UnitTest ensures it +// is in a state similar to the UnitTest's singleton's between tests. +class UnitTestRecordPropertyTest : + public testing::internal::UnitTestRecordPropertyTestHelper { + public: + static void SetUpTestSuite() { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestSuite( + "disabled"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestSuite( + "errors"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestSuite( + "failures"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestSuite( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestSuite( + "tests"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestSuite( + "time"); + + Test::RecordProperty("test_case_key_1", "1"); + + const testing::TestSuite* test_suite = + UnitTest::GetInstance()->current_test_suite(); + + ASSERT_TRUE(test_suite != nullptr); + + ASSERT_EQ(1, test_suite->ad_hoc_test_result().test_property_count()); + EXPECT_STREQ("test_case_key_1", + test_suite->ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", + test_suite->ad_hoc_test_result().GetTestProperty(0).value()); + } +}; + +// Tests TestResult has the expected property when added. +TEST_F(UnitTestRecordPropertyTest, OnePropertyFoundWhenAdded) { + UnitTestRecordProperty("key_1", "1"); + + ASSERT_EQ(1, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); +} + +// Tests TestResult has multiple properties when added. +TEST_F(UnitTestRecordPropertyTest, MultiplePropertiesFoundWhenAdded) { + UnitTestRecordProperty("key_1", "1"); + UnitTestRecordProperty("key_2", "2"); + + ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); + + EXPECT_STREQ("key_2", + unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); + EXPECT_STREQ("2", unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); +} + +// Tests TestResult::RecordProperty() overrides values for duplicate keys. +TEST_F(UnitTestRecordPropertyTest, OverridesValuesForDuplicateKeys) { + UnitTestRecordProperty("key_1", "1"); + UnitTestRecordProperty("key_2", "2"); + UnitTestRecordProperty("key_1", "12"); + UnitTestRecordProperty("key_2", "22"); + + ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("12", + unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); + + EXPECT_STREQ("key_2", + unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); + EXPECT_STREQ("22", + unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); +} + +TEST_F(UnitTestRecordPropertyTest, + AddFailureInsideTestsWhenUsingTestSuiteReservedKeys) { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "value_param"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "type_param"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "status"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "time"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "classname"); +} + +TEST_F(UnitTestRecordPropertyTest, + AddRecordWithReservedKeysGeneratesCorrectPropertyList) { + EXPECT_NONFATAL_FAILURE( + Test::RecordProperty("name", "1"), + "'classname', 'name', 'status', 'time', 'type_param', 'value_param'," + " 'file', and 'line' are reserved"); +} + +class UnitTestRecordPropertyTestEnvironment : public Environment { + public: + void TearDown() override { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestSuite( + "tests"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestSuite( + "failures"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestSuite( + "disabled"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestSuite( + "errors"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestSuite( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestSuite( + "timestamp"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestSuite( + "time"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestSuite( + "random_seed"); + } +}; + +// This will test property recording outside of any test or test case. +static Environment* record_property_env GTEST_ATTRIBUTE_UNUSED_ = + AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment); + +// This group of tests is for predicate assertions (ASSERT_PRED*, etc) +// of various arities. They do not attempt to be exhaustive. Rather, +// view them as smoke tests that can be easily reviewed and verified. +// A more complete set of tests for predicate assertions can be found +// in gtest_pred_impl_unittest.cc. + +// First, some predicates and predicate-formatters needed by the tests. + +// Returns true if and only if the argument is an even number. +bool IsEven(int n) { + return (n % 2) == 0; +} + +// A functor that returns true if and only if the argument is an even number. +struct IsEvenFunctor { + bool operator()(int n) { return IsEven(n); } +}; + +// A predicate-formatter function that asserts the argument is an even +// number. +AssertionResult AssertIsEven(const char* expr, int n) { + if (IsEven(n)) { + return AssertionSuccess(); + } + + Message msg; + msg << expr << " evaluates to " << n << ", which is not even."; + return AssertionFailure(msg); +} + +// A predicate function that returns AssertionResult for use in +// EXPECT/ASSERT_TRUE/FALSE. +AssertionResult ResultIsEven(int n) { + if (IsEven(n)) + return AssertionSuccess() << n << " is even"; + else + return AssertionFailure() << n << " is odd"; +} + +// A predicate function that returns AssertionResult but gives no +// explanation why it succeeds. Needed for testing that +// EXPECT/ASSERT_FALSE handles such functions correctly. +AssertionResult ResultIsEvenNoExplanation(int n) { + if (IsEven(n)) + return AssertionSuccess(); + else + return AssertionFailure() << n << " is odd"; +} + +// A predicate-formatter functor that asserts the argument is an even +// number. +struct AssertIsEvenFunctor { + AssertionResult operator()(const char* expr, int n) { + return AssertIsEven(expr, n); + } +}; + +// Returns true if and only if the sum of the arguments is an even number. +bool SumIsEven2(int n1, int n2) { + return IsEven(n1 + n2); +} + +// A functor that returns true if and only if the sum of the arguments is an +// even number. +struct SumIsEven3Functor { + bool operator()(int n1, int n2, int n3) { + return IsEven(n1 + n2 + n3); + } +}; + +// A predicate-formatter function that asserts the sum of the +// arguments is an even number. +AssertionResult AssertSumIsEven4( + const char* e1, const char* e2, const char* e3, const char* e4, + int n1, int n2, int n3, int n4) { + const int sum = n1 + n2 + n3 + n4; + if (IsEven(sum)) { + return AssertionSuccess(); + } + + Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4 + << ") evaluates to " << sum << ", which is not even."; + return AssertionFailure(msg); +} + +// A predicate-formatter functor that asserts the sum of the arguments +// is an even number. +struct AssertSumIsEven5Functor { + AssertionResult operator()( + const char* e1, const char* e2, const char* e3, const char* e4, + const char* e5, int n1, int n2, int n3, int n4, int n5) { + const int sum = n1 + n2 + n3 + n4 + n5; + if (IsEven(sum)) { + return AssertionSuccess(); + } + + Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " (" + << n1 << " + " << n2 << " + " << n3 << " + " << n4 << " + " << n5 + << ") evaluates to " << sum << ", which is not even."; + return AssertionFailure(msg); + } +}; + + +// Tests unary predicate assertions. + +// Tests unary predicate assertions that don't use a custom formatter. +TEST(Pred1Test, WithoutFormat) { + // Success cases. + EXPECT_PRED1(IsEvenFunctor(), 2) << "This failure is UNEXPECTED!"; + ASSERT_PRED1(IsEven, 4); + + // Failure cases. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(IsEven, 5) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE(ASSERT_PRED1(IsEvenFunctor(), 5), + "evaluates to false"); +} + +// Tests unary predicate assertions that use a custom formatter. +TEST(Pred1Test, WithFormat) { + // Success cases. + EXPECT_PRED_FORMAT1(AssertIsEven, 2); + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), 4) + << "This failure is UNEXPECTED!"; + + // Failure cases. + const int n = 5; + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT1(AssertIsEvenFunctor(), n), + "n evaluates to 5, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEven, 5) << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that unary predicate assertions evaluates their arguments +// exactly once. +TEST(Pred1Test, SingleEvaluationOnFailure) { + // A success case. + static int n = 0; + EXPECT_PRED1(IsEven, n++); + EXPECT_EQ(1, n) << "The argument is not evaluated exactly once."; + + // A failure case. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), n++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(2, n) << "The argument is not evaluated exactly once."; +} + + +// Tests predicate assertions whose arity is >= 2. + +// Tests predicate assertions that don't use a custom formatter. +TEST(PredTest, WithoutFormat) { + // Success cases. + ASSERT_PRED2(SumIsEven2, 2, 4) << "This failure is UNEXPECTED!"; + EXPECT_PRED3(SumIsEven3Functor(), 4, 6, 8); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(SumIsEven2, n1, n2) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(SumIsEven3Functor(), 1, 2, 4); + }, "evaluates to false"); +} + +// Tests predicate assertions that use a custom formatter. +TEST(PredTest, WithFormat) { + // Success cases. + ASSERT_PRED_FORMAT4(AssertSumIsEven4, 4, 6, 8, 10) << + "This failure is UNEXPECTED!"; + EXPECT_PRED_FORMAT5(AssertSumIsEven5Functor(), 2, 4, 6, 8, 10); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + const int n3 = 4; + const int n4 = 6; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, n1, n2, n3, n4); + }, "evaluates to 13, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), 1, 2, 4, 6, 8) + << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that predicate assertions evaluates their arguments +// exactly once. +TEST(PredTest, SingleEvaluationOnFailure) { + // A success case. + int n1 = 0; + int n2 = 0; + EXPECT_PRED2(SumIsEven2, n1++, n2++); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + + // Another success case. + n1 = n2 = 0; + int n3 = 0; + int n4 = 0; + int n5 = 0; + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), + n1++, n2++, n3++, n4++, n5++) + << "This failure is UNEXPECTED!"; + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; + EXPECT_EQ(1, n5) << "Argument 5 is not evaluated exactly once."; + + // A failure case. + n1 = n2 = n3 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(SumIsEven3Functor(), ++n1, n2++, n3++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + + // Another failure case. + n1 = n2 = n3 = n4 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, ++n1, n2++, n3++, n4++); + }, "evaluates to 1, which is not even."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; +} + +// Test predicate assertions for sets +TEST(PredTest, ExpectPredEvalFailure) { + std::set set_a = {2, 1, 3, 4, 5}; + std::set set_b = {0, 4, 8}; + const auto compare_sets = [] (std::set, std::set) { return false; }; + EXPECT_NONFATAL_FAILURE( + EXPECT_PRED2(compare_sets, set_a, set_b), + "compare_sets(set_a, set_b) evaluates to false, where\nset_a evaluates " + "to { 1, 2, 3, 4, 5 }\nset_b evaluates to { 0, 4, 8 }"); +} + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PREDn and EXPECT_PREDn. + +bool IsPositive(double x) { + return x > 0; +} + +template +bool IsNegative(T x) { + return x < 0; +} + +template +bool GreaterThan(T1 x1, T2 x2) { + return x1 > x2; +} + +// Tests that overloaded functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsOverloadedFunction) { + // C++Builder requires C-style casts rather than static_cast. + EXPECT_PRED1((bool (*)(int))(IsPositive), 5); // NOLINT + ASSERT_PRED1((bool (*)(double))(IsPositive), 6.0); // NOLINT +} + +// Tests that template functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED1(IsNegative, -5); + // Makes sure that we can handle templates with more than one + // parameter. + ASSERT_PRED2((GreaterThan), 5, 0); +} + + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PRED_FORMATn and EXPECT_PRED_FORMATn. + +AssertionResult IsPositiveFormat(const char* /* expr */, int n) { + return n > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +AssertionResult IsPositiveFormat(const char* /* expr */, double x) { + return x > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +template +AssertionResult IsNegativeFormat(const char* /* expr */, T x) { + return x < 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +template +AssertionResult EqualsFormat(const char* /* expr1 */, const char* /* expr2 */, + const T1& x1, const T2& x2) { + return x1 == x2 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +// Tests that overloaded functions can be used in *_PRED_FORMAT* +// without explicitly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsOverloadedFunction) { + EXPECT_PRED_FORMAT1(IsPositiveFormat, 5); + ASSERT_PRED_FORMAT1(IsPositiveFormat, 6.0); +} + +// Tests that template functions can be used in *_PRED_FORMAT* without +// explicitly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED_FORMAT1(IsNegativeFormat, -5); + ASSERT_PRED_FORMAT2(EqualsFormat, 3, 3); +} + + +// Tests string assertions. + +// Tests ASSERT_STREQ with non-NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ) { + const char * const p1 = "good"; + ASSERT_STREQ(p1, p1); + + // Let p2 have the same content as p1, but be at a different address. + const char p2[] = "good"; + ASSERT_STREQ(p1, p2); + + EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"), + " \"bad\"\n \"good\""); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null) { + ASSERT_STREQ(static_cast(nullptr), nullptr); + EXPECT_FATAL_FAILURE(ASSERT_STREQ(nullptr, "non-null"), "non-null"); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null2) { + EXPECT_FATAL_FAILURE(ASSERT_STREQ("non-null", nullptr), "non-null"); +} + +// Tests ASSERT_STRNE. +TEST(StringAssertionTest, ASSERT_STRNE) { + ASSERT_STRNE("hi", "Hi"); + ASSERT_STRNE("Hi", nullptr); + ASSERT_STRNE(nullptr, "Hi"); + ASSERT_STRNE("", nullptr); + ASSERT_STRNE(nullptr, ""); + ASSERT_STRNE("", "Hi"); + ASSERT_STRNE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("Hi", "Hi"), + "\"Hi\" vs \"Hi\""); +} + +// Tests ASSERT_STRCASEEQ. +TEST(StringAssertionTest, ASSERT_STRCASEEQ) { + ASSERT_STRCASEEQ("hi", "Hi"); + ASSERT_STRCASEEQ(static_cast(nullptr), nullptr); + + ASSERT_STRCASEEQ("", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("Hi", "hi2"), + "Ignoring case"); +} + +// Tests ASSERT_STRCASENE. +TEST(StringAssertionTest, ASSERT_STRCASENE) { + ASSERT_STRCASENE("hi1", "Hi2"); + ASSERT_STRCASENE("Hi", nullptr); + ASSERT_STRCASENE(nullptr, "Hi"); + ASSERT_STRCASENE("", nullptr); + ASSERT_STRCASENE(nullptr, ""); + ASSERT_STRCASENE("", "Hi"); + ASSERT_STRCASENE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"), + "(ignoring case)"); +} + +// Tests *_STREQ on wide strings. +TEST(StringAssertionTest, STREQ_Wide) { + // NULL strings. + ASSERT_STREQ(static_cast(nullptr), nullptr); + + // Empty strings. + ASSERT_STREQ(L"", L""); + + // Non-null vs NULL. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"non-null", nullptr), "non-null"); + + // Equal strings. + EXPECT_STREQ(L"Hi", L"Hi"); + + // Unequal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc", L"Abc"), + "Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"), + "abc"); + + // The streaming variation. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_STREQ(L"abc\x8119", L"abc\x8121") << "Expected failure"; + }, "Expected failure"); +} + +// Tests *_STRNE on wide strings. +TEST(StringAssertionTest, STRNE_Wide) { + // NULL strings. + EXPECT_NONFATAL_FAILURE( + { // NOLINT + EXPECT_STRNE(static_cast(nullptr), nullptr); + }, + ""); + + // Empty strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"", L""), + "L\"\""); + + // Non-null vs NULL. + ASSERT_STRNE(L"non-null", nullptr); + + // Equal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"Hi", L"Hi"), + "L\"Hi\""); + + // Unequal strings. + EXPECT_STRNE(L"abc", L"Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"), + "abc"); + + // The streaming variation. + ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen"; +} + +// Tests for ::testing::IsSubstring(). + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsSubstringTest, ReturnsCorrectResultForCString) { + EXPECT_FALSE(IsSubstring("", "", nullptr, "a")); + EXPECT_FALSE(IsSubstring("", "", "b", nullptr)); + EXPECT_FALSE(IsSubstring("", "", "needle", "haystack")); + + EXPECT_TRUE(IsSubstring("", "", static_cast(nullptr), nullptr)); + EXPECT_TRUE(IsSubstring("", "", "needle", "two needles")); +} + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) { + EXPECT_FALSE(IsSubstring("", "", kNull, L"a")); + EXPECT_FALSE(IsSubstring("", "", L"b", kNull)); + EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack")); + + EXPECT_TRUE( + IsSubstring("", "", static_cast(nullptr), nullptr)); + EXPECT_TRUE(IsSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is const char*. +TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: \"haystack\"", + IsSubstring("needle_expr", "haystack_expr", + "needle", "haystack").failure_message()); +} + +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { + EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world"))); +} + +#if GTEST_HAS_STD_WSTRING +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) { + EXPECT_TRUE(IsSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_FALSE(IsSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, GeneratesCorrectMessageForWstring) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: L\"haystack\"", + IsSubstring( + "needle_expr", "haystack_expr", + ::std::wstring(L"needle"), L"haystack").failure_message()); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests for ::testing::IsNotSubstring(). + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) { + EXPECT_TRUE(IsNotSubstring("", "", "needle", "haystack")); + EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles")); +} + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) { + EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack")); + EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: L\"two needles\"", + IsNotSubstring( + "needle_expr", "haystack_expr", + L"needle", L"two needles").failure_message()); +} + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { + EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world"))); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: \"two needles\"", + IsNotSubstring( + "needle_expr", "haystack_expr", + ::std::string("needle"), "two needles").failure_message()); +} + +#if GTEST_HAS_STD_WSTRING + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { + EXPECT_FALSE( + IsNotSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_TRUE(IsNotSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests floating-point assertions. + +template +class FloatingPointTest : public Test { + protected: + // Pre-calculated numbers to be used by the tests. + struct TestValues { + RawType close_to_positive_zero; + RawType close_to_negative_zero; + RawType further_from_negative_zero; + + RawType close_to_one; + RawType further_from_one; + + RawType infinity; + RawType close_to_infinity; + RawType further_from_infinity; + + RawType nan1; + RawType nan2; + }; + + typedef typename testing::internal::FloatingPoint Floating; + typedef typename Floating::Bits Bits; + + void SetUp() override { + const size_t max_ulps = Floating::kMaxUlps; + + // The bits that represent 0.0. + const Bits zero_bits = Floating(0).bits(); + + // Makes some numbers close to 0.0. + values_.close_to_positive_zero = Floating::ReinterpretBits( + zero_bits + max_ulps/2); + values_.close_to_negative_zero = -Floating::ReinterpretBits( + zero_bits + max_ulps - max_ulps/2); + values_.further_from_negative_zero = -Floating::ReinterpretBits( + zero_bits + max_ulps + 1 - max_ulps/2); + + // The bits that represent 1.0. + const Bits one_bits = Floating(1).bits(); + + // Makes some numbers close to 1.0. + values_.close_to_one = Floating::ReinterpretBits(one_bits + max_ulps); + values_.further_from_one = Floating::ReinterpretBits( + one_bits + max_ulps + 1); + + // +infinity. + values_.infinity = Floating::Infinity(); + + // The bits that represent +infinity. + const Bits infinity_bits = Floating(values_.infinity).bits(); + + // Makes some numbers close to infinity. + values_.close_to_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps); + values_.further_from_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps - 1); + + // Makes some NAN's. Sets the most significant bit of the fraction so that + // our NaN's are quiet; trying to process a signaling NaN would raise an + // exception if our environment enables floating point exceptions. + values_.nan1 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 1); + values_.nan2 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 200); + } + + void TestSize() { + EXPECT_EQ(sizeof(RawType), sizeof(Bits)); + } + + static TestValues values_; +}; + +template +typename FloatingPointTest::TestValues + FloatingPointTest::values_; + +// Instantiates FloatingPointTest for testing *_FLOAT_EQ. +typedef FloatingPointTest FloatTest; + +// Tests that the size of Float::Bits matches the size of float. +TEST_F(FloatTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(FloatTest, Zeros) { + EXPECT_FLOAT_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.5), + "1.5"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_FLOAT_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(FloatTest, AlmostZeros) { + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; + + EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero); + EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero); + EXPECT_FLOAT_EQ(v.close_to_positive_zero, v.close_to_negative_zero); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FLOAT_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); +} + +// Tests comparing numbers close to each other. +TEST_F(FloatTest, SmallDiff) { + EXPECT_FLOAT_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); +} + +// Tests comparing numbers far apart. +TEST_F(FloatTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(2.5, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(FloatTest, Infinity) { + EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); + + // This is interesting as the representations of infinity and nan1 + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, values_.nan1), + "values_.nan1"); +} + +// Tests that comparing with NAN always returns false. +TEST_F(FloatTest, NaN) { + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; + + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2), + "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1), + "v.nan1"); + + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity), + "v.infinity"); +} + +// Tests that *_FLOAT_EQ are reflexive. +TEST_F(FloatTest, Reflexive) { + EXPECT_FLOAT_EQ(0.0, 0.0); + EXPECT_FLOAT_EQ(1.0, 1.0); + ASSERT_FLOAT_EQ(values_.infinity, values_.infinity); +} + +// Tests that *_FLOAT_EQ are commutative. +TEST_F(FloatTest, Commutative) { + // We already tested EXPECT_FLOAT_EQ(1.0, values_.close_to_one). + EXPECT_FLOAT_EQ(values_.close_to_one, 1.0); + + // We already tested EXPECT_FLOAT_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.further_from_one, 1.0), + "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(FloatTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0f, -1.1f, 0.2f); + EXPECT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests ASSERT_NEAR. +TEST_F(FloatTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0f, -1.1f, 0.2f); + ASSERT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests the cases where FloatLE() should succeed. +TEST_F(FloatTest, FloatLESucceeds) { + EXPECT_PRED_FORMAT2(FloatLE, 1.0f, 2.0f); // When val1 < val2, + ASSERT_PRED_FORMAT2(FloatLE, 1.0f, 1.0f); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(FloatLE, values_.close_to_positive_zero, 0.0f); +} + +// Tests the cases where FloatLE() should fail. +TEST_F(FloatTest, FloatLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(FloatLE, 2.0f, 1.0f), + "(2.0f) <= (1.0f)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, values_.further_from_one, 1.0f); + }, "(values_.further_from_one) <= (1.0f)"); + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, -values_.infinity, values_.nan1); + }, "(-values_.infinity) <= (values_.nan1)"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(FloatLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +} + +// Instantiates FloatingPointTest for testing *_DOUBLE_EQ. +typedef FloatingPointTest DoubleTest; + +// Tests that the size of Double::Bits matches the size of double. +TEST_F(DoubleTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(DoubleTest, Zeros) { + EXPECT_DOUBLE_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(0.0, 1.0), + "1.0"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_DOUBLE_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(DoubleTest, AlmostZeros) { + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const DoubleTest::TestValues& v = this->values_; + + EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero); + EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero); + EXPECT_DOUBLE_EQ(v.close_to_positive_zero, v.close_to_negative_zero); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DOUBLE_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); +} + +// Tests comparing numbers close to each other. +TEST_F(DoubleTest, SmallDiff) { + EXPECT_DOUBLE_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); +} + +// Tests comparing numbers far apart. +TEST_F(DoubleTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(2.0, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(DoubleTest, Infinity) { + EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); + + // This is interesting as the representations of infinity_ and nan1_ + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, values_.nan1), + "values_.nan1"); +} + +// Tests that comparing with NAN always returns false. +TEST_F(DoubleTest, NaN) { + static const DoubleTest::TestValues& v = this->values_; + + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity), + "v.infinity"); +} + +// Tests that *_DOUBLE_EQ are reflexive. +TEST_F(DoubleTest, Reflexive) { + EXPECT_DOUBLE_EQ(0.0, 0.0); + EXPECT_DOUBLE_EQ(1.0, 1.0); + ASSERT_DOUBLE_EQ(values_.infinity, values_.infinity); +} + +// Tests that *_DOUBLE_EQ are commutative. +TEST_F(DoubleTest, Commutative) { + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.close_to_one). + EXPECT_DOUBLE_EQ(values_.close_to_one, 1.0); + + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.further_from_one, 1.0), + "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(DoubleTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0, -1.1, 0.2); + EXPECT_NEAR(2.0, 3.0, 1.0); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests ASSERT_NEAR. +TEST_F(DoubleTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0, -1.1, 0.2); + ASSERT_NEAR(2.0, 3.0, 1.0); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests the cases where DoubleLE() should succeed. +TEST_F(DoubleTest, DoubleLESucceeds) { + EXPECT_PRED_FORMAT2(DoubleLE, 1.0, 2.0); // When val1 < val2, + ASSERT_PRED_FORMAT2(DoubleLE, 1.0, 1.0); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(DoubleLE, values_.close_to_positive_zero, 0.0); +} + +// Tests the cases where DoubleLE() should fail. +TEST_F(DoubleTest, DoubleLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(DoubleLE, 2.0, 1.0), + "(2.0) <= (1.0)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, values_.further_from_one, 1.0); + }, "(values_.further_from_one) <= (1.0)"); + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, -values_.infinity, values_.nan1); + }, " (-values_.infinity) <= (values_.nan1)"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +} + + +// Verifies that a test or test case whose name starts with DISABLED_ is +// not run. + +// A test whose name starts with DISABLED_. +// Should not run. +TEST(DisabledTest, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +// A test whose name does not start with DISABLED_. +// Should run. +TEST(DisabledTest, NotDISABLED_TestShouldRun) { + EXPECT_EQ(1, 1); +} + +// A test case whose name starts with DISABLED_. +// Should not run. +TEST(DISABLED_TestSuite, TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// A test case and test whose names start with DISABLED_. +// Should not run. +TEST(DISABLED_TestSuite, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// Check that when all tests in a test case are disabled, SetUpTestSuite() and +// TearDownTestSuite() are not called. +class DisabledTestsTest : public Test { + protected: + static void SetUpTestSuite() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "SetUpTestSuite() should not be called."; + } + + static void TearDownTestSuite() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "TearDownTestSuite() should not be called."; + } +}; + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_1) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +// Tests that disabled typed tests aren't run. + +#if GTEST_HAS_TYPED_TEST + +template +class TypedTest : public Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_SUITE(TypedTest, NumericTypes); + +TYPED_TEST(TypedTest, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +template +class DISABLED_TypedTest : public Test { +}; + +TYPED_TEST_SUITE(DISABLED_TypedTest, NumericTypes); + +TYPED_TEST(DISABLED_TypedTest, ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +#endif // GTEST_HAS_TYPED_TEST + +// Tests that disabled type-parameterized tests aren't run. + +#if GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public Test { +}; + +TYPED_TEST_SUITE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_SUITE_P(TypedTestP, DISABLED_ShouldNotRun); + +INSTANTIATE_TYPED_TEST_SUITE_P(My, TypedTestP, NumericTypes); + +template +class DISABLED_TypedTestP : public Test { +}; + +TYPED_TEST_SUITE_P(DISABLED_TypedTestP); + +TYPED_TEST_P(DISABLED_TypedTestP, ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_SUITE_P(DISABLED_TypedTestP, ShouldNotRun); + +INSTANTIATE_TYPED_TEST_SUITE_P(My, DISABLED_TypedTestP, NumericTypes); + +#endif // GTEST_HAS_TYPED_TEST_P + +// Tests that assertion macros evaluate their arguments exactly once. + +class SingleEvaluationTest : public Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + // This helper function is needed by the FailedASSERT_STREQ test + // below. It's public to work around C++Builder's bug with scoping local + // classes. + static void CompareAndIncrementCharPtrs() { + ASSERT_STREQ(p1_++, p2_++); + } + + // This helper function is needed by the FailedASSERT_NE test below. It's + // public to work around C++Builder's bug with scoping local classes. + static void CompareAndIncrementInts() { + ASSERT_NE(a_++, b_++); + } + + protected: + SingleEvaluationTest() { + p1_ = s1_; + p2_ = s2_; + a_ = 0; + b_ = 0; + } + + static const char* const s1_; + static const char* const s2_; + static const char* p1_; + static const char* p2_; + + static int a_; + static int b_; +}; + +const char* const SingleEvaluationTest::s1_ = "01234"; +const char* const SingleEvaluationTest::s2_ = "abcde"; +const char* SingleEvaluationTest::p1_; +const char* SingleEvaluationTest::p2_; +int SingleEvaluationTest::a_; +int SingleEvaluationTest::b_; + +// Tests that when ASSERT_STREQ fails, it evaluates its arguments +// exactly once. +TEST_F(SingleEvaluationTest, FailedASSERT_STREQ) { + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementCharPtrs(), + "p2_++"); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); +} + +// Tests that string assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ASSERT_STR) { + // successful EXPECT_STRNE + EXPECT_STRNE(p1_++, p2_++); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); + + // failed EXPECT_STRCASEEQ + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ(p1_++, p2_++), + "Ignoring case"); + EXPECT_EQ(s1_ + 2, p1_); + EXPECT_EQ(s2_ + 2, p2_); +} + +// Tests that when ASSERT_NE fails, it evaluates its arguments exactly +// once. +TEST_F(SingleEvaluationTest, FailedASSERT_NE) { + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementInts(), + "(a_++) != (b_++)"); + EXPECT_EQ(1, a_); + EXPECT_EQ(1, b_); +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, OtherCases) { + // successful EXPECT_TRUE + EXPECT_TRUE(0 == a_++); // NOLINT + EXPECT_EQ(1, a_); + + // failed EXPECT_TRUE + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(-1 == a_++), "-1 == a_++"); + EXPECT_EQ(2, a_); + + // successful EXPECT_GT + EXPECT_GT(a_++, b_++); + EXPECT_EQ(3, a_); + EXPECT_EQ(1, b_); + + // failed EXPECT_LT + EXPECT_NONFATAL_FAILURE(EXPECT_LT(a_++, b_++), "(a_++) < (b_++)"); + EXPECT_EQ(4, a_); + EXPECT_EQ(2, b_); + + // successful ASSERT_TRUE + ASSERT_TRUE(0 < a_++); // NOLINT + EXPECT_EQ(5, a_); + + // successful ASSERT_GT + ASSERT_GT(a_++, b_++); + EXPECT_EQ(6, a_); + EXPECT_EQ(3, b_); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowAnInteger() { + throw 1; +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ExceptionTests) { + // successful EXPECT_THROW + EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, int); + EXPECT_EQ(1, a_); + + // failed EXPECT_THROW, throws different + EXPECT_NONFATAL_FAILURE(EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, bool), "throws a different type"); + EXPECT_EQ(2, a_); + + // failed EXPECT_THROW, throws nothing + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(a_++, bool), "throws nothing"); + EXPECT_EQ(3, a_); + + // successful EXPECT_NO_THROW + EXPECT_NO_THROW(a_++); + EXPECT_EQ(4, a_); + + // failed EXPECT_NO_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }), "it throws"); + EXPECT_EQ(5, a_); + + // successful EXPECT_ANY_THROW + EXPECT_ANY_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }); + EXPECT_EQ(6, a_); + + // failed EXPECT_ANY_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(a_++), "it doesn't"); + EXPECT_EQ(7, a_); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests {ASSERT|EXPECT}_NO_FATAL_FAILURE. +class NoFatalFailureTest : public Test { + protected: + void Succeeds() {} + void FailsNonFatal() { + ADD_FAILURE() << "some non-fatal failure"; + } + void Fails() { + FAIL() << "some fatal failure"; + } + + void DoAssertNoFatalFailureOnFails() { + ASSERT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "should not reach here."; + } + + void DoExpectNoFatalFailureOnFails() { + EXPECT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "other failure"; + } +}; + +TEST_F(NoFatalFailureTest, NoFailure) { + EXPECT_NO_FATAL_FAILURE(Succeeds()); + ASSERT_NO_FATAL_FAILURE(Succeeds()); +} + +TEST_F(NoFatalFailureTest, NonFatalIsNoFailure) { + EXPECT_NONFATAL_FAILURE( + EXPECT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); + EXPECT_NONFATAL_FAILURE( + ASSERT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); +} + +TEST_F(NoFatalFailureTest, AssertNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoAssertNoFatalFailureOnFails(); + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); +} + +TEST_F(NoFatalFailureTest, ExpectNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoExpectNoFatalFailureOnFails(); + } + ASSERT_EQ(3, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(2).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "other failure", + gtest_failures.GetTestPartResult(2).message()); +} + +TEST_F(NoFatalFailureTest, MessageIsStreamable) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message"; + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "foo", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "my message", + gtest_failures.GetTestPartResult(1).message()); +} + +// Tests non-string assertions. + +std::string EditsToString(const std::vector& edits) { + std::string out; + for (size_t i = 0; i < edits.size(); ++i) { + static const char kEdits[] = " +-/"; + out.append(1, kEdits[edits[i]]); + } + return out; +} + +std::vector CharsToIndices(const std::string& str) { + std::vector out; + for (size_t i = 0; i < str.size(); ++i) { + out.push_back(static_cast(str[i])); + } + return out; +} + +std::vector CharsToLines(const std::string& str) { + std::vector out; + for (size_t i = 0; i < str.size(); ++i) { + out.push_back(str.substr(i, 1)); + } + return out; +} + +TEST(EditDistance, TestSuites) { + struct Case { + int line; + const char* left; + const char* right; + const char* expected_edits; + const char* expected_diff; + }; + static const Case kCases[] = { + // No change. + {__LINE__, "A", "A", " ", ""}, + {__LINE__, "ABCDE", "ABCDE", " ", ""}, + // Simple adds. + {__LINE__, "X", "XA", " +", "@@ +1,2 @@\n X\n+A\n"}, + {__LINE__, "X", "XABCD", " ++++", "@@ +1,5 @@\n X\n+A\n+B\n+C\n+D\n"}, + // Simple removes. + {__LINE__, "XA", "X", " -", "@@ -1,2 @@\n X\n-A\n"}, + {__LINE__, "XABCD", "X", " ----", "@@ -1,5 @@\n X\n-A\n-B\n-C\n-D\n"}, + // Simple replaces. + {__LINE__, "A", "a", "/", "@@ -1,1 +1,1 @@\n-A\n+a\n"}, + {__LINE__, "ABCD", "abcd", "////", + "@@ -1,4 +1,4 @@\n-A\n-B\n-C\n-D\n+a\n+b\n+c\n+d\n"}, + // Path finding. + {__LINE__, "ABCDEFGH", "ABXEGH1", " -/ - +", + "@@ -1,8 +1,7 @@\n A\n B\n-C\n-D\n+X\n E\n-F\n G\n H\n+1\n"}, + {__LINE__, "AAAABCCCC", "ABABCDCDC", "- / + / ", + "@@ -1,9 +1,9 @@\n-A\n A\n-A\n+B\n A\n B\n C\n+D\n C\n-C\n+D\n C\n"}, + {__LINE__, "ABCDE", "BCDCD", "- +/", + "@@ -1,5 +1,5 @@\n-A\n B\n C\n D\n-E\n+C\n+D\n"}, + {__LINE__, "ABCDEFGHIJKL", "BCDCDEFGJKLJK", "- ++ -- ++", + "@@ -1,4 +1,5 @@\n-A\n B\n+C\n+D\n C\n D\n" + "@@ -6,7 +7,7 @@\n F\n G\n-H\n-I\n J\n K\n L\n+J\n+K\n"}, + {}}; + for (const Case* c = kCases; c->left; ++c) { + EXPECT_TRUE(c->expected_edits == + EditsToString(CalculateOptimalEdits(CharsToIndices(c->left), + CharsToIndices(c->right)))) + << "Left <" << c->left << "> Right <" << c->right << "> Edits <" + << EditsToString(CalculateOptimalEdits( + CharsToIndices(c->left), CharsToIndices(c->right))) << ">"; + EXPECT_TRUE(c->expected_diff == CreateUnifiedDiff(CharsToLines(c->left), + CharsToLines(c->right))) + << "Left <" << c->left << "> Right <" << c->right << "> Diff <" + << CreateUnifiedDiff(CharsToLines(c->left), CharsToLines(c->right)) + << ">"; + } +} + +// Tests EqFailure(), used for implementing *EQ* assertions. +TEST(AssertionTest, EqFailure) { + const std::string foo_val("5"), bar_val("6"); + const std::string msg1( + EqFailure("foo", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Expected equality of these values:\n" + " foo\n" + " Which is: 5\n" + " bar\n" + " Which is: 6", + msg1.c_str()); + + const std::string msg2( + EqFailure("foo", "6", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Expected equality of these values:\n" + " foo\n" + " Which is: 5\n" + " 6", + msg2.c_str()); + + const std::string msg3( + EqFailure("5", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Expected equality of these values:\n" + " 5\n" + " bar\n" + " Which is: 6", + msg3.c_str()); + + const std::string msg4( + EqFailure("5", "6", foo_val, bar_val, false).failure_message()); + EXPECT_STREQ( + "Expected equality of these values:\n" + " 5\n" + " 6", + msg4.c_str()); + + const std::string msg5( + EqFailure("foo", "bar", + std::string("\"x\""), std::string("\"y\""), + true).failure_message()); + EXPECT_STREQ( + "Expected equality of these values:\n" + " foo\n" + " Which is: \"x\"\n" + " bar\n" + " Which is: \"y\"\n" + "Ignoring case", + msg5.c_str()); +} + +TEST(AssertionTest, EqFailureWithDiff) { + const std::string left( + "1\\n2XXX\\n3\\n5\\n6\\n7\\n8\\n9\\n10\\n11\\n12XXX\\n13\\n14\\n15"); + const std::string right( + "1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9\\n11\\n12\\n13\\n14"); + const std::string msg1( + EqFailure("left", "right", left, right, false).failure_message()); + EXPECT_STREQ( + "Expected equality of these values:\n" + " left\n" + " Which is: " + "1\\n2XXX\\n3\\n5\\n6\\n7\\n8\\n9\\n10\\n11\\n12XXX\\n13\\n14\\n15\n" + " right\n" + " Which is: 1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9\\n11\\n12\\n13\\n14\n" + "With diff:\n@@ -1,5 +1,6 @@\n 1\n-2XXX\n+2\n 3\n+4\n 5\n 6\n" + "@@ -7,8 +8,6 @@\n 8\n 9\n-10\n 11\n-12XXX\n+12\n 13\n 14\n-15\n", + msg1.c_str()); +} + +// Tests AppendUserMessage(), used for implementing the *EQ* macros. +TEST(AssertionTest, AppendUserMessage) { + const std::string foo("foo"); + + Message msg; + EXPECT_STREQ("foo", + AppendUserMessage(foo, msg).c_str()); + + msg << "bar"; + EXPECT_STREQ("foo\nbar", + AppendUserMessage(foo, msg).c_str()); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +// Tests ASSERT_TRUE. +TEST(AssertionTest, ASSERT_TRUE) { + ASSERT_TRUE(2 > 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_TRUE(2 < 1), + "2 < 1"); +} + +// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertTrueWithAssertionResult) { + ASSERT_TRUE(ResultIsEven(2)); +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +#endif + ASSERT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + +// Tests ASSERT_FALSE. +TEST(AssertionTest, ASSERT_FALSE) { + ASSERT_FALSE(2 < 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); +} + +// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertFalseWithAssertionResult) { + ASSERT_FALSE(ResultIsEven(3)); +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); +#endif + ASSERT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them +# pragma option pop +#endif + +// Tests using ASSERT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, ASSERT_EQ_Double) { + // A success. + ASSERT_EQ(5.6, 5.6); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(5.1, 5.2), + "5.1"); +} + +// Tests ASSERT_EQ. +TEST(AssertionTest, ASSERT_EQ) { + ASSERT_EQ(5, 2 + 3); + EXPECT_FATAL_FAILURE(ASSERT_EQ(5, 2*3), + "Expected equality of these values:\n" + " 5\n" + " 2*3\n" + " Which is: 6"); +} + +// Tests ASSERT_EQ(NULL, pointer). +TEST(AssertionTest, ASSERT_EQ_NULL) { + // A success. + const char* p = nullptr; + // Some older GCC versions may issue a spurious warning in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. + ASSERT_EQ(nullptr, p); + + // A failure. + static int n = 0; + EXPECT_FATAL_FAILURE(ASSERT_EQ(nullptr, &n), " &n\n Which is:"); +} + +// Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that ASSERT_EQ(0, non_pointer) isn't interpreted by Google Test as +// ASSERT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, ASSERT_EQ_0) { + int n = 0; + + // A success. + ASSERT_EQ(0, n); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(0, 5.6), + " 0\n 5.6"); +} + +// Tests ASSERT_NE. +TEST(AssertionTest, ASSERT_NE) { + ASSERT_NE(6, 7); + EXPECT_FATAL_FAILURE(ASSERT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); +} + +// Tests ASSERT_LE. +TEST(AssertionTest, ASSERT_LE) { + ASSERT_LE(2, 3); + ASSERT_LE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); +} + +// Tests ASSERT_LT. +TEST(AssertionTest, ASSERT_LT) { + ASSERT_LT(2, 3); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); +} + +// Tests ASSERT_GE. +TEST(AssertionTest, ASSERT_GE) { + ASSERT_GE(2, 1); + ASSERT_GE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); +} + +// Tests ASSERT_GT. +TEST(AssertionTest, ASSERT_GT) { + ASSERT_GT(2, 1); + EXPECT_FATAL_FAILURE(ASSERT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowNothing() {} + +// Tests ASSERT_THROW. +TEST(AssertionTest, ASSERT_THROW) { + ASSERT_THROW(ThrowAnInteger(), int); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of type bool.\n" + " Actual: it throws a different type."); +# endif + + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); +} + +// Tests ASSERT_NO_THROW. +TEST(AssertionTest, ASSERT_NO_THROW) { + ASSERT_NO_THROW(ThrowNothing()); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an exception." + "\n Actual: it throws."); +} + +// Tests ASSERT_ANY_THROW. +TEST(AssertionTest, ASSERT_ANY_THROW) { + ASSERT_ANY_THROW(ThrowAnInteger()); + EXPECT_FATAL_FAILURE( + ASSERT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Makes sure we deal with the precedence of <<. This test should +// compile. +TEST(AssertionTest, AssertPrecedence) { + ASSERT_EQ(1 < 2, true); + bool false_value = false; + ASSERT_EQ(true && false_value, false); +} + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// Tests calling a test subroutine that's not part of a fixture. +TEST(AssertionTest, NonFixtureSubroutine) { + EXPECT_FATAL_FAILURE(TestEq1(2), + " x\n Which is: 2"); +} + +// An uncopyable class. +class Uncopyable { + public: + explicit Uncopyable(int a_value) : value_(a_value) {} + + int value() const { return value_; } + bool operator==(const Uncopyable& rhs) const { + return value() == rhs.value(); + } + private: + // This constructor deliberately has no implementation, as we don't + // want this class to be copyable. + Uncopyable(const Uncopyable&); // NOLINT + + int value_; +}; + +::std::ostream& operator<<(::std::ostream& os, const Uncopyable& value) { + return os << value.value(); +} + + +bool IsPositiveUncopyable(const Uncopyable& x) { + return x.value() > 0; +} + +// A subroutine used by the following test. +void TestAssertNonPositive() { + Uncopyable y(-1); + ASSERT_PRED1(IsPositiveUncopyable, y); +} +// A subroutine used by the following test. +void TestAssertEqualsUncopyable() { + Uncopyable x(5); + Uncopyable y(-1); + ASSERT_EQ(x, y); +} + +// Tests that uncopyable objects can be used in assertions. +TEST(AssertionTest, AssertWorksWithUncopyableObject) { + Uncopyable x(5); + ASSERT_PRED1(IsPositiveUncopyable, x); + ASSERT_EQ(x, x); + EXPECT_FATAL_FAILURE(TestAssertNonPositive(), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_FATAL_FAILURE(TestAssertEqualsUncopyable(), + "Expected equality of these values:\n" + " x\n Which is: 5\n y\n Which is: -1"); +} + +// Tests that uncopyable objects can be used in expects. +TEST(AssertionTest, ExpectWorksWithUncopyableObject) { + Uncopyable x(5); + EXPECT_PRED1(IsPositiveUncopyable, x); + Uncopyable y(-1); + EXPECT_NONFATAL_FAILURE(EXPECT_PRED1(IsPositiveUncopyable, y), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_EQ(x, x); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), + "Expected equality of these values:\n" + " x\n Which is: 5\n y\n Which is: -1"); +} + +enum NamedEnum { + kE1 = 0, + kE2 = 1 +}; + +TEST(AssertionTest, NamedEnum) { + EXPECT_EQ(kE1, kE1); + EXPECT_LT(kE1, kE2); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Which is: 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Which is: 1"); +} + +// Sun Studio and HP aCC2reject this code. +#if !defined(__SUNPRO_CC) && !defined(__HP_aCC) + +// Tests using assertions with anonymous enums. +enum { + kCaseA = -1, + +# if GTEST_OS_LINUX + + // We want to test the case where the size of the anonymous enum is + // larger than sizeof(int), to make sure our implementation of the + // assertions doesn't truncate the enums. However, MSVC + // (incorrectly) doesn't allow an enum value to exceed the range of + // an int, so this has to be conditionally compiled. + // + // On Linux, kCaseB and kCaseA have the same value when truncated to + // int size. We want to test whether this will confuse the + // assertions. + kCaseB = testing::internal::kMaxBiggestInt, + +# else + + kCaseB = INT_MAX, + +# endif // GTEST_OS_LINUX + + kCaseC = 42 +}; + +TEST(AssertionTest, AnonymousEnum) { +# if GTEST_OS_LINUX + + EXPECT_EQ(static_cast(kCaseA), static_cast(kCaseB)); + +# endif // GTEST_OS_LINUX + + EXPECT_EQ(kCaseA, kCaseA); + EXPECT_NE(kCaseA, kCaseB); + EXPECT_LT(kCaseA, kCaseB); + EXPECT_LE(kCaseA, kCaseB); + EXPECT_GT(kCaseB, kCaseA); + EXPECT_GE(kCaseA, kCaseA); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseB), + "(kCaseA) >= (kCaseB)"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseC), + "-1 vs 42"); + + ASSERT_EQ(kCaseA, kCaseA); + ASSERT_NE(kCaseA, kCaseB); + ASSERT_LT(kCaseA, kCaseB); + ASSERT_LE(kCaseA, kCaseB); + ASSERT_GT(kCaseB, kCaseA); + ASSERT_GE(kCaseA, kCaseA); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), + " kCaseB\n Which is: "); + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "\n Which is: 42"); +# endif + + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "\n Which is: -1"); +} + +#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC) + +#if GTEST_OS_WINDOWS + +static HRESULT UnexpectedHRESULTFailure() { + return E_UNEXPECTED; +} + +static HRESULT OkHRESULTSuccess() { + return S_OK; +} + +static HRESULT FalseHRESULTSuccess() { + return S_FALSE; +} + +// HRESULT assertion tests test both zero and non-zero +// success codes as well as failure message for each. +// +// Windows CE doesn't support message texts. +TEST(HRESULTAssertionTest, EXPECT_HRESULT_SUCCEEDED) { + EXPECT_HRESULT_SUCCEEDED(S_OK); + EXPECT_HRESULT_SUCCEEDED(S_FALSE); + + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_SUCCEEDED) { + ASSERT_HRESULT_SUCCEEDED(S_OK); + ASSERT_HRESULT_SUCCEEDED(S_FALSE); + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); +} + +TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { + EXPECT_HRESULT_FAILED(E_UNEXPECTED); + + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()), + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x0"); + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()), + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x1"); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { + ASSERT_HRESULT_FAILED(E_UNEXPECTED); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x0"); +# endif + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x1"); +} + +// Tests that streaming to the HRESULT macros works. +TEST(HRESULTAssertionTest, Streaming) { + EXPECT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + ASSERT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + EXPECT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + ASSERT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); +# endif + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); + + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); +} + +#endif // GTEST_OS_WINDOWS + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +// Tests that the assertion macros behave like single statements. +TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + ASSERT_TRUE(false) << "This should never be executed; " + "It's a compilation test only."; + + if (AlwaysTrue()) + EXPECT_FALSE(false); + else + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_LT(1, 3); + + if (AlwaysFalse()) + ; // NOLINT + else + EXPECT_GT(3, 2) << ""; +} + +#if GTEST_HAS_EXCEPTIONS +// Tests that the compiler will not complain about unreachable code in the +// EXPECT_THROW/EXPECT_ANY_THROW/EXPECT_NO_THROW macros. +TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { + int n = 0; + + EXPECT_THROW(throw 1, int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(n++, int), ""); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(throw 1, const char*), ""); + EXPECT_NO_THROW(n++); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(throw 1), ""); + EXPECT_ANY_THROW(throw 1); + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(n++), ""); +} + +TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + EXPECT_THROW(ThrowNothing(), bool); + + if (AlwaysTrue()) + EXPECT_THROW(ThrowAnInteger(), int); + else + ; // NOLINT + + if (AlwaysFalse()) + EXPECT_NO_THROW(ThrowAnInteger()); + + if (AlwaysTrue()) + EXPECT_NO_THROW(ThrowNothing()); + else + ; // NOLINT + + if (AlwaysFalse()) + EXPECT_ANY_THROW(ThrowNothing()); + + if (AlwaysTrue()) + EXPECT_ANY_THROW(ThrowAnInteger()); + else + ; // NOLINT +} +#endif // GTEST_HAS_EXCEPTIONS + +TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. " + << "It's a compilation test only."; + else + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_NO_FATAL_FAILURE(FAIL()) << ""; + else + ; // NOLINT + + if (AlwaysTrue()) + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + else + ; // NOLINT + + if (AlwaysFalse()) + ; // NOLINT + else + ASSERT_NO_FATAL_FAILURE(SUCCEED()); +} + +// Tests that the assertion macros work well with switch statements. +TEST(AssertionSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + ASSERT_TRUE(true); + } + + switch (0) + case 0: + EXPECT_FALSE(false) << "EXPECT_FALSE failed in switch case"; + + // Binary assertions are implemented using a different code path + // than the Boolean assertions. Hence we test them separately. + switch (0) { + case 1: + default: + ASSERT_EQ(1, 1) << "ASSERT_EQ failed in default switch handler"; + } + + switch (0) + case 0: + EXPECT_NE(1, 2); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowAString() { + throw "std::string"; +} + +// Test that the exception assertion macros compile and work with const +// type qualifier. +TEST(AssertionSyntaxTest, WorksWithConst) { + ASSERT_THROW(ThrowAString(), const char*); + + EXPECT_THROW(ThrowAString(), const char*); +} + +#endif // GTEST_HAS_EXCEPTIONS + +} // namespace + +namespace testing { + +// Tests that Google Test tracks SUCCEED*. +TEST(SuccessfulAssertionTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "OK"; + EXPECT_EQ(2, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful EXPECT_*. +TEST(SuccessfulAssertionTest, EXPECT) { + EXPECT_TRUE(true); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful EXPECT_STR*. +TEST(SuccessfulAssertionTest, EXPECT_STR) { + EXPECT_STREQ("", ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful ASSERT_*. +TEST(SuccessfulAssertionTest, ASSERT) { + ASSERT_TRUE(true); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful ASSERT_STR*. +TEST(SuccessfulAssertionTest, ASSERT_STR) { + ASSERT_STREQ("", ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +} // namespace testing + +namespace { + +// Tests the message streaming variation of assertions. + +TEST(AssertionWithMessageTest, EXPECT) { + EXPECT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(1, 1) << "Expected failure #1.", + "Expected failure #1"); + EXPECT_LE(1, 2) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(1, 0) << "Expected failure #2.", + "Expected failure #2."); + EXPECT_GE(1, 0) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_GT(1, 2) << "Expected failure #3.", + "Expected failure #3."); + + EXPECT_STREQ("1", "1") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("1", "1") << "Expected failure #4.", + "Expected failure #4."); + EXPECT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("a", "A") << "Expected failure #5.", + "Expected failure #5."); + + EXPECT_FLOAT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1, 1.2) << "Expected failure #6.", + "Expected failure #6."); + EXPECT_NEAR(1, 1.1, 0.2) << "This should succeed."; +} + +TEST(AssertionWithMessageTest, ASSERT) { + ASSERT_EQ(1, 1) << "This should succeed."; + ASSERT_NE(1, 2) << "This should succeed."; + ASSERT_LE(1, 2) << "This should succeed."; + ASSERT_LT(1, 2) << "This should succeed."; + ASSERT_GE(1, 0) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_GT(1, 2) << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_STR) { + ASSERT_STREQ("1", "1") << "This should succeed."; + ASSERT_STRNE("1", "2") << "This should succeed."; + ASSERT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("a", "A") << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_FLOATING) { + ASSERT_FLOAT_EQ(1, 1) << "This should succeed."; + ASSERT_DOUBLE_EQ(1, 1) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1,1.2, 0.1) << "Expect failure.", // NOLINT + "Expect failure."); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests using ASSERT_FALSE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_FALSE) { + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FALSE(true) << "Expected failure: " << 2 << " > " << 1 + << " evaluates to " << true; + }, "Expected failure"); +} + +// Tests using FAIL with a streamed message. +TEST(AssertionWithMessageTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL() << 0, + "0"); +} + +// Tests using SUCCEED with a streamed message. +TEST(AssertionWithMessageTest, SUCCEED) { + SUCCEED() << "Success == " << 1; +} + +// Tests using ASSERT_TRUE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_TRUE) { + ASSERT_TRUE(true) << "This should succeed."; + ASSERT_TRUE(true) << true; + EXPECT_FATAL_FAILURE( + { // NOLINT + ASSERT_TRUE(false) << static_cast(nullptr) + << static_cast(nullptr); + }, + "(null)(null)"); +} + +#if GTEST_OS_WINDOWS +// Tests using wide strings in assertion messages. +TEST(AssertionWithMessageTest, WideStringMessage) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_TRUE(false) << L"This failure is expected.\x8119"; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(1, 2) << "This failure is " + << L"expected too.\x8120"; + }, "This failure is expected too."); +} +#endif // GTEST_OS_WINDOWS + +// Tests EXPECT_TRUE. +TEST(ExpectTest, EXPECT_TRUE) { + EXPECT_TRUE(true) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #2.", + "Intentional failure #2."); + EXPECT_TRUE(2 > 1); // NOLINT + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1), + "Value of: 2 < 1\n" + " Actual: false\n" + "Expected: true"); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 > 3), + "2 > 3"); +} + +// Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectTrueWithAssertionResult) { + EXPECT_TRUE(ResultIsEven(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); + EXPECT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + +// Tests EXPECT_FALSE with a streamed message. +TEST(ExpectTest, EXPECT_FALSE) { + EXPECT_FALSE(2 < 1); // NOLINT + EXPECT_FALSE(false) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #2.", + "Intentional failure #2."); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 < 3), + "2 < 3"); +} + +// Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectFalseWithAssertionResult) { + EXPECT_FALSE(ResultIsEven(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); + EXPECT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them +# pragma option pop +#endif + +// Tests EXPECT_EQ. +TEST(ExpectTest, EXPECT_EQ) { + EXPECT_EQ(5, 2 + 3); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2*3), + "Expected equality of these values:\n" + " 5\n" + " 2*3\n" + " Which is: 6"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2 - 3), + "2 - 3"); +} + +// Tests using EXPECT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, EXPECT_EQ_Double) { + // A success. + EXPECT_EQ(5.6, 5.6); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5.1, 5.2), + "5.1"); +} + +// Tests EXPECT_EQ(NULL, pointer). +TEST(ExpectTest, EXPECT_EQ_NULL) { + // A success. + const char* p = nullptr; + // Some older GCC versions may issue a spurious warning in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. + EXPECT_EQ(nullptr, p); + + // A failure. + int n = 0; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(nullptr, &n), " &n\n Which is:"); +} + +// Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that EXPECT_EQ(0, non_pointer) isn't interpreted by Google Test as +// EXPECT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, EXPECT_EQ_0) { + int n = 0; + + // A success. + EXPECT_EQ(0, n); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6), + " 0\n 5.6"); +} + +// Tests EXPECT_NE. +TEST(ExpectTest, EXPECT_NE) { + EXPECT_NE(6, 7); + + EXPECT_NONFATAL_FAILURE(EXPECT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(2, 2), + "2"); + char* const p0 = nullptr; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p0, p0), + "p0"); + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + char* const p1 = reinterpret_cast(pv1); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p1, p1), + "p1"); +} + +// Tests EXPECT_LE. +TEST(ExpectTest, EXPECT_LE) { + EXPECT_LE(2, 3); + EXPECT_LE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(1.1, 0.9), + "(1.1) <= (0.9)"); +} + +// Tests EXPECT_LT. +TEST(ExpectTest, EXPECT_LT) { + EXPECT_LT(2, 3); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1), + "(2) < (1)"); +} + +// Tests EXPECT_GE. +TEST(ExpectTest, EXPECT_GE) { + EXPECT_GE(2, 1); + EXPECT_GE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(0.9, 1.1), + "(0.9) >= (1.1)"); +} + +// Tests EXPECT_GT. +TEST(ExpectTest, EXPECT_GT) { + EXPECT_GT(2, 1); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 3), + "(2) > (3)"); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests EXPECT_THROW. +TEST(ExpectTest, EXPECT_THROW) { + EXPECT_THROW(ThrowAnInteger(), int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of " + "type bool.\n Actual: it throws a different type."); + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); +} + +// Tests EXPECT_NO_THROW. +TEST(ExpectTest, EXPECT_NO_THROW) { + EXPECT_NO_THROW(ThrowNothing()); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an " + "exception.\n Actual: it throws."); +} + +// Tests EXPECT_ANY_THROW. +TEST(ExpectTest, EXPECT_ANY_THROW) { + EXPECT_ANY_THROW(ThrowAnInteger()); + EXPECT_NONFATAL_FAILURE( + EXPECT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Make sure we deal with the precedence of <<. +TEST(ExpectTest, ExpectPrecedence) { + EXPECT_EQ(1 < 2, true); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false), + " true && false\n Which is: false"); +} + + +// Tests the StreamableToString() function. + +// Tests using StreamableToString() on a scalar. +TEST(StreamableToStringTest, Scalar) { + EXPECT_STREQ("5", StreamableToString(5).c_str()); +} + +// Tests using StreamableToString() on a non-char pointer. +TEST(StreamableToStringTest, Pointer) { + int n = 0; + int* p = &n; + EXPECT_STRNE("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a NULL non-char pointer. +TEST(StreamableToStringTest, NullPointer) { + int* p = nullptr; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a C string. +TEST(StreamableToStringTest, CString) { + EXPECT_STREQ("Foo", StreamableToString("Foo").c_str()); +} + +// Tests using StreamableToString() on a NULL C string. +TEST(StreamableToStringTest, NullCString) { + char* p = nullptr; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using streamable values as assertion messages. + +// Tests using std::string as an assertion message. +TEST(StreamableTest, string) { + static const std::string str( + "This failure message is a std::string, and is expected."); + EXPECT_FATAL_FAILURE(FAIL() << str, + str.c_str()); +} + +// Tests that we can output strings containing embedded NULs. +// Limited to Linux because we can only do this with std::string's. +TEST(StreamableTest, stringWithEmbeddedNUL) { + static const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + static const std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) + - 1); // drops the trailing NUL + EXPECT_FATAL_FAILURE(FAIL() << string_with_nul, + "Here's a NUL\\0 and some more string"); +} + +// Tests that we can output a NUL char. +TEST(StreamableTest, NULChar) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "A NUL" << '\0' << " and some more string"; + }, "A NUL\\0 and some more string"); +} + +// Tests using int as an assertion message. +TEST(StreamableTest, int) { + EXPECT_FATAL_FAILURE(FAIL() << 900913, + "900913"); +} + +// Tests using NULL char pointer as an assertion message. +// +// In MSVC, streaming a NULL char * causes access violation. Google Test +// implemented a workaround (substituting "(null)" for NULL). This +// tests whether the workaround works. +TEST(StreamableTest, NullCharPtr) { + EXPECT_FATAL_FAILURE(FAIL() << static_cast(nullptr), "(null)"); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to testing::Message. +TEST(StreamableTest, BasicIoManip) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush << " in line 2."; + }, "Line 1.\nA NUL char \\0 in line 2."); +} + +// Tests the macros that haven't been covered so far. + +void AddFailureHelper(bool* aborted) { + *aborted = true; + ADD_FAILURE() << "Intentional failure."; + *aborted = false; +} + +// Tests ADD_FAILURE. +TEST(MacroTest, ADD_FAILURE) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted), + "Intentional failure."); + EXPECT_FALSE(aborted); +} + +// Tests ADD_FAILURE_AT. +TEST(MacroTest, ADD_FAILURE_AT) { + // Verifies that ADD_FAILURE_AT does generate a nonfatal failure and + // the failure message contains the user-streamed part. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42) << "Wrong!", "Wrong!"); + + // Verifies that the user-streamed part is optional. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42), "Failed"); + + // Unfortunately, we cannot verify that the failure message contains + // the right file path and line number the same way, as + // EXPECT_NONFATAL_FAILURE() doesn't get to see the file path and + // line number. Instead, we do that in googletest-output-test_.cc. +} + +// Tests FAIL. +TEST(MacroTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL(), + "Failed"); + EXPECT_FATAL_FAILURE(FAIL() << "Intentional failure.", + "Intentional failure."); +} + +// Tests GTEST_FAIL_AT. +TEST(MacroTest, GTEST_FAIL_AT) { + // Verifies that GTEST_FAIL_AT does generate a fatal failure and + // the failure message contains the user-streamed part. + EXPECT_FATAL_FAILURE(GTEST_FAIL_AT("foo.cc", 42) << "Wrong!", "Wrong!"); + + // Verifies that the user-streamed part is optional. + EXPECT_FATAL_FAILURE(GTEST_FAIL_AT("foo.cc", 42), "Failed"); + + // See the ADD_FAIL_AT test above to see how we test that the failure message + // contains the right filename and line number -- the same applies here. +} + +// Tests SUCCEED +TEST(MacroTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "Explicit success."; +} + +// Tests for EXPECT_EQ() and ASSERT_EQ(). +// +// These tests fail *intentionally*, s.t. the failure messages can be +// generated and tested. +// +// We have different tests for different argument types. + +// Tests using bool values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Bool) { + EXPECT_EQ(true, true); + EXPECT_FATAL_FAILURE({ + bool false_value = false; + ASSERT_EQ(false_value, true); + }, " false_value\n Which is: false\n true"); +} + +// Tests using int values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Int) { + ASSERT_EQ(32, 32); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33), + " 32\n 33"); +} + +// Tests using time_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Time_T) { + EXPECT_EQ(static_cast(0), + static_cast(0)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0), + static_cast(1234)), + "1234"); +} + +// Tests using char values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Char) { + ASSERT_EQ('z', 'z'); + const char ch = 'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch), + " ch\n Which is: 'b'"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch), + " ch\n Which is: 'b'"); +} + +// Tests using wchar_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideChar) { + EXPECT_EQ(L'b', L'b'); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'\0', L'x'), + "Expected equality of these values:\n" + " L'\0'\n" + " Which is: L'\0' (0, 0x0)\n" + " L'x'\n" + " Which is: L'x' (120, 0x78)"); + + static wchar_t wchar; + wchar = L'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'a', wchar), + "wchar"); + wchar = 0x8119; + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0x8120), wchar), + " wchar\n Which is: L'"); +} + +// Tests using ::std::string values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdString) { + // Compares a const char* to an std::string that has identical + // content. + ASSERT_EQ("Test", ::std::string("Test")); + + // Compares two identical std::strings. + static const ::std::string str1("A * in the middle"); + static const ::std::string str2(str1); + EXPECT_EQ(str1, str2); + + // Compares a const char* to an std::string that has different + // content + EXPECT_NONFATAL_FAILURE(EXPECT_EQ("Test", ::std::string("test")), + "\"test\""); + + // Compares an std::string to a char* that has different content. + char* const p1 = const_cast("foo"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::std::string("bar"), p1), + "p1"); + + // Compares two std::strings that have different contents, one of + // which having a NUL character in the middle. This should fail. + static ::std::string str3(str1); + str3.at(2) = '\0'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3), + " str3\n Which is: \"A \\0 in the middle\""); +} + +#if GTEST_HAS_STD_WSTRING + +// Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdWideString) { + // Compares two identical std::wstrings. + const ::std::wstring wstr1(L"A * in the middle"); + const ::std::wstring wstr2(wstr1); + ASSERT_EQ(wstr1, wstr2); + + // Compares an std::wstring to a const wchar_t* that has identical + // content. + const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8119); + + // Compares an std::wstring to a const wchar_t* that has different + // content. + const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8120); + }, "kTestX8120"); + + // Compares two std::wstrings that have different contents, one of + // which having a NUL character in the middle. + ::std::wstring wstr3(wstr1); + wstr3.at(2) = L'\0'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(wstr1, wstr3), + "wstr3"); + + // Compares a wchar_t* to an std::wstring that has different + // content. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(const_cast(L"foo"), ::std::wstring(L"bar")); + }, ""); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests using char pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, CharPointer) { + char* const p0 = nullptr; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + char* const p1 = reinterpret_cast(pv1); + char* const p2 = reinterpret_cast(pv2); + ASSERT_EQ(p1, p1); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + " p2\n Which is:"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + " p2\n Which is:"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast(0x1234), + reinterpret_cast(0xABC0)), + "ABC0"); +} + +// Tests using wchar_t pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideCharPointer) { + wchar_t* const p0 = nullptr; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + wchar_t* const p1 = reinterpret_cast(pv1); + wchar_t* const p2 = reinterpret_cast(pv2); + EXPECT_EQ(p0, p0); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + " p2\n Which is:"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + " p2\n Which is:"); + void* pv3 = (void*)0x1234; // NOLINT + void* pv4 = (void*)0xABC0; // NOLINT + const wchar_t* p3 = reinterpret_cast(pv3); + const wchar_t* p4 = reinterpret_cast(pv4); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p3, p4), + "p4"); +} + +// Tests using other types of pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, OtherPointer) { + ASSERT_EQ(static_cast(nullptr), static_cast(nullptr)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(nullptr), + reinterpret_cast(0x1234)), + "0x1234"); +} + +// A class that supports binary comparison operators but not streaming. +class UnprintableChar { + public: + explicit UnprintableChar(char ch) : char_(ch) {} + + bool operator==(const UnprintableChar& rhs) const { + return char_ == rhs.char_; + } + bool operator!=(const UnprintableChar& rhs) const { + return char_ != rhs.char_; + } + bool operator<(const UnprintableChar& rhs) const { + return char_ < rhs.char_; + } + bool operator<=(const UnprintableChar& rhs) const { + return char_ <= rhs.char_; + } + bool operator>(const UnprintableChar& rhs) const { + return char_ > rhs.char_; + } + bool operator>=(const UnprintableChar& rhs) const { + return char_ >= rhs.char_; + } + + private: + char char_; +}; + +// Tests that ASSERT_EQ() and friends don't require the arguments to +// be printable. +TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) { + const UnprintableChar x('x'), y('y'); + ASSERT_EQ(x, x); + EXPECT_NE(x, y); + ASSERT_LT(x, y); + EXPECT_LE(x, y); + ASSERT_GT(y, x); + EXPECT_GE(x, x); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(y, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <79>"); + + // Code tested by EXPECT_FATAL_FAILURE cannot reference local + // variables, so we have to write UnprintableChar('x') instead of x. +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <78>"); +#endif + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <79>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <79>"); +} + +// Tests the FRIEND_TEST macro. + +// This class has a private member we want to test. We will test it +// both in a TEST and in a TEST_F. +class Foo { + public: + Foo() {} + + private: + int Bar() const { return 1; } + + // Declares the friend tests that can access the private member + // Bar(). + FRIEND_TEST(FRIEND_TEST_Test, TEST); + FRIEND_TEST(FRIEND_TEST_Test2, TEST_F); +}; + +// Tests that the FRIEND_TEST declaration allows a TEST to access a +// class's private members. This should compile. +TEST(FRIEND_TEST_Test, TEST) { + ASSERT_EQ(1, Foo().Bar()); +} + +// The fixture needed to test using FRIEND_TEST with TEST_F. +class FRIEND_TEST_Test2 : public Test { + protected: + Foo foo; +}; + +// Tests that the FRIEND_TEST declaration allows a TEST_F to access a +// class's private members. This should compile. +TEST_F(FRIEND_TEST_Test2, TEST_F) { + ASSERT_EQ(1, foo.Bar()); +} + +// Tests the life cycle of Test objects. + +// The test fixture for testing the life cycle of Test objects. +// +// This class counts the number of live test objects that uses this +// fixture. +class TestLifeCycleTest : public Test { + protected: + // Constructor. Increments the number of test objects that uses + // this fixture. + TestLifeCycleTest() { count_++; } + + // Destructor. Decrements the number of test objects that uses this + // fixture. + ~TestLifeCycleTest() override { count_--; } + + // Returns the number of live test objects that uses this fixture. + int count() const { return count_; } + + private: + static int count_; +}; + +int TestLifeCycleTest::count_ = 0; + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test1) { + // There should be only one test object in this test case that's + // currently alive. + ASSERT_EQ(1, count()); +} + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test2) { + // After Test1 is done and Test2 is started, there should still be + // only one live test object, as the object for Test1 should've been + // deleted. + ASSERT_EQ(1, count()); +} + +} // namespace + +// Tests that the copy constructor works when it is NOT optimized away by +// the compiler. +TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) { + // Checks that the copy constructor doesn't try to dereference NULL pointers + // in the source object. + AssertionResult r1 = AssertionSuccess(); + AssertionResult r2 = r1; + // The following line is added to prevent the compiler from optimizing + // away the constructor call. + r1 << "abc"; + + AssertionResult r3 = r1; + EXPECT_EQ(static_cast(r3), static_cast(r1)); + EXPECT_STREQ("abc", r1.message()); +} + +// Tests that AssertionSuccess and AssertionFailure construct +// AssertionResult objects as expected. +TEST(AssertionResultTest, ConstructionWorks) { + AssertionResult r1 = AssertionSuccess(); + EXPECT_TRUE(r1); + EXPECT_STREQ("", r1.message()); + + AssertionResult r2 = AssertionSuccess() << "abc"; + EXPECT_TRUE(r2); + EXPECT_STREQ("abc", r2.message()); + + AssertionResult r3 = AssertionFailure(); + EXPECT_FALSE(r3); + EXPECT_STREQ("", r3.message()); + + AssertionResult r4 = AssertionFailure() << "def"; + EXPECT_FALSE(r4); + EXPECT_STREQ("def", r4.message()); + + AssertionResult r5 = AssertionFailure(Message() << "ghi"); + EXPECT_FALSE(r5); + EXPECT_STREQ("ghi", r5.message()); +} + +// Tests that the negation flips the predicate result but keeps the message. +TEST(AssertionResultTest, NegationWorks) { + AssertionResult r1 = AssertionSuccess() << "abc"; + EXPECT_FALSE(!r1); + EXPECT_STREQ("abc", (!r1).message()); + + AssertionResult r2 = AssertionFailure() << "def"; + EXPECT_TRUE(!r2); + EXPECT_STREQ("def", (!r2).message()); +} + +TEST(AssertionResultTest, StreamingWorks) { + AssertionResult r = AssertionSuccess(); + r << "abc" << 'd' << 0 << true; + EXPECT_STREQ("abcd0true", r.message()); +} + +TEST(AssertionResultTest, CanStreamOstreamManipulators) { + AssertionResult r = AssertionSuccess(); + r << "Data" << std::endl << std::flush << std::ends << "Will be visible"; + EXPECT_STREQ("Data\n\\0Will be visible", r.message()); +} + +// The next test uses explicit conversion operators + +TEST(AssertionResultTest, ConstructibleFromContextuallyConvertibleToBool) { + struct ExplicitlyConvertibleToBool { + explicit operator bool() const { return value; } + bool value; + }; + ExplicitlyConvertibleToBool v1 = {false}; + ExplicitlyConvertibleToBool v2 = {true}; + EXPECT_FALSE(v1); + EXPECT_TRUE(v2); +} + +struct ConvertibleToAssertionResult { + operator AssertionResult() const { return AssertionResult(true); } +}; + +TEST(AssertionResultTest, ConstructibleFromImplicitlyConvertible) { + ConvertibleToAssertionResult obj; + EXPECT_TRUE(obj); +} + +// Tests streaming a user type whose definition and operator << are +// both in the global namespace. +class Base { + public: + explicit Base(int an_x) : x_(an_x) {} + int x() const { return x_; } + private: + int x_; +}; +std::ostream& operator<<(std::ostream& os, + const Base& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const Base* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) { + Message msg; + Base a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in an unnamed namespace. +namespace { +class MyTypeInUnnamedNameSpace : public Base { + public: + explicit MyTypeInUnnamedNameSpace(int an_x): Base(an_x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace + +TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) { + Message msg; + MyTypeInUnnamedNameSpace a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in a user namespace. +namespace namespace1 { +class MyTypeInNameSpace1 : public Base { + public: + explicit MyTypeInNameSpace1(int an_x): Base(an_x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace namespace1 + +TEST(MessageTest, CanStreamUserTypeInUserNameSpace) { + Message msg; + namespace1::MyTypeInNameSpace1 a(1); + + msg << a << &a; // Uses namespace1::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition is in a user namespace +// but whose operator<< is in the global namespace. +namespace namespace2 { +class MyTypeInNameSpace2 : public ::Base { + public: + explicit MyTypeInNameSpace2(int an_x): Base(an_x) {} +}; +} // namespace namespace2 +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInUserNameSpaceWithStreamOperatorInGlobal) { + Message msg; + namespace2::MyTypeInNameSpace2 a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming NULL pointers to testing::Message. +TEST(MessageTest, NullPointers) { + Message msg; + char* const p1 = nullptr; + unsigned char* const p2 = nullptr; + int* p3 = nullptr; + double* p4 = nullptr; + bool* p5 = nullptr; + Message* p6 = nullptr; + + msg << p1 << p2 << p3 << p4 << p5 << p6; + ASSERT_STREQ("(null)(null)(null)(null)(null)(null)", + msg.GetString().c_str()); +} + +// Tests streaming wide strings to testing::Message. +TEST(MessageTest, WideStrings) { + // Streams a NULL of type const wchar_t*. + const wchar_t* const_wstr = nullptr; + EXPECT_STREQ("(null)", + (Message() << const_wstr).GetString().c_str()); + + // Streams a NULL of type wchar_t*. + wchar_t* wstr = nullptr; + EXPECT_STREQ("(null)", + (Message() << wstr).GetString().c_str()); + + // Streams a non-NULL of type const wchar_t*. + const_wstr = L"abc\x8119"; + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << const_wstr).GetString().c_str()); + + // Streams a non-NULL of type wchar_t*. + wstr = const_cast(const_wstr); + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << wstr).GetString().c_str()); +} + + +// This line tests that we can define tests in the testing namespace. +namespace testing { + +// Tests the TestInfo class. + +class TestInfoTest : public Test { + protected: + static const TestInfo* GetTestInfo(const char* test_name) { + const TestSuite* const test_suite = + GetUnitTestImpl()->GetTestSuite("TestInfoTest", "", nullptr, nullptr); + + for (int i = 0; i < test_suite->total_test_count(); ++i) { + const TestInfo* const test_info = test_suite->GetTestInfo(i); + if (strcmp(test_name, test_info->name()) == 0) + return test_info; + } + return nullptr; + } + + static const TestResult* GetTestResult( + const TestInfo* test_info) { + return test_info->result(); + } +}; + +// Tests TestInfo::test_case_name() and TestInfo::name(). +TEST_F(TestInfoTest, Names) { + const TestInfo* const test_info = GetTestInfo("Names"); + + ASSERT_STREQ("TestInfoTest", test_info->test_case_name()); + ASSERT_STREQ("Names", test_info->name()); +} + +// Tests TestInfo::result(). +TEST_F(TestInfoTest, result) { + const TestInfo* const test_info = GetTestInfo("result"); + + // Initially, there is no TestPartResult for this test. + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); + + // After the previous assertion, there is still none. + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); +} + +#define VERIFY_CODE_LOCATION \ + const int expected_line = __LINE__ - 1; \ + const TestInfo* const test_info = GetUnitTestImpl()->current_test_info(); \ + ASSERT_TRUE(test_info); \ + EXPECT_STREQ(__FILE__, test_info->file()); \ + EXPECT_EQ(expected_line, test_info->line()) + +TEST(CodeLocationForTEST, Verify) { + VERIFY_CODE_LOCATION; +} + +class CodeLocationForTESTF : public Test { +}; + +TEST_F(CodeLocationForTESTF, Verify) { + VERIFY_CODE_LOCATION; +} + +class CodeLocationForTESTP : public TestWithParam { +}; + +TEST_P(CodeLocationForTESTP, Verify) { + VERIFY_CODE_LOCATION; +} + +INSTANTIATE_TEST_SUITE_P(, CodeLocationForTESTP, Values(0)); + +template +class CodeLocationForTYPEDTEST : public Test { +}; + +TYPED_TEST_SUITE(CodeLocationForTYPEDTEST, int); + +TYPED_TEST(CodeLocationForTYPEDTEST, Verify) { + VERIFY_CODE_LOCATION; +} + +template +class CodeLocationForTYPEDTESTP : public Test { +}; + +TYPED_TEST_SUITE_P(CodeLocationForTYPEDTESTP); + +TYPED_TEST_P(CodeLocationForTYPEDTESTP, Verify) { + VERIFY_CODE_LOCATION; +} + +REGISTER_TYPED_TEST_SUITE_P(CodeLocationForTYPEDTESTP, Verify); + +INSTANTIATE_TYPED_TEST_SUITE_P(My, CodeLocationForTYPEDTESTP, int); + +#undef VERIFY_CODE_LOCATION + +// Tests setting up and tearing down a test case. +// Legacy API is deprecated but still available +#ifndef REMOVE_LEGACY_TEST_CASEAPI +class SetUpTestCaseTest : public Test { + protected: + // This will be called once before the first test in this test case + // is run. + static void SetUpTestCase() { + printf("Setting up the test case . . .\n"); + + // Initializes some shared resource. In this simple example, we + // just create a C string. More complex stuff can be done if + // desired. + shared_resource_ = "123"; + + // Increments the number of test cases that have been set up. + counter_++; + + // SetUpTestCase() should be called only once. + EXPECT_EQ(1, counter_); + } + + // This will be called once after the last test in this test case is + // run. + static void TearDownTestCase() { + printf("Tearing down the test case . . .\n"); + + // Decrements the number of test cases that have been set up. + counter_--; + + // TearDownTestCase() should be called only once. + EXPECT_EQ(0, counter_); + + // Cleans up the shared resource. + shared_resource_ = nullptr; + } + + // This will be called before each test in this test case. + void SetUp() override { + // SetUpTestCase() should be called only once, so counter_ should + // always be 1. + EXPECT_EQ(1, counter_); + } + + // Number of test cases that have been set up. + static int counter_; + + // Some resource to be shared by all tests in this test case. + static const char* shared_resource_; +}; + +int SetUpTestCaseTest::counter_ = 0; +const char* SetUpTestCaseTest::shared_resource_ = nullptr; + +// A test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test1) { EXPECT_STRNE(nullptr, shared_resource_); } + +// Another test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test2) { + EXPECT_STREQ("123", shared_resource_); +} +#endif // REMOVE_LEGACY_TEST_CASEAPI + +// Tests SetupTestSuite/TearDown TestSuite +class SetUpTestSuiteTest : public Test { + protected: + // This will be called once before the first test in this test case + // is run. + static void SetUpTestSuite() { + printf("Setting up the test suite . . .\n"); + + // Initializes some shared resource. In this simple example, we + // just create a C string. More complex stuff can be done if + // desired. + shared_resource_ = "123"; + + // Increments the number of test cases that have been set up. + counter_++; + + // SetUpTestSuite() should be called only once. + EXPECT_EQ(1, counter_); + } + + // This will be called once after the last test in this test case is + // run. + static void TearDownTestSuite() { + printf("Tearing down the test suite . . .\n"); + + // Decrements the number of test suites that have been set up. + counter_--; + + // TearDownTestSuite() should be called only once. + EXPECT_EQ(0, counter_); + + // Cleans up the shared resource. + shared_resource_ = nullptr; + } + + // This will be called before each test in this test case. + void SetUp() override { + // SetUpTestSuite() should be called only once, so counter_ should + // always be 1. + EXPECT_EQ(1, counter_); + } + + // Number of test suites that have been set up. + static int counter_; + + // Some resource to be shared by all tests in this test case. + static const char* shared_resource_; +}; + +int SetUpTestSuiteTest::counter_ = 0; +const char* SetUpTestSuiteTest::shared_resource_ = nullptr; + +// A test that uses the shared resource. +TEST_F(SetUpTestSuiteTest, TestSetupTestSuite1) { + EXPECT_STRNE(nullptr, shared_resource_); +} + +// Another test that uses the shared resource. +TEST_F(SetUpTestSuiteTest, TestSetupTestSuite2) { + EXPECT_STREQ("123", shared_resource_); +} + +// The ParseFlagsTest test case tests ParseGoogleTestFlagsOnly. + +// The Flags struct stores a copy of all Google Test flags. +struct Flags { + // Constructs a Flags struct where each flag has its default value. + Flags() : also_run_disabled_tests(false), + break_on_failure(false), + catch_exceptions(false), + death_test_use_fork(false), + filter(""), + list_tests(false), + output(""), + print_time(true), + random_seed(0), + repeat(1), + shuffle(false), + stack_trace_depth(kMaxStackTraceDepth), + stream_result_to(""), + throw_on_failure(false) {} + + // Factory methods. + + // Creates a Flags struct where the gtest_also_run_disabled_tests flag has + // the given value. + static Flags AlsoRunDisabledTests(bool also_run_disabled_tests) { + Flags flags; + flags.also_run_disabled_tests = also_run_disabled_tests; + return flags; + } + + // Creates a Flags struct where the gtest_break_on_failure flag has + // the given value. + static Flags BreakOnFailure(bool break_on_failure) { + Flags flags; + flags.break_on_failure = break_on_failure; + return flags; + } + + // Creates a Flags struct where the gtest_catch_exceptions flag has + // the given value. + static Flags CatchExceptions(bool catch_exceptions) { + Flags flags; + flags.catch_exceptions = catch_exceptions; + return flags; + } + + // Creates a Flags struct where the gtest_death_test_use_fork flag has + // the given value. + static Flags DeathTestUseFork(bool death_test_use_fork) { + Flags flags; + flags.death_test_use_fork = death_test_use_fork; + return flags; + } + + // Creates a Flags struct where the gtest_filter flag has the given + // value. + static Flags Filter(const char* filter) { + Flags flags; + flags.filter = filter; + return flags; + } + + // Creates a Flags struct where the gtest_list_tests flag has the + // given value. + static Flags ListTests(bool list_tests) { + Flags flags; + flags.list_tests = list_tests; + return flags; + } + + // Creates a Flags struct where the gtest_output flag has the given + // value. + static Flags Output(const char* output) { + Flags flags; + flags.output = output; + return flags; + } + + // Creates a Flags struct where the gtest_print_time flag has the given + // value. + static Flags PrintTime(bool print_time) { + Flags flags; + flags.print_time = print_time; + return flags; + } + + // Creates a Flags struct where the gtest_random_seed flag has the given + // value. + static Flags RandomSeed(Int32 random_seed) { + Flags flags; + flags.random_seed = random_seed; + return flags; + } + + // Creates a Flags struct where the gtest_repeat flag has the given + // value. + static Flags Repeat(Int32 repeat) { + Flags flags; + flags.repeat = repeat; + return flags; + } + + // Creates a Flags struct where the gtest_shuffle flag has the given + // value. + static Flags Shuffle(bool shuffle) { + Flags flags; + flags.shuffle = shuffle; + return flags; + } + + // Creates a Flags struct where the GTEST_FLAG(stack_trace_depth) flag has + // the given value. + static Flags StackTraceDepth(Int32 stack_trace_depth) { + Flags flags; + flags.stack_trace_depth = stack_trace_depth; + return flags; + } + + // Creates a Flags struct where the GTEST_FLAG(stream_result_to) flag has + // the given value. + static Flags StreamResultTo(const char* stream_result_to) { + Flags flags; + flags.stream_result_to = stream_result_to; + return flags; + } + + // Creates a Flags struct where the gtest_throw_on_failure flag has + // the given value. + static Flags ThrowOnFailure(bool throw_on_failure) { + Flags flags; + flags.throw_on_failure = throw_on_failure; + return flags; + } + + // These fields store the flag values. + bool also_run_disabled_tests; + bool break_on_failure; + bool catch_exceptions; + bool death_test_use_fork; + const char* filter; + bool list_tests; + const char* output; + bool print_time; + Int32 random_seed; + Int32 repeat; + bool shuffle; + Int32 stack_trace_depth; + const char* stream_result_to; + bool throw_on_failure; +}; + +// Fixture for testing ParseGoogleTestFlagsOnly(). +class ParseFlagsTest : public Test { + protected: + // Clears the flags before each test. + void SetUp() override { + GTEST_FLAG(also_run_disabled_tests) = false; + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; + GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; + GTEST_FLAG(throw_on_failure) = false; + } + + // Asserts that two narrow or wide string arrays are equal. + template + static void AssertStringArrayEq(int size1, CharType** array1, int size2, + CharType** array2) { + ASSERT_EQ(size1, size2) << " Array sizes different."; + + for (int i = 0; i != size1; i++) { + ASSERT_STREQ(array1[i], array2[i]) << " where i == " << i; + } + } + + // Verifies that the flag values match the expected values. + static void CheckFlags(const Flags& expected) { + EXPECT_EQ(expected.also_run_disabled_tests, + GTEST_FLAG(also_run_disabled_tests)); + EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); + EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); + EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork)); + EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); + EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); + EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); + EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time)); + EXPECT_EQ(expected.random_seed, GTEST_FLAG(random_seed)); + EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); + EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle)); + EXPECT_EQ(expected.stack_trace_depth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ(expected.stream_result_to, + GTEST_FLAG(stream_result_to).c_str()); + EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); + } + + // Parses a command line (specified by argc1 and argv1), then + // verifies that the flag values are expected and that the + // recognized flags are removed from the command line. + template + static void TestParsingFlags(int argc1, const CharType** argv1, + int argc2, const CharType** argv2, + const Flags& expected, bool should_print_help) { + const bool saved_help_flag = ::testing::internal::g_help_flag; + ::testing::internal::g_help_flag = false; + +# if GTEST_HAS_STREAM_REDIRECTION + CaptureStdout(); +# endif + + // Parses the command line. + internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); + +# if GTEST_HAS_STREAM_REDIRECTION + const std::string captured_stdout = GetCapturedStdout(); +# endif + + // Verifies the flag values. + CheckFlags(expected); + + // Verifies that the recognized flags are removed from the command + // line. + AssertStringArrayEq(argc1 + 1, argv1, argc2 + 1, argv2); + + // ParseGoogleTestFlagsOnly should neither set g_help_flag nor print the + // help message for the flags it recognizes. + EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); + +# if GTEST_HAS_STREAM_REDIRECTION + const char* const expected_help_fragment = + "This program contains tests written using"; + if (should_print_help) { + EXPECT_PRED_FORMAT2(IsSubstring, expected_help_fragment, captured_stdout); + } else { + EXPECT_PRED_FORMAT2(IsNotSubstring, + expected_help_fragment, captured_stdout); + } +# endif // GTEST_HAS_STREAM_REDIRECTION + + ::testing::internal::g_help_flag = saved_help_flag; + } + + // This macro wraps TestParsingFlags s.t. the user doesn't need + // to specify the array sizes. + +# define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ + TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ + sizeof(argv2)/sizeof(*argv2) - 1, argv2, \ + expected, should_print_help) +}; + +// Tests parsing an empty command line. +TEST_F(ParseFlagsTest, Empty) { + const char* argv[] = {nullptr}; + + const char* argv2[] = {nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests parsing a command line that has no flag. +TEST_F(ParseFlagsTest, NoFlag) { + const char* argv[] = {"foo.exe", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests parsing a bad --gtest_filter flag. +TEST_F(ParseFlagsTest, FilterBad) { + const char* argv[] = {"foo.exe", "--gtest_filter", nullptr}; + + const char* argv2[] = {"foo.exe", "--gtest_filter", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), true); +} + +// Tests parsing an empty --gtest_filter flag. +TEST_F(ParseFlagsTest, FilterEmpty) { + const char* argv[] = {"foo.exe", "--gtest_filter=", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), false); +} + +// Tests parsing a non-empty --gtest_filter flag. +TEST_F(ParseFlagsTest, FilterNonEmpty) { + const char* argv[] = {"foo.exe", "--gtest_filter=abc", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false); +} + +// Tests parsing --gtest_break_on_failure. +TEST_F(ParseFlagsTest, BreakOnFailureWithoutValue) { + const char* argv[] = {"foo.exe", "--gtest_break_on_failure", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); +} + +// Tests parsing --gtest_break_on_failure=0. +TEST_F(ParseFlagsTest, BreakOnFailureFalse_0) { + const char* argv[] = {"foo.exe", "--gtest_break_on_failure=0", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing --gtest_break_on_failure=f. +TEST_F(ParseFlagsTest, BreakOnFailureFalse_f) { + const char* argv[] = {"foo.exe", "--gtest_break_on_failure=f", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing --gtest_break_on_failure=F. +TEST_F(ParseFlagsTest, BreakOnFailureFalse_F) { + const char* argv[] = {"foo.exe", "--gtest_break_on_failure=F", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing a --gtest_break_on_failure flag that has a "true" +// definition. +TEST_F(ParseFlagsTest, BreakOnFailureTrue) { + const char* argv[] = {"foo.exe", "--gtest_break_on_failure=1", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); +} + +// Tests parsing --gtest_catch_exceptions. +TEST_F(ParseFlagsTest, CatchExceptions) { + const char* argv[] = {"foo.exe", "--gtest_catch_exceptions", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true), false); +} + +// Tests parsing --gtest_death_test_use_fork. +TEST_F(ParseFlagsTest, DeathTestUseFork) { + const char* argv[] = {"foo.exe", "--gtest_death_test_use_fork", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true), false); +} + +// Tests having the same flag twice with different values. The +// expected behavior is that the one coming last takes precedence. +TEST_F(ParseFlagsTest, DuplicatedFlags) { + const char* argv[] = {"foo.exe", "--gtest_filter=a", "--gtest_filter=b", + nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b"), false); +} + +// Tests having an unrecognized flag on the command line. +TEST_F(ParseFlagsTest, UnrecognizedFlag) { + const char* argv[] = {"foo.exe", "--gtest_break_on_failure", + "bar", // Unrecognized by Google Test. + "--gtest_filter=b", nullptr}; + + const char* argv2[] = {"foo.exe", "bar", nullptr}; + + Flags flags; + flags.break_on_failure = true; + flags.filter = "b"; + GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false); +} + +// Tests having a --gtest_list_tests flag +TEST_F(ParseFlagsTest, ListTestsFlag) { + const char* argv[] = {"foo.exe", "--gtest_list_tests", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); +} + +// Tests having a --gtest_list_tests flag with a "true" value +TEST_F(ParseFlagsTest, ListTestsTrue) { + const char* argv[] = {"foo.exe", "--gtest_list_tests=1", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); +} + +// Tests having a --gtest_list_tests flag with a "false" value +TEST_F(ParseFlagsTest, ListTestsFalse) { + const char* argv[] = {"foo.exe", "--gtest_list_tests=0", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_list_tests=f. +TEST_F(ParseFlagsTest, ListTestsFalse_f) { + const char* argv[] = {"foo.exe", "--gtest_list_tests=f", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_list_tests=F. +TEST_F(ParseFlagsTest, ListTestsFalse_F) { + const char* argv[] = {"foo.exe", "--gtest_list_tests=F", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_output (invalid). +TEST_F(ParseFlagsTest, OutputEmpty) { + const char* argv[] = {"foo.exe", "--gtest_output", nullptr}; + + const char* argv2[] = {"foo.exe", "--gtest_output", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), true); +} + +// Tests parsing --gtest_output=xml +TEST_F(ParseFlagsTest, OutputXml) { + const char* argv[] = {"foo.exe", "--gtest_output=xml", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml"), false); +} + +// Tests parsing --gtest_output=xml:file +TEST_F(ParseFlagsTest, OutputXmlFile) { + const char* argv[] = {"foo.exe", "--gtest_output=xml:file", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file"), false); +} + +// Tests parsing --gtest_output=xml:directory/path/ +TEST_F(ParseFlagsTest, OutputXmlDirectory) { + const char* argv[] = {"foo.exe", "--gtest_output=xml:directory/path/", + nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::Output("xml:directory/path/"), false); +} + +// Tests having a --gtest_print_time flag +TEST_F(ParseFlagsTest, PrintTimeFlag) { + const char* argv[] = {"foo.exe", "--gtest_print_time", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); +} + +// Tests having a --gtest_print_time flag with a "true" value +TEST_F(ParseFlagsTest, PrintTimeTrue) { + const char* argv[] = {"foo.exe", "--gtest_print_time=1", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); +} + +// Tests having a --gtest_print_time flag with a "false" value +TEST_F(ParseFlagsTest, PrintTimeFalse) { + const char* argv[] = {"foo.exe", "--gtest_print_time=0", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_print_time=f. +TEST_F(ParseFlagsTest, PrintTimeFalse_f) { + const char* argv[] = {"foo.exe", "--gtest_print_time=f", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_print_time=F. +TEST_F(ParseFlagsTest, PrintTimeFalse_F) { + const char* argv[] = {"foo.exe", "--gtest_print_time=F", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_random_seed=number +TEST_F(ParseFlagsTest, RandomSeed) { + const char* argv[] = {"foo.exe", "--gtest_random_seed=1000", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000), false); +} + +// Tests parsing --gtest_repeat=number +TEST_F(ParseFlagsTest, Repeat) { + const char* argv[] = {"foo.exe", "--gtest_repeat=1000", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag +TEST_F(ParseFlagsTest, AlsoRunDisabledTestsFlag) { + const char* argv[] = {"foo.exe", "--gtest_also_run_disabled_tests", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true), + false); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "true" value +TEST_F(ParseFlagsTest, AlsoRunDisabledTestsTrue) { + const char* argv[] = {"foo.exe", "--gtest_also_run_disabled_tests=1", + nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true), + false); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "false" value +TEST_F(ParseFlagsTest, AlsoRunDisabledTestsFalse) { + const char* argv[] = {"foo.exe", "--gtest_also_run_disabled_tests=0", + nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(false), + false); +} + +// Tests parsing --gtest_shuffle. +TEST_F(ParseFlagsTest, ShuffleWithoutValue) { + const char* argv[] = {"foo.exe", "--gtest_shuffle", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); +} + +// Tests parsing --gtest_shuffle=0. +TEST_F(ParseFlagsTest, ShuffleFalse_0) { + const char* argv[] = {"foo.exe", "--gtest_shuffle=0", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false); +} + +// Tests parsing a --gtest_shuffle flag that has a "true" definition. +TEST_F(ParseFlagsTest, ShuffleTrue) { + const char* argv[] = {"foo.exe", "--gtest_shuffle=1", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); +} + +// Tests parsing --gtest_stack_trace_depth=number. +TEST_F(ParseFlagsTest, StackTraceDepth) { + const char* argv[] = {"foo.exe", "--gtest_stack_trace_depth=5", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false); +} + +TEST_F(ParseFlagsTest, StreamResultTo) { + const char* argv[] = {"foo.exe", "--gtest_stream_result_to=localhost:1234", + nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_( + argv, argv2, Flags::StreamResultTo("localhost:1234"), false); +} + +// Tests parsing --gtest_throw_on_failure. +TEST_F(ParseFlagsTest, ThrowOnFailureWithoutValue) { + const char* argv[] = {"foo.exe", "--gtest_throw_on_failure", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); +} + +// Tests parsing --gtest_throw_on_failure=0. +TEST_F(ParseFlagsTest, ThrowOnFailureFalse_0) { + const char* argv[] = {"foo.exe", "--gtest_throw_on_failure=0", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false), false); +} + +// Tests parsing a --gtest_throw_on_failure flag that has a "true" +// definition. +TEST_F(ParseFlagsTest, ThrowOnFailureTrue) { + const char* argv[] = {"foo.exe", "--gtest_throw_on_failure=1", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); +} + +# if GTEST_OS_WINDOWS +// Tests parsing wide strings. +TEST_F(ParseFlagsTest, WideStrings) { + const wchar_t* argv[] = { + L"foo.exe", + L"--gtest_filter=Foo*", + L"--gtest_list_tests=1", + L"--gtest_break_on_failure", + L"--non_gtest_flag", + NULL + }; + + const wchar_t* argv2[] = { + L"foo.exe", + L"--non_gtest_flag", + NULL + }; + + Flags expected_flags; + expected_flags.break_on_failure = true; + expected_flags.filter = "Foo*"; + expected_flags.list_tests = true; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); +} +# endif // GTEST_OS_WINDOWS + +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +class FlagfileTest : public ParseFlagsTest { + public: + virtual void SetUp() { + ParseFlagsTest::SetUp(); + + testdata_path_.Set(internal::FilePath( + testing::TempDir() + internal::GetCurrentExecutableName().string() + + "_flagfile_test")); + testing::internal::posix::RmDir(testdata_path_.c_str()); + EXPECT_TRUE(testdata_path_.CreateFolder()); + } + + virtual void TearDown() { + testing::internal::posix::RmDir(testdata_path_.c_str()); + ParseFlagsTest::TearDown(); + } + + internal::FilePath CreateFlagfile(const char* contents) { + internal::FilePath file_path(internal::FilePath::GenerateUniqueFileName( + testdata_path_, internal::FilePath("unique"), "txt")); + FILE* f = testing::internal::posix::FOpen(file_path.c_str(), "w"); + fprintf(f, "%s", contents); + fclose(f); + return file_path; + } + + private: + internal::FilePath testdata_path_; +}; + +// Tests an empty flagfile. +TEST_F(FlagfileTest, Empty) { + internal::FilePath flagfile_path(CreateFlagfile("")); + std::string flagfile_flag = + std::string("--" GTEST_FLAG_PREFIX_ "flagfile=") + flagfile_path.c_str(); + + const char* argv[] = {"foo.exe", flagfile_flag.c_str(), nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests passing a non-empty --gtest_filter flag via --gtest_flagfile. +TEST_F(FlagfileTest, FilterNonEmpty) { + internal::FilePath flagfile_path(CreateFlagfile( + "--" GTEST_FLAG_PREFIX_ "filter=abc")); + std::string flagfile_flag = + std::string("--" GTEST_FLAG_PREFIX_ "flagfile=") + flagfile_path.c_str(); + + const char* argv[] = {"foo.exe", flagfile_flag.c_str(), nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false); +} + +// Tests passing several flags via --gtest_flagfile. +TEST_F(FlagfileTest, SeveralFlags) { + internal::FilePath flagfile_path(CreateFlagfile( + "--" GTEST_FLAG_PREFIX_ "filter=abc\n" + "--" GTEST_FLAG_PREFIX_ "break_on_failure\n" + "--" GTEST_FLAG_PREFIX_ "list_tests")); + std::string flagfile_flag = + std::string("--" GTEST_FLAG_PREFIX_ "flagfile=") + flagfile_path.c_str(); + + const char* argv[] = {"foo.exe", flagfile_flag.c_str(), nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + Flags expected_flags; + expected_flags.break_on_failure = true; + expected_flags.filter = "abc"; + expected_flags.list_tests = true; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); +} +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + +// Tests current_test_info() in UnitTest. +class CurrentTestInfoTest : public Test { + protected: + // Tests that current_test_info() returns NULL before the first test in + // the test case is run. + static void SetUpTestSuite() { + // There should be no tests running at this point. + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_TRUE(test_info == nullptr) + << "There should be no tests running at this point."; + } + + // Tests that current_test_info() returns NULL after the last test in + // the test case has run. + static void TearDownTestSuite() { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_TRUE(test_info == nullptr) + << "There should be no tests running at this point."; + } +}; + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. +TEST_F(CurrentTestInfoTest, WorksForFirstTestInATestSuite) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(nullptr != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForFirstTestInATestSuite", test_info->name()) + << "Expected the name of the currently running test."; +} + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. We +// use this test to see that the TestInfo object actually changed from +// the previous invocation. +TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestSuite) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(nullptr != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForSecondTestInATestSuite", test_info->name()) + << "Expected the name of the currently running test."; +} + +} // namespace testing + + +// These two lines test that we can define tests in a namespace that +// has the name "testing" and is nested in another namespace. +namespace my_namespace { +namespace testing { + +// Makes sure that TEST knows to use ::testing::Test instead of +// ::my_namespace::testing::Test. +class Test {}; + +// Makes sure that an assertion knows to use ::testing::Message instead of +// ::my_namespace::testing::Message. +class Message {}; + +// Makes sure that an assertion knows to use +// ::testing::AssertionResult instead of +// ::my_namespace::testing::AssertionResult. +class AssertionResult {}; + +// Tests that an assertion that should succeed works as expected. +TEST(NestedTestingNamespaceTest, Success) { + EXPECT_EQ(1, 1) << "This shouldn't fail."; +} + +// Tests that an assertion that should fail works as expected. +TEST(NestedTestingNamespaceTest, Failure) { + EXPECT_FATAL_FAILURE(FAIL() << "This failure is expected.", + "This failure is expected."); +} + +} // namespace testing +} // namespace my_namespace + +// Tests that one can call superclass SetUp and TearDown methods-- +// that is, that they are not private. +// No tests are based on this fixture; the test "passes" if it compiles +// successfully. +class ProtectedFixtureMethodsTest : public Test { + protected: + void SetUp() override { Test::SetUp(); } + void TearDown() override { Test::TearDown(); } +}; + +// StreamingAssertionsTest tests the streaming versions of a representative +// sample of assertions. +TEST(StreamingAssertionsTest, Unconditional) { + SUCCEED() << "expected success"; + EXPECT_NONFATAL_FAILURE(ADD_FAILURE() << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(FAIL() << "expected failure", + "expected failure"); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +TEST(StreamingAssertionsTest, Truth) { + EXPECT_TRUE(true) << "unexpected failure"; + ASSERT_TRUE(true) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, Truth2) { + EXPECT_FALSE(false) << "unexpected failure"; + ASSERT_FALSE(false) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(true) << "expected failure", + "expected failure"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them +# pragma option pop +#endif + +TEST(StreamingAssertionsTest, IntegerEquals) { + EXPECT_EQ(1, 1) << "unexpected failure"; + ASSERT_EQ(1, 1) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(1, 2) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(1, 2) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, IntegerLessThan) { + EXPECT_LT(1, 2) << "unexpected failure"; + ASSERT_LT(1, 2) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 1) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqual) { + EXPECT_STREQ("foo", "foo") << "unexpected failure"; + ASSERT_STREQ("foo", "foo") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STREQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsNotEqual) { + EXPECT_STRNE("foo", "bar") << "unexpected failure"; + ASSERT_STRNE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("foo", "foo") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("foo", "foo") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqualIgnoringCase) { + EXPECT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + ASSERT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringNotEqualIgnoringCase) { + EXPECT_STRCASENE("foo", "bar") << "unexpected failure"; + ASSERT_STRCASENE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("foo", "FOO") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("bar", "BAR") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, FloatingPointEquals) { + EXPECT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + ASSERT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); +} + +#if GTEST_HAS_EXCEPTIONS + +TEST(StreamingAssertionsTest, Throw) { + EXPECT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + ASSERT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, NoThrow) { + EXPECT_NO_THROW(ThrowNothing()) << "unexpected failure"; + ASSERT_NO_THROW(ThrowNothing()) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, AnyThrow) { + EXPECT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + ASSERT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(ThrowNothing()) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(ThrowNothing()) << + "expected failure", "expected failure"); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests that Google Test correctly decides whether to use colors in the output. + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsYes) { + GTEST_FLAG(color) = "yes"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsAliasOfYes) { + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + + GTEST_FLAG(color) = "True"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "t"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "1"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsNo) { + GTEST_FLAG(color) = "no"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsInvalid) { + SetEnv("TERM", "xterm"); // TERM supports colors. + + GTEST_FLAG(color) = "F"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "0"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "unknown"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenStdoutIsTty) { + GTEST_FLAG(color) = "auto"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { + GTEST_FLAG(color) = "auto"; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW + // On Windows, we ignore the TERM variable as it's usually not set. + + SetEnv("TERM", "dumb"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", ""); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#else + // On non-Windows platforms, we rely on TERM to determine if the + // terminal supports colors. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "emacs"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "vt100"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-mono"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "screen"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "screen-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "tmux"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "tmux-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "rxvt-unicode"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "rxvt-unicode-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "linux"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "cygwin"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#endif // GTEST_OS_WINDOWS +} + +// Verifies that StaticAssertTypeEq works in a namespace scope. + +static bool dummy1 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq(); +static bool dummy2 GTEST_ATTRIBUTE_UNUSED_ = + StaticAssertTypeEq(); + +// Verifies that StaticAssertTypeEq works in a class. + +template +class StaticAssertTypeEqTestHelper { + public: + StaticAssertTypeEqTestHelper() { StaticAssertTypeEq(); } +}; + +TEST(StaticAssertTypeEqTest, WorksInClass) { + StaticAssertTypeEqTestHelper(); +} + +// Verifies that StaticAssertTypeEq works inside a function. + +typedef int IntAlias; + +TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { + StaticAssertTypeEq(); + StaticAssertTypeEq(); +} + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasNonfatalFailure()); +} + +static void FailFatally() { FAIL(); } + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsOnlyFatalFailure) { + FailFatally(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_FALSE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +// A wrapper for calling HasNonfatalFailure outside of a test body. +static bool HasNonfatalFailureHelper() { + return testing::Test::HasNonfatalFailure(); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasNonfatalFailureHelper()); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasFailure()); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsFatalFailure) { + FailFatally(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +// A wrapper for calling HasFailure outside of a test body. +static bool HasFailureHelper() { return testing::Test::HasFailure(); } + +TEST(HasFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasFailureHelper()); +} + +TEST(HasFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_failure = HasFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +class TestListener : public EmptyTestEventListener { + public: + TestListener() : on_start_counter_(nullptr), is_destroyed_(nullptr) {} + TestListener(int* on_start_counter, bool* is_destroyed) + : on_start_counter_(on_start_counter), + is_destroyed_(is_destroyed) {} + + ~TestListener() override { + if (is_destroyed_) + *is_destroyed_ = true; + } + + protected: + void OnTestProgramStart(const UnitTest& /*unit_test*/) override { + if (on_start_counter_ != nullptr) (*on_start_counter_)++; + } + + private: + int* on_start_counter_; + bool* is_destroyed_; +}; + +// Tests the constructor. +TEST(TestEventListenersTest, ConstructionWorks) { + TestEventListeners listeners; + + EXPECT_TRUE(TestEventListenersAccessor::GetRepeater(&listeners) != nullptr); + EXPECT_TRUE(listeners.default_result_printer() == nullptr); + EXPECT_TRUE(listeners.default_xml_generator() == nullptr); +} + +// Tests that the TestEventListeners destructor deletes all the listeners it +// owns. +TEST(TestEventListenersTest, DestructionWorks) { + bool default_result_printer_is_destroyed = false; + bool default_xml_printer_is_destroyed = false; + bool extra_listener_is_destroyed = false; + TestListener* default_result_printer = + new TestListener(nullptr, &default_result_printer_is_destroyed); + TestListener* default_xml_printer = + new TestListener(nullptr, &default_xml_printer_is_destroyed); + TestListener* extra_listener = + new TestListener(nullptr, &extra_listener_is_destroyed); + + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, + default_result_printer); + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, + default_xml_printer); + listeners.Append(extra_listener); + } + EXPECT_TRUE(default_result_printer_is_destroyed); + EXPECT_TRUE(default_xml_printer_is_destroyed); + EXPECT_TRUE(extra_listener_is_destroyed); +} + +// Tests that a listener Append'ed to a TestEventListeners list starts +// receiving events. +TEST(TestEventListenersTest, Append) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); + } + EXPECT_TRUE(is_destroyed); +} + +// Tests that listeners receive events in the order they were appended to +// the list, except for *End requests, which must be received in the reverse +// order. +class SequenceTestingListener : public EmptyTestEventListener { + public: + SequenceTestingListener(std::vector* vector, const char* id) + : vector_(vector), id_(id) {} + + protected: + void OnTestProgramStart(const UnitTest& /*unit_test*/) override { + vector_->push_back(GetEventDescription("OnTestProgramStart")); + } + + void OnTestProgramEnd(const UnitTest& /*unit_test*/) override { + vector_->push_back(GetEventDescription("OnTestProgramEnd")); + } + + void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) override { + vector_->push_back(GetEventDescription("OnTestIterationStart")); + } + + void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) override { + vector_->push_back(GetEventDescription("OnTestIterationEnd")); + } + + private: + std::string GetEventDescription(const char* method) { + Message message; + message << id_ << "." << method; + return message.GetString(); + } + + std::vector* vector_; + const char* const id_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener); +}; + +TEST(EventListenerTest, AppendKeepsOrder) { + std::vector vec; + TestEventListeners listeners; + listeners.Append(new SequenceTestingListener(&vec, "1st")); + listeners.Append(new SequenceTestingListener(&vec, "2nd")); + listeners.Append(new SequenceTestingListener(&vec, "3rd")); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestProgramStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestProgramStart", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( + *UnitTest::GetInstance()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestProgramEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestProgramEnd", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestIterationStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestIterationStart", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestIterationEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestIterationEnd", vec[2].c_str()); +} + +// Tests that a listener removed from a TestEventListeners list stops receiving +// events and is not deleted when the list is destroyed. +TEST(TestEventListenersTest, Release) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + EXPECT_EQ(listener, listeners.Release(listener)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_TRUE(listeners.Release(listener) == nullptr); + } + EXPECT_EQ(0, on_start_counter); + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that no events are forwarded when event forwarding is disabled. +TEST(EventListenerTest, SuppressEventForwarding) { + int on_start_counter = 0; + TestListener* listener = new TestListener(&on_start_counter, nullptr); + + TestEventListeners listeners; + listeners.Append(listener); + ASSERT_TRUE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::SuppressEventForwarding(&listeners); + ASSERT_FALSE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); +} + +// Tests that events generated by Google Test are not forwarded in +// death test subprocesses. +TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) { + EXPECT_DEATH_IF_SUPPORTED({ + GTEST_CHECK_(TestEventListenersAccessor::EventForwardingEnabled( + *GetUnitTestImpl()->listeners())) << "expected failure";}, + "expected failure"); +} + +// Tests that a listener installed via SetDefaultResultPrinter() starts +// receiving events and is returned via default_result_printer() and that +// the previous default_result_printer is removed from the list and deleted. +TEST(EventListenerTest, default_result_printer) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_result_printer()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_result_printer with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, nullptr); + + EXPECT_TRUE(listeners.default_result_printer() == nullptr); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_result_printer listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_result_printer() == nullptr); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_result_printer. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that a listener installed via SetDefaultXmlGenerator() starts +// receiving events and is returned via default_xml_generator() and that +// the previous default_xml_generator is removed from the list and deleted. +TEST(EventListenerTest, default_xml_generator) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_xml_generator()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_xml_generator with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, nullptr); + + EXPECT_TRUE(listeners.default_xml_generator() == nullptr); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_xml_generator listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_xml_generator() == nullptr); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_xml_generator. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Sanity tests to ensure that the alternative, verbose spellings of +// some of the macros work. We don't test them thoroughly as that +// would be quite involved. Since their implementations are +// straightforward, and they are rarely used, we'll just rely on the +// users to tell us when they are broken. +GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST. + GTEST_SUCCEED() << "OK"; // GTEST_SUCCEED is the same as SUCCEED. + + // GTEST_FAIL is the same as FAIL. + EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure", + "An expected failure"); + + // GTEST_ASSERT_XY is the same as ASSERT_XY. + + GTEST_ASSERT_EQ(0, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_NE(0, 1); + GTEST_ASSERT_NE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_NE(0, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LE(0, 0); + GTEST_ASSERT_LE(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LE(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LT(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(0, 0) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GE(0, 0); + GTEST_ASSERT_GE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GE(0, 1) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GT(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(1, 1) << "An expected failure", + "An expected failure"); +} + +// Tests for internal utilities necessary for implementation of the universal +// printing. + +class ConversionHelperBase {}; +class ConversionHelperDerived : public ConversionHelperBase {}; + +// Tests that IsAProtocolMessage::value is a compile-time constant. +TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_(IsAProtocolMessage<::proto2::Message>::value, + const_true); + GTEST_COMPILE_ASSERT_(!IsAProtocolMessage::value, const_false); +} + +// Tests that IsAProtocolMessage::value is true when T is +// proto2::Message or a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { + EXPECT_TRUE(IsAProtocolMessage< ::proto2::Message>::value); +} + +// Tests that IsAProtocolMessage::value is false when T is neither +// ::proto2::Message nor a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) { + EXPECT_FALSE(IsAProtocolMessage::value); + EXPECT_FALSE(IsAProtocolMessage::value); +} + +// Tests GTEST_REMOVE_REFERENCE_AND_CONST_. + +template +void TestGTestRemoveReferenceAndConst() { + static_assert(std::is_same::value, + "GTEST_REMOVE_REFERENCE_AND_CONST_ failed."); +} + +TEST(RemoveReferenceToConstTest, Works) { + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); +} + +// Tests GTEST_REFERENCE_TO_CONST_. + +template +void TestGTestReferenceToConst() { + static_assert(std::is_same::value, + "GTEST_REFERENCE_TO_CONST_ failed."); +} + +TEST(GTestReferenceToConstTest, Works) { + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); +} + + +// Tests IsContainerTest. + +class NonContainer {}; + +TEST(IsContainerTestTest, WorksForNonContainer) { + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); +} + +TEST(IsContainerTestTest, WorksForContainer) { + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); +} + +struct ConstOnlyContainerWithPointerIterator { + using const_iterator = int*; + const_iterator begin() const; + const_iterator end() const; +}; + +struct ConstOnlyContainerWithClassIterator { + struct const_iterator { + const int& operator*() const; + const_iterator& operator++(/* pre-increment */); + }; + const_iterator begin() const; + const_iterator end() const; +}; + +TEST(IsContainerTestTest, ConstOnlyContainer) { + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest(0))); +} + +// Tests IsHashTable. +struct AHashTable { + typedef void hasher; +}; +struct NotReallyAHashTable { + typedef void hasher; + typedef void reverse_iterator; +}; +TEST(IsHashTable, Basic) { + EXPECT_TRUE(testing::internal::IsHashTable::value); + EXPECT_FALSE(testing::internal::IsHashTable::value); + EXPECT_FALSE(testing::internal::IsHashTable>::value); + EXPECT_TRUE(testing::internal::IsHashTable>::value); +} + +// Tests ArrayEq(). + +TEST(ArrayEqTest, WorksForDegeneratedArrays) { + EXPECT_TRUE(ArrayEq(5, 5L)); + EXPECT_FALSE(ArrayEq('a', 0)); +} + +TEST(ArrayEqTest, WorksForOneDimensionalArrays) { + // Note that a and b are distinct but compatible types. + const int a[] = { 0, 1 }; + long b[] = { 0, 1 }; + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + b[0] = 2; + EXPECT_FALSE(ArrayEq(a, b)); + EXPECT_FALSE(ArrayEq(a, 1, b)); +} + +TEST(ArrayEqTest, WorksForTwoDimensionalArrays) { + const char a[][3] = { "hi", "lo" }; + const char b[][3] = { "hi", "lo" }; + const char c[][3] = { "hi", "li" }; + + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + EXPECT_FALSE(ArrayEq(a, c)); + EXPECT_FALSE(ArrayEq(a, 2, c)); +} + +// Tests ArrayAwareFind(). + +TEST(ArrayAwareFindTest, WorksForOneDimensionalArray) { + const char a[] = "hello"; + EXPECT_EQ(a + 4, ArrayAwareFind(a, a + 5, 'o')); + EXPECT_EQ(a + 5, ArrayAwareFind(a, a + 5, 'x')); +} + +TEST(ArrayAwareFindTest, WorksForTwoDimensionalArray) { + int a[][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } }; + const int b[2] = { 2, 3 }; + EXPECT_EQ(a + 1, ArrayAwareFind(a, a + 3, b)); + + const int c[2] = { 6, 7 }; + EXPECT_EQ(a + 3, ArrayAwareFind(a, a + 3, c)); +} + +// Tests CopyArray(). + +TEST(CopyArrayTest, WorksForDegeneratedArrays) { + int n = 0; + CopyArray('a', &n); + EXPECT_EQ('a', n); +} + +TEST(CopyArrayTest, WorksForOneDimensionalArrays) { + const char a[3] = "hi"; + int b[3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); +#endif + + int c[3]; + CopyArray(a, 3, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { + const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; + int b[2][3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); +#endif + + int c[2][3]; + CopyArray(a, 2, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +// Tests NativeArray. + +TEST(NativeArrayTest, ConstructorFromArrayWorks) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, RelationToSourceReference()); + EXPECT_EQ(3U, na.size()); + EXPECT_EQ(a, na.begin()); +} + +TEST(NativeArrayTest, CreatesAndDeletesCopyOfArrayWhenAskedTo) { + typedef int Array[2]; + Array* a = new Array[1]; + (*a)[0] = 0; + (*a)[1] = 1; + NativeArray na(*a, 2, RelationToSourceCopy()); + EXPECT_NE(*a, na.begin()); + delete[] a; + EXPECT_EQ(0, na.begin()[0]); + EXPECT_EQ(1, na.begin()[1]); + + // We rely on the heap checker to verify that na deletes the copy of + // array. +} + +TEST(NativeArrayTest, TypeMembersAreCorrect) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); + + StaticAssertTypeEq::const_iterator>(); + StaticAssertTypeEq::const_iterator>(); +} + +TEST(NativeArrayTest, MethodsWork) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, RelationToSourceCopy()); + ASSERT_EQ(3U, na.size()); + EXPECT_EQ(3, na.end() - na.begin()); + + NativeArray::const_iterator it = na.begin(); + EXPECT_EQ(0, *it); + ++it; + EXPECT_EQ(1, *it); + it++; + EXPECT_EQ(2, *it); + ++it; + EXPECT_EQ(na.end(), it); + + EXPECT_TRUE(na == na); + + NativeArray na2(a, 3, RelationToSourceReference()); + EXPECT_TRUE(na == na2); + + const int b1[3] = { 0, 1, 1 }; + const int b2[4] = { 0, 1, 2, 3 }; + EXPECT_FALSE(na == NativeArray(b1, 3, RelationToSourceReference())); + EXPECT_FALSE(na == NativeArray(b2, 4, RelationToSourceCopy())); +} + +TEST(NativeArrayTest, WorksForTwoDimensionalArray) { + const char a[2][3] = { "hi", "lo" }; + NativeArray na(a, 2, RelationToSourceReference()); + ASSERT_EQ(2U, na.size()); + EXPECT_EQ(a, na.begin()); +} + +// IndexSequence +TEST(IndexSequence, MakeIndexSequence) { + using testing::internal::IndexSequence; + using testing::internal::MakeIndexSequence; + EXPECT_TRUE( + (std::is_same, MakeIndexSequence<0>::type>::value)); + EXPECT_TRUE( + (std::is_same, MakeIndexSequence<1>::type>::value)); + EXPECT_TRUE( + (std::is_same, MakeIndexSequence<2>::type>::value)); + EXPECT_TRUE(( + std::is_same, MakeIndexSequence<3>::type>::value)); + EXPECT_TRUE( + (std::is_base_of, MakeIndexSequence<3>>::value)); +} + +// ElemFromList +TEST(ElemFromList, Basic) { + using testing::internal::ElemFromList; + using Idx = testing::internal::MakeIndexSequence<3>::type; + EXPECT_TRUE(( + std::is_same::type>::value)); + EXPECT_TRUE( + (std::is_same::type>::value)); + EXPECT_TRUE( + (std::is_same::type>::value)); + EXPECT_TRUE( + (std::is_same< + char, ElemFromList<7, testing::internal::MakeIndexSequence<12>::type, + int, int, int, int, int, int, int, char, int, int, + int, int>::type>::value)); +} + +// FlatTuple +TEST(FlatTuple, Basic) { + using testing::internal::FlatTuple; + + FlatTuple tuple = {}; + EXPECT_EQ(0, tuple.Get<0>()); + EXPECT_EQ(0.0, tuple.Get<1>()); + EXPECT_EQ(nullptr, tuple.Get<2>()); + + tuple = FlatTuple(7, 3.2, "Foo"); + EXPECT_EQ(7, tuple.Get<0>()); + EXPECT_EQ(3.2, tuple.Get<1>()); + EXPECT_EQ(std::string("Foo"), tuple.Get<2>()); + + tuple.Get<1>() = 5.1; + EXPECT_EQ(5.1, tuple.Get<1>()); +} + +TEST(FlatTuple, ManyTypes) { + using testing::internal::FlatTuple; + + // Instantiate FlatTuple with 257 ints. + // Tests show that we can do it with thousands of elements, but very long + // compile times makes it unusuitable for this test. +#define GTEST_FLAT_TUPLE_INT8 int, int, int, int, int, int, int, int, +#define GTEST_FLAT_TUPLE_INT16 GTEST_FLAT_TUPLE_INT8 GTEST_FLAT_TUPLE_INT8 +#define GTEST_FLAT_TUPLE_INT32 GTEST_FLAT_TUPLE_INT16 GTEST_FLAT_TUPLE_INT16 +#define GTEST_FLAT_TUPLE_INT64 GTEST_FLAT_TUPLE_INT32 GTEST_FLAT_TUPLE_INT32 +#define GTEST_FLAT_TUPLE_INT128 GTEST_FLAT_TUPLE_INT64 GTEST_FLAT_TUPLE_INT64 +#define GTEST_FLAT_TUPLE_INT256 GTEST_FLAT_TUPLE_INT128 GTEST_FLAT_TUPLE_INT128 + + // Let's make sure that we can have a very long list of types without blowing + // up the template instantiation depth. + FlatTuple tuple; + + tuple.Get<0>() = 7; + tuple.Get<99>() = 17; + tuple.Get<256>() = 1000; + EXPECT_EQ(7, tuple.Get<0>()); + EXPECT_EQ(17, tuple.Get<99>()); + EXPECT_EQ(1000, tuple.Get<256>()); +} + +// Tests SkipPrefix(). + +TEST(SkipPrefixTest, SkipsWhenPrefixMatches) { + const char* const str = "hello"; + + const char* p = str; + EXPECT_TRUE(SkipPrefix("", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_TRUE(SkipPrefix("hell", &p)); + EXPECT_EQ(str + 4, p); +} + +TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) { + const char* const str = "world"; + + const char* p = str; + EXPECT_FALSE(SkipPrefix("W", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_FALSE(SkipPrefix("world!", &p)); + EXPECT_EQ(str, p); +} + +// Tests ad_hoc_test_result(). + +class AdHocTestResultTest : public testing::Test { + protected: + static void SetUpTestSuite() { + FAIL() << "A failure happened inside SetUpTestSuite()."; + } +}; + +TEST_F(AdHocTestResultTest, AdHocTestResultForTestSuiteShowsFailure) { + const testing::TestResult& test_result = testing::UnitTest::GetInstance() + ->current_test_suite() + ->ad_hoc_test_result(); + EXPECT_TRUE(test_result.Failed()); +} + +TEST_F(AdHocTestResultTest, AdHocTestResultTestForUnitTestDoesNotShowFailure) { + const testing::TestResult& test_result = + testing::UnitTest::GetInstance()->ad_hoc_test_result(); + EXPECT_FALSE(test_result.Failed()); +} + +class DynamicUnitTestFixture : public testing::Test {}; + +class DynamicTest : public DynamicUnitTestFixture { + void TestBody() override { EXPECT_TRUE(true); } +}; + +auto* dynamic_test = testing::RegisterTest( + "DynamicUnitTestFixture", "DynamicTest", "TYPE", "VALUE", __FILE__, + __LINE__, []() -> DynamicUnitTestFixture* { return new DynamicTest; }); + +TEST(RegisterTest, WasRegistered) { + auto* unittest = testing::UnitTest::GetInstance(); + for (int i = 0; i < unittest->total_test_suite_count(); ++i) { + auto* tests = unittest->GetTestSuite(i); + if (tests->name() != std::string("DynamicUnitTestFixture")) continue; + for (int j = 0; j < tests->total_test_count(); ++j) { + if (tests->GetTestInfo(j)->name() != std::string("DynamicTest")) continue; + // Found it. + EXPECT_STREQ(tests->GetTestInfo(j)->value_param(), "VALUE"); + EXPECT_STREQ(tests->GetTestInfo(j)->type_param(), "TYPE"); + return; + } + } + + FAIL() << "Didn't find the test!"; +} diff --git a/3rdparty/gtest/test/gtest_xml_outfile1_test_.cc b/3rdparty/gtest/test/gtest_xml_outfile1_test_.cc new file mode 100644 index 0000000..19aa252 --- /dev/null +++ b/3rdparty/gtest/test/gtest_xml_outfile1_test_.cc @@ -0,0 +1,43 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// gtest_xml_outfile1_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include "gtest/gtest.h" + +class PropertyOne : public testing::Test { + protected: + void SetUp() override { RecordProperty("SetUpProp", 1); } + void TearDown() override { RecordProperty("TearDownProp", 1); } +}; + +TEST_F(PropertyOne, TestSomeProperties) { + RecordProperty("TestSomeProperty", 1); +} diff --git a/3rdparty/gtest/test/gtest_xml_outfile2_test_.cc b/3rdparty/gtest/test/gtest_xml_outfile2_test_.cc new file mode 100644 index 0000000..f9a2a6e --- /dev/null +++ b/3rdparty/gtest/test/gtest_xml_outfile2_test_.cc @@ -0,0 +1,43 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// gtest_xml_outfile2_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include "gtest/gtest.h" + +class PropertyTwo : public testing::Test { + protected: + void SetUp() override { RecordProperty("SetUpProp", 2); } + void TearDown() override { RecordProperty("TearDownProp", 2); } +}; + +TEST_F(PropertyTwo, TestSomeProperties) { + RecordProperty("TestSomeProperty", 2); +} diff --git a/3rdparty/gtest/test/gtest_xml_outfiles_test.py b/3rdparty/gtest/test/gtest_xml_outfiles_test.py new file mode 100644 index 0000000..e093f6f --- /dev/null +++ b/3rdparty/gtest/test/gtest_xml_outfiles_test.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test for the gtest_xml_output module.""" + +import os +from xml.dom import minidom, Node +import gtest_test_utils +import gtest_xml_test_utils + +GTEST_OUTPUT_SUBDIR = "xml_outfiles" +GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" +GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" + +EXPECTED_XML_1 = """ + + + + + + + + + + + +""" + +EXPECTED_XML_2 = """ + + + + + + + + + + + +""" + + +class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): + """Unit test for Google Test's XML output functionality.""" + + def setUp(self): + # We want the trailing '/' that the last "" provides in os.path.join, for + # telling Google Test to create an output directory instead of a single file + # for xml output. + self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_OUTPUT_SUBDIR, "") + self.DeleteFilesAndDir() + + def tearDown(self): + self.DeleteFilesAndDir() + + def DeleteFilesAndDir(self): + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + ".xml")) + except os.error: + pass + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + ".xml")) + except os.error: + pass + try: + os.rmdir(self.output_dir_) + except os.error: + pass + + def testOutfile1(self): + self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_XML_1) + + def testOutfile2(self): + self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2) + + def _TestOutFile(self, test_name, expected_xml): + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name) + command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] + p = gtest_test_utils.Subprocess(command, + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + + output_file_name1 = test_name + ".xml" + output_file1 = os.path.join(self.output_dir_, output_file_name1) + output_file_name2 = 'lt-' + output_file_name1 + output_file2 = os.path.join(self.output_dir_, output_file_name2) + self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2), + output_file1) + + expected = minidom.parseString(expected_xml) + if os.path.isfile(output_file1): + actual = minidom.parse(output_file1) + else: + actual = minidom.parse(output_file2) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) + expected.unlink() + actual.unlink() + + +if __name__ == "__main__": + os.environ["GTEST_STACK_TRACE_DEPTH"] = "0" + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/gtest_xml_output_unittest.py b/3rdparty/gtest/test/gtest_xml_output_unittest.py new file mode 100644 index 0000000..63b1af0 --- /dev/null +++ b/3rdparty/gtest/test/gtest_xml_output_unittest.py @@ -0,0 +1,389 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test for the gtest_xml_output module""" + +import datetime +import errno +import os +import re +import sys +from xml.dom import minidom, Node + +import gtest_test_utils +import gtest_xml_test_utils + +GTEST_FILTER_FLAG = '--gtest_filter' +GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' +GTEST_OUTPUT_FLAG = '--gtest_output' +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' +GTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_' + +# The flag indicating stacktraces are not supported +NO_STACKTRACE_SUPPORT_FLAG = '--no_stacktrace_support' + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' +SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' + +SUPPORTS_STACK_TRACES = NO_STACKTRACE_SUPPORT_FLAG not in sys.argv + +if SUPPORTS_STACK_TRACES: + STACK_TRACE_TEMPLATE = '\nStack trace:\n*' +else: + STACK_TRACE_TEMPLATE = '' + # unittest.main() can't handle unknown flags + sys.argv.remove(NO_STACKTRACE_SUPPORT_FLAG) + +EXPECTED_NON_EMPTY_XML = """ + + + + + + + + + + + + + + + + + + + + ]]>%(stack)s]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" % { + 'stack': STACK_TRACE_TEMPLATE +} + +EXPECTED_FILTERED_TEST_XML = """ + + + + +""" + +EXPECTED_SHARDED_TEST_XML = """ + + + + + + + + + + + + + + +""" + +EXPECTED_EMPTY_XML = """ + +""" + +GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) + +SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess( + [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output + + +class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): + """ + Unit test for Google Test's XML output functionality. + """ + + # This test currently breaks on platforms that do not support typed and + # type-parameterized tests, so we don't run it under them. + if SUPPORTS_TYPED_TESTS: + def testNonEmptyXmlOutput(self): + """ + Runs a test program that generates a non-empty XML output, and + tests that the XML output is expected. + """ + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) + + def testEmptyXmlOutput(self): + """Verifies XML output for a Google Test binary without actual tests. + + Runs a test program that generates an empty XML output, and + tests that the XML output is expected. + """ + + self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0) + + def testTimestampValue(self): + """Checks whether the timestamp attribute in the XML output is valid. + + Runs a test program that generates an empty XML output, and checks if + the timestamp attribute in the testsuites tag is valid. + """ + actual = self._GetXmlOutput('gtest_no_test_unittest', [], {}, 0) + date_time_str = actual.documentElement.getAttributeNode('timestamp').value + # datetime.strptime() is only available in Python 2.5+ so we have to + # parse the expected datetime manually. + match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str) + self.assertTrue( + re.match, + 'XML datettime string %s has incorrect format' % date_time_str) + date_time_from_xml = datetime.datetime( + year=int(match.group(1)), month=int(match.group(2)), + day=int(match.group(3)), hour=int(match.group(4)), + minute=int(match.group(5)), second=int(match.group(6))) + + time_delta = abs(datetime.datetime.now() - date_time_from_xml) + # timestamp value should be near the current local time + self.assertTrue(time_delta < datetime.timedelta(seconds=600), + 'time_delta is %s' % time_delta) + actual.unlink() + + def testDefaultOutputFile(self): + """ + Confirms that Google Test produces an XML output file with the expected + default name if no name is explicitly specified. + """ + output_file = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_DEFAULT_OUTPUT_FILE) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath( + 'gtest_no_test_unittest') + try: + os.remove(output_file) + except OSError: + e = sys.exc_info()[1] + if e.errno != errno.ENOENT: + raise + + p = gtest_test_utils.Subprocess( + [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG], + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + self.assert_(os.path.isfile(output_file)) + + def testSuppressedXmlOutput(self): + """ + Tests that no XML file is generated if the default XML listener is + shut down before RUN_ALL_TESTS is invoked. + """ + + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_PROGRAM_NAME + 'out.xml') + if os.path.isfile(xml_path): + os.remove(xml_path) + + command = [GTEST_PROGRAM_PATH, + '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path), + '--shut_down_xml'] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + # p.signal is available only if p.terminated_by_signal is True. + self.assertFalse( + p.terminated_by_signal, + '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(1, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, 1)) + + self.assert_(not os.path.isfile(xml_path)) + + def testFilteredTestXmlOutput(self): + """Verifies XML output when a filter is applied. + + Runs a test program that executes only some tests and verifies that + non-selected tests do not show up in the XML output. + """ + + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0, + extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG]) + + def testShardedTestXmlOutput(self): + """Verifies XML output when run using multiple shards. + + Runs a test program that executes only one shard and verifies that tests + from other shards do not show up in the XML output. + """ + + self._TestXmlOutput( + GTEST_PROGRAM_NAME, + EXPECTED_SHARDED_TEST_XML, + 0, + extra_env={SHARD_INDEX_ENV_VAR: '0', + TOTAL_SHARDS_ENV_VAR: '10'}) + + def _GetXmlOutput(self, gtest_prog_name, extra_args, extra_env, + expected_exit_code): + """ + Returns the xml output generated by running the program gtest_prog_name. + Furthermore, the program's exit code must be expected_exit_code. + """ + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + gtest_prog_name + 'out.xml') + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) + + command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] + + extra_args) + environ_copy = os.environ.copy() + if extra_env: + environ_copy.update(extra_env) + p = gtest_test_utils.Subprocess(command, env=environ_copy) + + if p.terminated_by_signal: + self.assert_(False, + '%s was killed by signal %d' % (gtest_prog_name, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(expected_exit_code, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, expected_exit_code)) + actual = minidom.parse(xml_path) + return actual + + def _TestXmlOutput(self, gtest_prog_name, expected_xml, + expected_exit_code, extra_args=None, extra_env=None): + """ + Asserts that the XML document generated by running the program + gtest_prog_name matches expected_xml, a string containing another + XML document. Furthermore, the program's exit code must be + expected_exit_code. + """ + + actual = self._GetXmlOutput(gtest_prog_name, extra_args or [], + extra_env or {}, expected_exit_code) + expected = minidom.parseString(expected_xml) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) + expected.unlink() + actual.unlink() + + +if __name__ == '__main__': + os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' + gtest_test_utils.Main() diff --git a/3rdparty/gtest/test/gtest_xml_output_unittest_.cc b/3rdparty/gtest/test/gtest_xml_output_unittest_.cc new file mode 100644 index 0000000..c95fd66 --- /dev/null +++ b/3rdparty/gtest/test/gtest_xml_output_unittest_.cc @@ -0,0 +1,188 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Unit test for Google Test XML output. +// +// A user can specify XML output in a Google Test program to run via +// either the GTEST_OUTPUT environment variable or the --gtest_output +// flag. This is used for testing such functionality. +// +// This program will be invoked from a Python unit test. Don't run it +// directly. + +#include "gtest/gtest.h" + +using ::testing::InitGoogleTest; +using ::testing::TestEventListeners; +using ::testing::TestWithParam; +using ::testing::UnitTest; +using ::testing::Test; +using ::testing::Values; + +class SuccessfulTest : public Test { +}; + +TEST_F(SuccessfulTest, Succeeds) { + SUCCEED() << "This is a success."; + ASSERT_EQ(1, 1); +} + +class FailedTest : public Test { +}; + +TEST_F(FailedTest, Fails) { + ASSERT_EQ(1, 2); +} + +class DisabledTest : public Test { +}; + +TEST_F(DisabledTest, DISABLED_test_not_run) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +class SkippedTest : public Test { +}; + +TEST_F(SkippedTest, Skipped) { + GTEST_SKIP(); +} + +TEST(MixedResultTest, Succeeds) { + EXPECT_EQ(1, 1); + ASSERT_EQ(1, 1); +} + +TEST(MixedResultTest, Fails) { + EXPECT_EQ(1, 2); + ASSERT_EQ(2, 3); +} + +TEST(MixedResultTest, DISABLED_test) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +TEST(XmlQuotingTest, OutputsCData) { + FAIL() << "XML output: " + ""; +} + +// Helps to test that invalid characters produced by test code do not make +// it into the XML file. +TEST(InvalidCharactersTest, InvalidCharactersInMessage) { + FAIL() << "Invalid characters in brackets [\x1\x2]"; +} + +class PropertyRecordingTest : public Test { + public: + static void SetUpTestSuite() { RecordProperty("SetUpTestSuite", "yes"); } + static void TearDownTestSuite() { + RecordProperty("TearDownTestSuite", "aye"); + } +}; + +TEST_F(PropertyRecordingTest, OneProperty) { + RecordProperty("key_1", "1"); +} + +TEST_F(PropertyRecordingTest, IntValuedProperty) { + RecordProperty("key_int", 1); +} + +TEST_F(PropertyRecordingTest, ThreeProperties) { + RecordProperty("key_1", "1"); + RecordProperty("key_2", "2"); + RecordProperty("key_3", "3"); +} + +TEST_F(PropertyRecordingTest, TwoValuesForOneKeyUsesLastValue) { + RecordProperty("key_1", "1"); + RecordProperty("key_1", "2"); +} + +TEST(NoFixtureTest, RecordProperty) { + RecordProperty("key", "1"); +} + +void ExternalUtilityThatCallsRecordProperty(const std::string& key, int value) { + testing::Test::RecordProperty(key, value); +} + +void ExternalUtilityThatCallsRecordProperty(const std::string& key, + const std::string& value) { + testing::Test::RecordProperty(key, value); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_int", 1); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); +} + +// Verifies that the test parameter value is output in the 'value_param' +// XML attribute for value-parameterized tests. +class ValueParamTest : public TestWithParam {}; +TEST_P(ValueParamTest, HasValueParamAttribute) {} +TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {} +INSTANTIATE_TEST_SUITE_P(Single, ValueParamTest, Values(33, 42)); + +#if GTEST_HAS_TYPED_TEST +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for typed tests. +template class TypedTest : public Test {}; +typedef testing::Types TypedTestTypes; +TYPED_TEST_SUITE(TypedTest, TypedTestTypes); +TYPED_TEST(TypedTest, HasTypeParamAttribute) {} +#endif + +#if GTEST_HAS_TYPED_TEST_P +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for type-parameterized tests. +template +class TypeParameterizedTestSuite : public Test {}; +TYPED_TEST_SUITE_P(TypeParameterizedTestSuite); +TYPED_TEST_P(TypeParameterizedTestSuite, HasTypeParamAttribute) {} +REGISTER_TYPED_TEST_SUITE_P(TypeParameterizedTestSuite, HasTypeParamAttribute); +typedef testing::Types TypeParameterizedTestSuiteTypes; // NOLINT +INSTANTIATE_TYPED_TEST_SUITE_P(Single, TypeParameterizedTestSuite, + TypeParameterizedTestSuiteTypes); +#endif + +int main(int argc, char** argv) { + InitGoogleTest(&argc, argv); + + if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) { + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_xml_generator()); + } + testing::Test::RecordProperty("ad_hoc_property", "42"); + return RUN_ALL_TESTS(); +} diff --git a/3rdparty/gtest/test/gtest_xml_test_utils.py b/3rdparty/gtest/test/gtest_xml_test_utils.py new file mode 100644 index 0000000..9914a49 --- /dev/null +++ b/3rdparty/gtest/test/gtest_xml_test_utils.py @@ -0,0 +1,196 @@ +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test utilities for gtest_xml_output""" + +import re +from xml.dom import minidom, Node +import gtest_test_utils + +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' + +class GTestXMLTestCase(gtest_test_utils.TestCase): + """ + Base class for tests of Google Test's XML output functionality. + """ + + + def AssertEquivalentNodes(self, expected_node, actual_node): + """ + Asserts that actual_node (a DOM node object) is equivalent to + expected_node (another DOM node object), in that either both of + them are CDATA nodes and have the same value, or both are DOM + elements and actual_node meets all of the following conditions: + + * It has the same tag name as expected_node. + * It has the same set of attributes as expected_node, each with + the same value as the corresponding attribute of expected_node. + Exceptions are any attribute named "time", which needs only be + convertible to a floating-point number and any attribute named + "type_param" which only has to be non-empty. + * It has an equivalent set of child nodes (including elements and + CDATA sections) as expected_node. Note that we ignore the + order of the children as they are not guaranteed to be in any + particular order. + """ + + if expected_node.nodeType == Node.CDATA_SECTION_NODE: + self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType) + self.assertEquals(expected_node.nodeValue, actual_node.nodeValue) + return + + self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType) + self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType) + self.assertEquals(expected_node.tagName, actual_node.tagName) + + expected_attributes = expected_node.attributes + actual_attributes = actual_node .attributes + self.assertEquals( + expected_attributes.length, actual_attributes.length, + 'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % ( + actual_node.tagName, expected_attributes.keys(), + actual_attributes.keys())) + for i in range(expected_attributes.length): + expected_attr = expected_attributes.item(i) + actual_attr = actual_attributes.get(expected_attr.name) + self.assert_( + actual_attr is not None, + 'expected attribute %s not found in element %s' % + (expected_attr.name, actual_node.tagName)) + self.assertEquals( + expected_attr.value, actual_attr.value, + ' values of attribute %s in element %s differ: %s vs %s' % + (expected_attr.name, actual_node.tagName, + expected_attr.value, actual_attr.value)) + + expected_children = self._GetChildren(expected_node) + actual_children = self._GetChildren(actual_node) + self.assertEquals( + len(expected_children), len(actual_children), + 'number of child elements differ in element ' + actual_node.tagName) + for child_id, child in expected_children.items(): + self.assert_(child_id in actual_children, + '<%s> is not in <%s> (in element %s)' % + (child_id, actual_children, actual_node.tagName)) + self.AssertEquivalentNodes(child, actual_children[child_id]) + + identifying_attribute = { + 'testsuites': 'name', + 'testsuite': 'name', + 'testcase': 'name', + 'failure': 'message', + 'property': 'name', + } + + def _GetChildren(self, element): + """ + Fetches all of the child nodes of element, a DOM Element object. + Returns them as the values of a dictionary keyed by the IDs of the + children. For , , , and + elements, the ID is the value of their "name" attribute; for + elements, it is the value of the "message" attribute; for + elements, it is the value of their parent's "name" attribute plus the + literal string "properties"; CDATA sections and non-whitespace + text nodes are concatenated into a single CDATA section with ID + "detail". An exception is raised if any element other than the above + four is encountered, if two child elements with the same identifying + attributes are encountered, or if any other type of node is encountered. + """ + + children = {} + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.tagName == 'properties': + self.assert_(child.parentNode is not None, + 'Encountered element without a parent') + child_id = child.parentNode.getAttribute('name') + '-properties' + else: + self.assert_(child.tagName in self.identifying_attribute, + 'Encountered unknown element <%s>' % child.tagName) + child_id = child.getAttribute( + self.identifying_attribute[child.tagName]) + self.assert_(child_id not in children) + children[child_id] = child + elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: + if 'detail' not in children: + if (child.nodeType == Node.CDATA_SECTION_NODE or + not child.nodeValue.isspace()): + children['detail'] = child.ownerDocument.createCDATASection( + child.nodeValue) + else: + children['detail'].nodeValue += child.nodeValue + else: + self.fail('Encountered unexpected node type %d' % child.nodeType) + return children + + def NormalizeXml(self, element): + """ + Normalizes Google Test's XML output to eliminate references to transient + information that may change from run to run. + + * The "time" attribute of , and + elements is replaced with a single asterisk, if it contains + only digit characters. + * The "timestamp" attribute of elements is replaced with a + single asterisk, if it contains a valid ISO8601 datetime value. + * The "type_param" attribute of elements is replaced with a + single asterisk (if it sn non-empty) as it is the type name returned + by the compiler and is platform dependent. + * The line info reported in the first line of the "message" + attribute and CDATA section of elements is replaced with the + file's basename and a single asterisk for the line number. + * The directory names in file paths are removed. + * The stack traces are removed. + """ + + if element.tagName in ('testsuites', 'testsuite', 'testcase'): + timestamp = element.getAttributeNode('timestamp') + timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$', + '*', timestamp.value) + if element.tagName in ('testsuites', 'testsuite', 'testcase'): + time = element.getAttributeNode('time') + time.value = re.sub(r'^\d+(\.\d+)?$', '*', time.value) + type_param = element.getAttributeNode('type_param') + if type_param and type_param.value: + type_param.value = '*' + elif element.tagName == 'failure': + source_line_pat = r'^.*[/\\](.*:)\d+\n' + # Replaces the source line information with a normalized form. + message = element.getAttributeNode('message') + message.value = re.sub(source_line_pat, '\\1*\n', message.value) + for child in element.childNodes: + if child.nodeType == Node.CDATA_SECTION_NODE: + # Replaces the source line information with a normalized form. + cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue) + # Removes the actual stack trace. + child.nodeValue = re.sub(r'Stack trace:\n(.|\n)*', + 'Stack trace:\n*', cdata) + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.NormalizeXml(child) diff --git a/3rdparty/gtest/test/production.cc b/3rdparty/gtest/test/production.cc new file mode 100644 index 0000000..0f69f6d --- /dev/null +++ b/3rdparty/gtest/test/production.cc @@ -0,0 +1,35 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// This is part of the unit test for gtest_prod.h. + +#include "production.h" + +PrivateCode::PrivateCode() : x_(0) {} diff --git a/3rdparty/gtest/test/production.h b/3rdparty/gtest/test/production.h new file mode 100644 index 0000000..542723b --- /dev/null +++ b/3rdparty/gtest/test/production.h @@ -0,0 +1,54 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// This is part of the unit test for gtest_prod.h. + +#ifndef GTEST_TEST_PRODUCTION_H_ +#define GTEST_TEST_PRODUCTION_H_ + +#include "gtest/gtest_prod.h" + +class PrivateCode { + public: + // Declares a friend test that does not use a fixture. + FRIEND_TEST(PrivateCodeTest, CanAccessPrivateMembers); + + // Declares a friend test that uses a fixture. + FRIEND_TEST(PrivateCodeFixtureTest, CanAccessPrivateMembers); + + PrivateCode(); + + int x() const { return x_; } + private: + void set_x(int an_x) { x_ = an_x; } + int x_; +}; + +#endif // GTEST_TEST_PRODUCTION_H_ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..cd5c027 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.10) +project(cpp-ipc) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") +if(NOT MSVC) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2") +endif() + +include_directories(${CMAKE_SOURCE_DIR}/include) + +set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) +set(gtest_force_shared_crt 1) + +add_subdirectory(src) +add_subdirectory(3rdparty/gtest) +add_subdirectory(test) +add_subdirectory(demo/chat) \ No newline at end of file diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt deleted file mode 100755 index 5791379..0000000 --- a/build/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(cpp-ipc) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") -if(NOT MSVC) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2") -endif() - -add_subdirectory(test) -add_subdirectory(chat) \ No newline at end of file diff --git a/build/chat/CMakeLists.txt b/build/chat/CMakeLists.txt deleted file mode 100644 index 686c633..0000000 --- a/build/chat/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -project(chat) - -include_directories(../../include) -file(GLOB SRC_FILES ../../demo/chat/*.cpp) -file(GLOB HEAD_FILES ../../demo/chat/*.h) -set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../output) - -link_directories(${EXECUTABLE_OUTPUT_PATH}) -add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEAD_FILES}) - -target_link_libraries(${PROJECT_NAME} ipc) -if(NOT MSVC) - target_link_libraries(${PROJECT_NAME} pthread rt) -endif() diff --git a/build/chat/chat.pro b/build/chat/chat.pro deleted file mode 100644 index fe38574..0000000 --- a/build/chat/chat.pro +++ /dev/null @@ -1,19 +0,0 @@ -TEMPLATE = app - -CONFIG += console -CONFIG += c++14 c++1z # may be useless -CONFIG -= app_bundle -CONFIG -= qt - -DESTDIR = ../../output - -INCLUDEPATH += \ - ../../include - -SOURCES += \ - ../../demo/chat/main.cpp - -LIBS += \ - -L$${DESTDIR} -lipc - -unix:LIBS += -lrt -lpthread diff --git a/build/cpp-ipc.pro b/build/cpp-ipc.pro deleted file mode 100644 index 731f38b..0000000 --- a/build/cpp-ipc.pro +++ /dev/null @@ -1,4 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS = ipc test chat -test.depends = ipc -chat.depends = ipc \ No newline at end of file diff --git a/build/ipc/CMakeLists.txt b/build/ipc/CMakeLists.txt deleted file mode 100755 index 15ea026..0000000 --- a/build/ipc/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -project(ipc) - -add_compile_options(-D__IPC_LIBRARY__) - -include_directories(${CMAKE_SOURCE_DIR}/../include ${CMAKE_SOURCE_DIR}/../src) - -if(UNIX) - file(GLOB SRC_FILES ${CMAKE_SOURCE_DIR}/../src/platform/*_linux.cpp) -else() - file(GLOB SRC_FILES ${CMAKE_SOURCE_DIR}/../src/platform/*_win.cpp) -endif() -aux_source_directory(${CMAKE_SOURCE_DIR}/../src SRC_FILES) -file(GLOB HEAD_FILES ${CMAKE_SOURCE_DIR}/../include/*.h ${CMAKE_SOURCE_DIR}/../src/*.inc ${CMAKE_SOURCE_DIR}/../src/memory/*.hpp) - -add_library(${PROJECT_NAME} SHARED ${SRC_FILES} ${HEAD_FILES}) -set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../output) diff --git a/build/ipc/ipc.pro b/build/ipc/ipc.pro deleted file mode 100644 index 6610884..0000000 --- a/build/ipc/ipc.pro +++ /dev/null @@ -1,73 +0,0 @@ -TEMPLATE = lib -TARGET = ipc - -CONFIG -= qt -CONFIG += c++14 c++1z # may be useless - -DEFINES += __IPC_LIBRARY__ -DESTDIR = ../../output - -INCLUDEPATH += \ - ../../include \ - ../../src - -HEADERS += \ - ../../include/export.h \ - ../../include/def.h \ - ../../include/shm.h \ - ../../include/waiter.h \ - ../../include/queue.h \ - ../../include/ipc.h \ - ../../include/rw_lock.h \ - ../../include/tls_pointer.h \ - ../../include/pool_alloc.h \ - ../../include/buffer.h \ - ../../src/memory/alloc.h \ - ../../src/memory/wrapper.h \ - ../../src/memory/resource.h \ - ../../src/platform/detail.h \ - ../../src/platform/waiter_wrapper.h \ - ../../src/circ/elem_def.h \ - ../../src/circ/elem_array.h \ - ../../src/prod_cons.h \ - ../../src/policy.h \ - ../../src/queue.h \ - ../../src/log.h \ - ../../src/id_pool.h \ - ../../src/pimpl.h \ - ../../src/concept.h - -SOURCES += \ - ../../src/shm.cpp \ - ../../src/ipc.cpp \ - ../../src/pool_alloc.cpp \ - ../../src/buffer.cpp \ - ../../src/waiter.cpp - -unix { - -HEADERS += \ - ../../src/platform/waiter_linux.h - -SOURCES += \ - ../../src/platform/shm_linux.cpp \ - ../../src/platform/tls_pointer_linux.cpp - -target.path = /usr/lib -INSTALLS += target - -} # unix - -else:win32 { - -HEADERS += \ - ../../src/platform/to_tchar.h \ - ../../src/platform/waiter_win.h - -SOURCES += \ - ../../src/platform/shm_win.cpp \ - ../../src/platform/tls_pointer_win.cpp - -LIBS += -lKernel32 - -} # else:win32 diff --git a/build/test/CMakeLists.txt b/build/test/CMakeLists.txt deleted file mode 100755 index 2544ced..0000000 --- a/build/test/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -project(test-ipc) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -find_package(Qt5 COMPONENTS Core Test REQUIRED) - -if(NOT MSVC) - add_compile_options(-Wno-attributes -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-function) -endif() - -include_directories(../../include ../../src ../../test) -file(GLOB SRC_FILES ../../test/*.cpp) -file(GLOB HEAD_FILES ../../test/*.h) -set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../output) - -link_directories(${EXECUTABLE_OUTPUT_PATH} ${CMAKE_SOURCE_DIR}/../test/gperftools) -add_subdirectory(../ipc ipc.out) - -add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEAD_FILES}) -target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Test ipc) -if(NOT MSVC) - target_link_libraries(${PROJECT_NAME} pthread rt) -endif() - -#target_link_libraries(${PROJECT_NAME} tcmalloc_minimal) diff --git a/build/test/test.pro b/build/test/test.pro deleted file mode 100755 index e637248..0000000 --- a/build/test/test.pro +++ /dev/null @@ -1,40 +0,0 @@ -TEMPLATE = app -TARGET = test-ipc - -QT += core testlib -QT -= gui - -CONFIG += console -CONFIG += c++14 c++1z # may be useless -CONFIG -= app_bundle - -DESTDIR = ../../output - -!msvc:QMAKE_CXXFLAGS += \ - -Wno-attributes \ - -Wno-missing-field-initializers \ - -Wno-unused-variable \ - -Wno-unused-function - -INCLUDEPATH += \ - ../../test \ - ../../include \ - ../../src - -HEADERS += \ - ../../test/test.h - -SOURCES += \ - ../../test/main.cpp \ - ../../test/test_shm.cpp \ - ../../test/test_mem.cpp \ - ../../test/test_circ.cpp \ - ../../test/test_waiter.cpp \ - ../../test/test_ipc.cpp - -LIBS += \ - -L$${DESTDIR} -lipc - -unix:LIBS += \ -# -L../../test/gperftools -ltcmalloc_minimal \ - -lrt -lpthread diff --git a/demo/chat/CMakeLists.txt b/demo/chat/CMakeLists.txt new file mode 100644 index 0000000..8dfabce --- /dev/null +++ b/demo/chat/CMakeLists.txt @@ -0,0 +1,11 @@ +project(chat) + +file(GLOB SRC_FILES ./*.cpp) +file(GLOB HEAD_FILES ./*.h) + +add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEAD_FILES}) + +target_link_libraries(${PROJECT_NAME} ipc) +if(NOT MSVC) + target_link_libraries(${PROJECT_NAME} pthread rt) +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..36bdfbb --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,18 @@ +project(ipc) + +add_compile_options(-D__IPC_LIBRARY__) + +include_directories( + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/src +) + +if(UNIX) + file(GLOB SRC_FILES ${CMAKE_SOURCE_DIR}/src/platform/*_linux.cpp) +else() + file(GLOB SRC_FILES ${CMAKE_SOURCE_DIR}/src/platform/*_win.cpp) +endif() +aux_source_directory(${CMAKE_SOURCE_DIR}/src SRC_FILES) +file(GLOB HEAD_FILES ${CMAKE_SOURCE_DIR}/include/*.h ${CMAKE_SOURCE_DIR}/src/*.inc ${CMAKE_SOURCE_DIR}/src/memory/*.hpp) + +add_library(${PROJECT_NAME} SHARED ${SRC_FILES} ${HEAD_FILES}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..f7dd881 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,29 @@ +project(test-ipc) + +if(NOT MSVC) + add_compile_options( + -Wno-attributes + -Wno-missing-field-initializers + -Wno-unused-variable + -Wno-unused-function) +endif() + +include_directories( + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_SOURCE_DIR}/test + ${CMAKE_SOURCE_DIR}/3rdparty + ${CMAKE_SOURCE_DIR}/3rdparty/gtest/include +) + +file(GLOB SRC_FILES ${CMAKE_SOURCE_DIR}/test/*.cpp) +file(GLOB HEAD_FILES ${CMAKE_SOURCE_DIR}/test/*.h) + +add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEAD_FILES}) + +link_directories(${CMAKE_SOURCE_DIR}/3rdparty/gperftools) +target_link_libraries(${PROJECT_NAME} gtest gtest_main ipc) +#target_link_libraries(${PROJECT_NAME} tcmalloc_minimal) +if(NOT MSVC) + target_link_libraries(${PROJECT_NAME} pthread rt) +endif() diff --git a/test/gperftools/libtcmalloc_minimal.so b/test/gperftools/libtcmalloc_minimal.so deleted file mode 100755 index 9f3c3fce1070db4c74df59aee428aec94e311d36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1414680 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

hY?9=d74d2%AgoZ=*=<+qZM8l~X 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

e^THA04oV}YY+QyDO^jT zcWUBF*k^bOCRP*-*@Ny3UDOfGApXY`pw~&I+XG0ae<5n^PudT`#jwwT(P;lbN*btP zpN55$eIfwF8lXz5?crH3NdcFR)~IwUW;T(+!<#3{dJDmcGvsPfN5%qEgnAf2yc4X)`QkO+Q* zAOXd~qvT;YtGES??Y@pfL^xv*@FENrQXSGSGj@$I8?z#+#{0-xnp6L_ub>F!is4*FicAr}Fy$ zS^$cSS;FF08sc{46-PlNrHo)IB+Wg_{L{Fm-!r*x#obC!obdmw5fZ)nj1yVsB2htH z)Y~Ke6);)uFt;Qkd>uiA)gX*zRYh76a}HBtnc1`NVssZilW@Cd)AB+F&PAPM4&|B( zyo5T)oWPY5I2#7aT*USa41<|7H*kdnK14|~_q|T)2FAkxnI|W+-)9p17e8hHaVVO3 zi;EN(4#hGbv8Ih(Z7d?Qk2h9B)Zxfeq+%>CqVd!gK>Dv(p>8$#vx#K=cmnAMzJwlD zTCo0dw+OtJ(Hx0}JwhytD@|}Ri~F`UkP%C3X{4@+WJR}wxY30$Q<5zVaiZ}-;^%G* z){12l(uO5Pqyw4U@1mA8(L}P2V-1iwZSYJ`w;7Unf%T$xBN~rs20@E`uoPuwk5Q6t zoJC_Q`_gLzb>=^~k>wb}GglN0&`98Xq;WS7Zq4oswQJQp8-Lac5;vZksPl@XbT4sU zd((it+orRYm}(+fZ@&z~Y^y&Ctz?Rs&;M&?qOpa{wm+_imbQY@jpBTMq?$g|5(@w> z?JhU+G4?|;Kc9O=Bj1>Lack#$r13h^|J2ftHRl0wrm)=JROM$UWNV}l7OD!#DwzPe z=c|2$h^iE8sxBJ0q&obn8-^ZMrU}7wSX>Zgbh&++E&#nvrI4&@wP22KZ(;c-UpK{> zGCk^<;zZ-cRJ*@cT&lBJPf3<>7A?u*w|5z}yWd2zTCYMDf2`UD>Q@xY_i5wx#Q*C@ z43VttAB3!DNl!@GC%e$#7%A|Efn-g_L*2}O)?lobl_{3>WO0oGQjy3@e*L|gE6L`B zb3bRc9MPyBYCW@{{3ccX7iXDEB=_E%$y6}gels9cpNjmVj^8h8l5z`1M2>hwT)wq) zMuU)9M&7%IT~g-WAh~7b887UnQbdJ?xbV%JGwKq!<>g3pP1O8lqo!0%6=V$hCyq!Z zF5ekBF+TyA1HTRsD~rd%^b3ThCtQ8&_|mV5;PjyO+T@`;>>XiJ%OjHTNia z7WXDcJSQ&sL}DYY1n{7;_t9RW{{RNPXT zUFBC7G4moi-zbwUz1JhUo6JFddE7w4ztNv~x)75#81pY0JpI#Ay7sZ1C_I|NZ6+fe zmrdar6ds8iqkVmvw7Hg0xHa*U=%0AHHgJ04C)0oPbnT|_2;w)Tw**~B5gxH&6v8PV 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%0A(RjdO$V14x&K<5@~kgxd_^sn3gnU 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�B zM@2o4qo&4D(O|?;gK<J0TKm~q92FJIw~&8XTAd-Ffn?`qgT_0GE#Zb)Gw{=%t9~t%#{W(&jfCw8$JjbOFg6 zJ|+W;BBJFS7coE)FIo}PfTYce7--WXbNCbqBy;%W3@nO>&cwKgDHQRN6|pCfv{?~T z5=HD87cnI+BD&ewN14bR9>aDK+RdhV1VRI`kPS;A6b(yUQEx0{lUxWzlN<{*Vj)|y zg;2DO#X>EFIPb#E1`wg-DHu!jAw^u``asktHCf$mHkimSh#Sh7+@{gCbyWvmQs((f z3}TQHHybe}n$egN%~ec^X2DaEsou7Dq)rkE5o>QPE(;QG;<*G(JA6Gd{$PSI?4z z<|D(P5m$^zbX||5>O^g3;~3p+%s)TB*?3Mi+-v|_`i3SvUI89zU!i4x5!|1hu~sYA z8cb=$FN$oeOxyD{QF!IU=ld^L`{>#`+ax3|@ivJM8&&%VQA=5u2Y{={HKulCPn$-e z9{uH!d!wQzC5oC-)fd9UmRk7@1RU(B+8$nxL(i$2?2Q>Pod}PzfooVNr^kQguBL;K z6K~KU4Rtm9=YqF<^O&dgO-lSH1EFIR%JaXHug_;>!}u~hWorsdC&HQnu4J7|tf`mPBgl!FM;hwTHKl&UYYI9xp}gR{d`+!nGt&p0 zD_8c92!X#TUwCG{WF`&PW$IrWLVsn`Zvjs+S3eM?Y|X~|AX;l!U;~Ii_)r5ZYsIez z$6CFy*3^_%Z?yNK^^C?ce8d3Gvr?x48MXWq3oWWmyxfcYSksyUq`q+P2Sh0UEaFe; z-KDXwZ0gO*C)5qbBRlQE#3fb|VSiP4cn4+ntTrtK!np+8%=*&;ZY$TA+Mzvd8b!|N zjbnxx$*eozA}o4?l~M`M?%Aupt$~9Llj{eSLu4*jK_|jy0Nma>nb-_A)X6OggX%}T89>J-l*eo8PPB#G2fV~)HM^S7y0RbwzdeNLhbqp{N@ZvzGPF_|;!PsX z&`4!yBr-Ho8RD&DL-lZH+3frPf8GWpS|vU#To#F%YEgRtKPA_g+EG1i8ijgvlY=^x zu%stcy|uBKv`L?>*S+N1$MS}MbcqJ}6Q5Yfi{?o3!W~uns9zr(DwhT>s;C1$W7Q^3 zr2!p;oY=FFhC1X_+PLyw4LUZVJm=i}y7~>-aIXe@)m;6+u_`scSEIFzyov90k^hcq zwG3L+;3#CVoy%%0AAMf?k!0_eOGd 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

EIdOyz0j;i*Zddje-nLI@Q%v!4cY5t?~{E< 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 RchJCZ{Pu?M>jp5c`vOahP2m6l diff --git a/test/gperftools/libtcmalloc_minimal.so.4 b/test/gperftools/libtcmalloc_minimal.so.4 deleted file mode 120000 index 74cc460..0000000 --- a/test/gperftools/libtcmalloc_minimal.so.4 +++ /dev/null @@ -1 +0,0 @@ -libtcmalloc_minimal.so \ No newline at end of file diff --git a/test/gperftools/libtcmalloc_minimal.so.4.5.3 b/test/gperftools/libtcmalloc_minimal.so.4.5.3 deleted file mode 120000 index 74cc460..0000000 --- a/test/gperftools/libtcmalloc_minimal.so.4.5.3 +++ /dev/null @@ -1 +0,0 @@ -libtcmalloc_minimal.so \ No newline at end of file diff --git a/test/main.cpp b/test/main.cpp deleted file mode 100644 index 605a810..0000000 --- a/test/main.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include -#include - -#include "test.h" - -namespace { - -QVector* suites__ = nullptr; - -} // internal-linkage - -TestSuite::TestSuite() { - static struct __ { - QVector suites_; - __() { suites__ = &suites_; } - } _; - _.suites_ << this; -} - -const char* TestSuite::name() const { - return ""; -} - -void TestSuite::initTestCase() { - qDebug() << QString("#### Start: %1 ####").arg(name()); -} - -int main(int argc, char* argv[]) { - QCoreApplication app(argc, argv); - Q_UNUSED(app) - -// QThread::sleep(5); - - int failed_count = 0; - for (const auto& suite : (*suites__)) { - if (QTest::qExec(suite, argc, argv) != 0) - ++failed_count; - } - return failed_count; -} diff --git a/test/test.h b/test/test.h index 49b630e..ad59f3d 100755 --- a/test/test.h +++ b/test/test.h @@ -1,7 +1,5 @@ #pragma once -#include - #include #include #include @@ -14,23 +12,11 @@ # include // abi::__cxa_demangle #endif/*__GNUC__*/ +#include "gtest/gtest.h" + #include "capo/stopwatch.hpp" #include "capo/spin_lock.hpp" -class TestSuite : public QObject -{ - Q_OBJECT - -public: - explicit TestSuite(); - -protected: - virtual const char* name() const; - -protected slots: - virtual void initTestCase(); -}; - struct test_stopwatch { capo::stopwatch<> sw_; std::atomic_flag started_ = ATOMIC_FLAG_INIT; diff --git a/test/test_circ.cpp b/test/test_circ.cpp index d076eac..98ab3b8 100755 --- a/test/test_circ.cpp +++ b/test/test_circ.cpp @@ -64,10 +64,10 @@ struct test_verify> { // std::cout << d << " "; //} //std::cout << std::endl; - QCOMPARE(vec.size(), static_cast(Loops)); + EXPECT_EQ(vec.size(), static_cast(Loops)); int i = 0; for (int d : vec) { - QCOMPARE(i, d); + EXPECT_EQ(i, d); ++i; } } @@ -90,8 +90,8 @@ struct test_verify> : test_veri sum += d; } } - QCOMPARE(datas.size(), static_cast(Loops)); - QCOMPARE(sum, (Loops * std::uint64_t(Loops - 1)) / 2); + EXPECT_EQ(datas.size(), static_cast(Loops)); + EXPECT_EQ(sum, (Loops * std::uint64_t(Loops - 1)) / 2); } } }; @@ -191,7 +191,7 @@ struct test_cq> { cn_t* connect() { cn_t* queue = new cn_t { "test-ipc-queue" }; - [&] { QVERIFY(queue->connect()); } (); + [&] { EXPECT_TRUE(queue->connect()); } (); return queue; } @@ -232,44 +232,21 @@ struct test_cq> { namespace { -class Unit : public TestSuite { - Q_OBJECT - - const char* name() const { - return "test_circ"; - } - -private slots: - void initTestCase(); - void test_inst(); - void test_prod_cons_1v1(); - void test_prod_cons_1v3(); - void test_prod_cons_performance(); - void test_queue(); -//}; -} unit__; - -#include "test_circ.moc" - constexpr int LoopCount = 1000000; //constexpr int LoopCount = 1000/*0000*/; -void Unit::initTestCase() { - TestSuite::initTestCase(); -} - -void Unit::test_inst() { - std::cout << "cq_t::head_size = " << cq_t::head_size << std::endl; - std::cout << "cq_t::data_size = " << cq_t::data_size << std::endl; - std::cout << "cq_t::elem_size = " << cq_t::elem_size << std::endl; +TEST(Circ, init) { + std::cout << "cq_t::head_size = " << cq_t::head_size << std::endl; + std::cout << "cq_t::data_size = " << cq_t::data_size << std::endl; + std::cout << "cq_t::elem_size = " << cq_t::elem_size << std::endl; std::cout << "cq_t::block_size = " << cq_t::block_size << std::endl; - QCOMPARE(static_cast(cq_t::data_size), sizeof(msg_t)); + EXPECT_EQ(static_cast(cq_t::data_size), sizeof(msg_t)); std::cout << "sizeof(ea_t) = " << sizeof(cq_t) << std::endl; } -void Unit::test_prod_cons_1v1() { +TEST(Circ, prod_cons_1v1) { ea_t< sizeof(msg_t), pc_t @@ -307,7 +284,7 @@ void Unit::test_prod_cons_1v1() { benchmark_prod_cons<2, 1, LoopCount, void>(&el_arr_mmb); } -void Unit::test_prod_cons_1v3() { +TEST(Circ, prod_cons_1v3) { ea_t< sizeof(msg_t), pc_t @@ -337,7 +314,7 @@ void Unit::test_prod_cons_1v3() { benchmark_prod_cons<1, 3, LoopCount, void>(&el_arr_mmb); } -void Unit::test_prod_cons_performance() { +TEST(Circ, prod_cons_performance) { ea_t< sizeof(msg_t), pc_t @@ -387,18 +364,18 @@ void Unit::test_prod_cons_performance() { }); } -void Unit::test_queue() { +TEST(Circ, queue) { using queue_t = ipc::queue >>; queue_t queue; - QVERIFY(!queue.push(msg_t { 1, 2 })); + EXPECT_TRUE(!queue.push(msg_t { 1, 2 })); msg_t msg {}; - QVERIFY(!queue.pop(msg)); - QCOMPARE(msg, (msg_t {})); - QVERIFY(sizeof(decltype(queue)::elems_t) <= sizeof(cq_t)); + EXPECT_TRUE(!queue.pop(msg)); + EXPECT_EQ(msg, (msg_t {})); + EXPECT_TRUE(sizeof(decltype(queue)::elems_t) <= sizeof(cq_t)); ipc::detail::static_for<16>([](auto index) { benchmark_prod_cons<1, decltype(index)::value + 1, LoopCount>((queue_t*)nullptr); diff --git a/test/test_ipc.cpp b/test/test_ipc.cpp index d8deb48..98490be 100755 --- a/test/test_ipc.cpp +++ b/test/test_ipc.cpp @@ -51,10 +51,10 @@ struct test_verify { void verify(int /*N*/, int /*Loops*/) { std::cout << "verifying..." << std::endl; for (auto& c_dats : list_) { - QCOMPARE(datas__.size(), c_dats.size()); + EXPECT_EQ(datas__.size(), c_dats.size()); std::size_t i = 0; for (auto& d : c_dats) { - QCOMPARE(datas__[i++], d); + EXPECT_EQ(datas__[i++], d); } } } @@ -87,7 +87,7 @@ struct test_cq { do { auto msg = cn.recv(); if (msg.size() < 2) { - QCOMPARE(msg, ipc::buff_t('\0')); + EXPECT_EQ(msg, ipc::buff_t('\0')); return; } proc(std::move(msg)); @@ -101,9 +101,9 @@ struct test_cq { void send(cn_t& cn, const std::array& info) { int n = info[1]; if (n < 0) { - /*QVERIFY*/(cn.send(ipc::buff_t('\0'))); + /*EXPECT_TRUE*/(cn.send(ipc::buff_t('\0'))); } - else /*QVERIFY*/(cn.send(datas__[static_cast(n)])); + else /*EXPECT_TRUE*/(cn.send(datas__[static_cast(n)])); } }; @@ -133,7 +133,7 @@ struct test_cq { do { auto msg = cn.recv(); if (msg.size() < 2) { - QCOMPARE(msg, ipc::buff_t('\0')); + EXPECT_EQ(msg, ipc::buff_t('\0')); return; } proc(std::move(msg)); @@ -153,64 +153,37 @@ struct test_cq { } _(cn, m_); int n = info[1]; if (n < 0) { - /*QVERIFY*/(cn.send(ipc::buff_t('\0'))); + /*EXPECT_TRUE*/(cn.send(ipc::buff_t('\0'))); } - else /*QVERIFY*/(cn.send(datas__[static_cast(n)])); + else /*EXPECT_TRUE*/(cn.send(datas__[static_cast(n)])); } }; namespace { -class Unit : public TestSuite { - Q_OBJECT +struct Init { + Init() { + capo::random<> rdm { DataMin, DataMax }; + capo::random<> bit { 0, (std::numeric_limits::max)() }; - const char* name() const { - return "test_ipc"; - } - -private slots: - void initTestCase(); - void cleanupTestCase(); - - void test_rw_lock(); - void test_route(); - void test_route_rtt(); - void test_route_performance(); - void test_channel(); - void test_channel_rtt(); - void test_channel_performance(); -// }; -} unit__; - -#include "test_ipc.moc" - -void Unit::initTestCase() { - TestSuite::initTestCase(); - - capo::random<> rdm { DataMin, DataMax }; - capo::random<> bit { 0, (std::numeric_limits::max)() }; - - for (int i = 0; i < LoopCount; ++i) { - std::size_t n = static_cast(rdm()); - ipc::buff_t buff { - new ipc::byte_t[n], n, - [](void* p, std::size_t) { - delete [] static_cast(p); + for (int i = 0; i < LoopCount; ++i) { + std::size_t n = static_cast(rdm()); + ipc::buff_t buff { + new ipc::byte_t[n], n, + [](void* p, std::size_t) { + delete [] static_cast(p); + } + }; + for (std::size_t k = 0; k < buff.size(); ++k) { + static_cast(buff.data())[k] = static_cast(bit()); } - }; - for (std::size_t k = 0; k < buff.size(); ++k) { - static_cast(buff.data())[k] = static_cast(bit()); + datas__.emplace_back(std::move(buff)); } - datas__.emplace_back(std::move(buff)); } -} - -void Unit::cleanupTestCase() { - datas__.clear(); -} +} init__; template -constexpr T acc(T b, T e) { +constexpr T acc(T b, T e) noexcept { return (e + b) * (e - b + 1) / 2; } @@ -241,7 +214,7 @@ void benchmark_lc() { int x = -1; { std::shared_lock guard { lc }; -// QVERIFY(!wf); +// EXPECT_TRUE(!wf); if (cnt < datas.size()) { x = datas[cnt]; } @@ -259,7 +232,7 @@ void benchmark_lc() { } std::uint64_t sum = 0; for (int i : seq) sum += static_cast(i); - QCOMPARE(sum, acc(1, Loops) * W); + EXPECT_EQ(sum, acc(1, Loops) * W); }); } @@ -300,7 +273,7 @@ void test_lock_performance() { benchmark_lc(); } -void Unit::test_rw_lock() { +TEST(IPC, rw_lock) { // test_lock_performance<1, 1>(); // test_lock_performance<4, 4>(); // test_lock_performance<1, 8>(); @@ -312,7 +285,7 @@ void test_prod_cons() { benchmark_prod_cons>((T*)nullptr); } -void Unit::test_route() { +TEST(IPC, route) { // return; std::vector const datas = { "hello!", @@ -330,8 +303,8 @@ void Unit::test_route() { for (std::size_t i = 0; i < datas.size(); ++i) { ipc::buff_t dd = cc.recv(); std::cout << "recv: " << (char*)dd.data() << std::endl; - QCOMPARE(dd.size(), std::strlen(datas[i]) + 1); - QVERIFY(std::memcmp(dd.data(), datas[i], dd.size()) == 0); + EXPECT_EQ(dd.size(), std::strlen(datas[i]) + 1); + EXPECT_TRUE(std::memcmp(dd.data(), datas[i], dd.size()) == 0); } }}; @@ -342,7 +315,7 @@ void Unit::test_route() { } for (std::size_t i = 0; i < datas.size(); ++i) { std::cout << "sending: " << datas[i] << std::endl; - QVERIFY(cc.send(datas[i])); + EXPECT_TRUE(cc.send(datas[i])); } }}; @@ -352,7 +325,7 @@ void Unit::test_route() { test_prod_cons(); // test & verify } -void Unit::test_route_rtt() { +TEST(IPC, route_rtt) { // return; test_stopwatch sw; @@ -381,7 +354,7 @@ void Unit::test_route_rtt() { //std::cout << "sent: " << i << "-[" << datas__[i].size() << "]" << std::endl; /*auto dd = */cr.recv(); // if (dd.size() != 1 || dd[0] != 'a') { -// QVERIFY(false); +// EXPECT_TRUE(false); // } } cc.send(ipc::buff_t('\0')); @@ -392,7 +365,7 @@ void Unit::test_route_rtt() { t2.join(); } -void Unit::test_route_performance() { +TEST(IPC, route_performance) { // return; ipc::detail::static_for<8>([](auto index) { test_prod_cons(); @@ -400,7 +373,7 @@ void Unit::test_route_performance() { // test_prod_cons(); // test & verify } -void Unit::test_channel() { +TEST(IPC, channel) { // return; int fail_v = 0; @@ -436,10 +409,10 @@ void Unit::test_channel() { t2.join(); - QCOMPARE(fail_v, 0); + EXPECT_EQ(fail_v, 0); } -void Unit::test_channel_rtt() { +TEST(IPC, channel_rtt) { // return; test_stopwatch sw; @@ -471,7 +444,7 @@ void Unit::test_channel_rtt() { /*auto dd = */cc.recv(); //if (dd.size() != 1 || dd.data()[0] != 'a') { // std::cout << "recv ack fail: " << i << "-[" << dd.size() << "]" << std::endl; - // QVERIFY(false); + // EXPECT_TRUE(false); //} } cc.send(ipc::buff_t('\0')); @@ -482,7 +455,7 @@ void Unit::test_channel_rtt() { t2.join(); } -void Unit::test_channel_performance() { +TEST(IPC, channel_performance) { // return; ipc::detail::static_for<8>([](auto index) { test_prod_cons(); diff --git a/test/test_mem.cpp b/test/test_mem.cpp index a6a99c2..8cee022 100755 --- a/test/test_mem.cpp +++ b/test/test_mem.cpp @@ -15,24 +15,6 @@ namespace { -class Unit : public TestSuite { - Q_OBJECT - - const char* name() const { - return "test_mem"; - } - -private slots: - void initTestCase(); - - void test_static_alloc(); - void test_pool_alloc(); - void test_tc_alloc(); -}; -// } unit__; - -#include "test_mem.moc" - constexpr int DataMin = 4; constexpr int DataMax = 256; constexpr int LoopCount = 4194304; @@ -100,14 +82,14 @@ struct alloc_random : alloc_ix_t> { } }; -void Unit::initTestCase() { - TestSuite::initTestCase(); - - capo::random<> rdm { DataMin, DataMax }; - for (int i = 0; i < LoopCount; ++i) { - sizes__.emplace_back(static_cast(rdm())); +struct Init { + Init() { + capo::random<> rdm{ DataMin, DataMax }; + for (int i = 0; i < LoopCount; ++i) { + sizes__.emplace_back(static_cast(rdm())); + } } -} +} init__; template void benchmark_alloc() { @@ -234,14 +216,14 @@ struct test_performance { // } // }; -void Unit::test_static_alloc() { +TEST(Memory, static_alloc) { // test_performance::start(); // test_performance::start(); // test_performance::start(); // test_performance::start(); } -void Unit::test_pool_alloc() { +TEST(Memory, pool_alloc) { test_performance::start(); test_performance::start(); @@ -251,7 +233,7 @@ void Unit::test_pool_alloc() { test_performance::start(); } -void Unit::test_tc_alloc() { +TEST(Memory, tc_alloc) { // test_performance::start(); // test_performance::start(); // test_performance::start(); diff --git a/test/test_shm.cpp b/test/test_shm.cpp index 2ba1b9f..f386cea 100755 --- a/test/test_shm.cpp +++ b/test/test_shm.cpp @@ -9,90 +9,67 @@ using namespace ipc::shm; namespace { -class Unit : public TestSuite { - Q_OBJECT - - const char* name() const { - return "test_shm"; - } - -private slots: - void cleanupTestCase(); - - void test_acquire(); - void test_release(); - void test_get(); - void test_hello(); - void test_mt(); -} unit__; - -#include "test_shm.moc" - handle shm_hd__; -void Unit::cleanupTestCase() { +TEST(SHM, acquire) { + EXPECT_TRUE(!shm_hd__.valid()); + + EXPECT_TRUE(shm_hd__.acquire("my-test-1", 1024)); + EXPECT_TRUE(shm_hd__.valid()); + EXPECT_EQ(shm_hd__.name(), "my-test-1"); + + EXPECT_TRUE(shm_hd__.acquire("my-test-2", 2048)); + EXPECT_TRUE(shm_hd__.valid()); + EXPECT_EQ(shm_hd__.name(), "my-test-2"); + + EXPECT_TRUE(shm_hd__.acquire("my-test-3", 4096)); + EXPECT_TRUE(shm_hd__.valid()); + EXPECT_EQ(shm_hd__.name(), "my-test-3"); +} + +TEST(SHM, release) { + EXPECT_TRUE(shm_hd__.valid()); shm_hd__.release(); + EXPECT_TRUE(!shm_hd__.valid()); } -void Unit::test_acquire() { - QVERIFY(!shm_hd__.valid()); - - QVERIFY(shm_hd__.acquire("my-test-1", 1024)); - QVERIFY(shm_hd__.valid()); - QCOMPARE(shm_hd__.name(), "my-test-1"); - - QVERIFY(shm_hd__.acquire("my-test-2", 2048)); - QVERIFY(shm_hd__.valid()); - QCOMPARE(shm_hd__.name(), "my-test-2"); - - QVERIFY(shm_hd__.acquire("my-test-3", 4096)); - QVERIFY(shm_hd__.valid()); - QCOMPARE(shm_hd__.name(), "my-test-3"); -} - -void Unit::test_release() { - QVERIFY(shm_hd__.valid()); - shm_hd__.release(); - QVERIFY(!shm_hd__.valid()); -} - -void Unit::test_get() { - QVERIFY(shm_hd__.get() == nullptr); - QVERIFY(shm_hd__.acquire("my-test", 1024)); +TEST(SHM, get) { + EXPECT_TRUE(shm_hd__.get() == nullptr); + EXPECT_TRUE(shm_hd__.acquire("my-test", 1024)); auto mem = shm_hd__.get(); - QVERIFY(mem != nullptr); - QVERIFY(mem == shm_hd__.get()); + EXPECT_TRUE(mem != nullptr); + EXPECT_TRUE(mem == shm_hd__.get()); std::uint8_t buf[1024] = {}; - QVERIFY(memcmp(mem, buf, sizeof(buf)) == 0); + EXPECT_TRUE(memcmp(mem, buf, sizeof(buf)) == 0); handle shm_other(shm_hd__.name(), shm_hd__.size()); - QVERIFY(shm_other.get() != shm_hd__.get()); + EXPECT_TRUE(shm_other.get() != shm_hd__.get()); } -void Unit::test_hello() { +TEST(SHM, hello) { auto mem = shm_hd__.get(); - QVERIFY(mem != nullptr); + EXPECT_TRUE(mem != nullptr); constexpr char hello[] = "hello!"; std::memcpy(mem, hello, sizeof(hello)); - QCOMPARE((char*)shm_hd__.get(), hello); + EXPECT_EQ((char*)shm_hd__.get(), hello); shm_hd__.release(); - QVERIFY(shm_hd__.get() == nullptr); - QVERIFY(shm_hd__.acquire("my-test", 1024)); + EXPECT_TRUE(shm_hd__.get() == nullptr); + EXPECT_TRUE(shm_hd__.acquire("my-test", 1024)); mem = shm_hd__.get(); - QVERIFY(mem != nullptr); + EXPECT_TRUE(mem != nullptr); std::uint8_t buf[1024] = {}; - QVERIFY(memcmp(mem, buf, sizeof(buf)) == 0); + EXPECT_TRUE(memcmp(mem, buf, sizeof(buf)) == 0); std::memcpy(mem, hello, sizeof(hello)); - QCOMPARE((char*)shm_hd__.get(), hello); + EXPECT_EQ((char*)shm_hd__.get(), hello); } -void Unit::test_mt() { +TEST(SHM, mt) { std::thread { [] { handle shm_mt(shm_hd__.name(), shm_hd__.size()); @@ -100,15 +77,15 @@ void Unit::test_mt() { shm_hd__.release(); constexpr char hello[] = "hello!"; - QCOMPARE((char*)shm_mt.get(), hello); + EXPECT_EQ((char*)shm_mt.get(), hello); } }.join(); - QVERIFY(shm_hd__.get() == nullptr); - QVERIFY(!shm_hd__.valid()); + EXPECT_TRUE(shm_hd__.get() == nullptr); + EXPECT_TRUE(!shm_hd__.valid()); - QVERIFY(shm_hd__.acquire("my-test", 1024)); + EXPECT_TRUE(shm_hd__.acquire("my-test", 1024)); std::uint8_t buf[1024] = {}; - QVERIFY(memcmp(shm_hd__.get(), buf, sizeof(buf)) == 0); + EXPECT_TRUE(memcmp(shm_hd__.get(), buf, sizeof(buf)) == 0); } } // internal-linkage diff --git a/test/test_waiter.cpp b/test/test_waiter.cpp index ed91873..2486736 100755 --- a/test/test_waiter.cpp +++ b/test/test_waiter.cpp @@ -6,38 +6,25 @@ namespace { -class Unit : public TestSuite { - Q_OBJECT - - const char* name() const { - return "test_waiter"; - } - -private slots: - void test_broadcast(); -} unit__; - -#include "test_waiter.moc" - -void Unit::test_broadcast() { +TEST(Waiter, broadcast) { ipc::detail::waiter w; std::thread ts[10]; for (auto& t : ts) { t = std::thread([&w] { ipc::detail::waiter_wrapper wp { &w }; - QVERIFY(wp.open("test-ipc-waiter")); - QVERIFY(wp.wait_if([] { return true; })); + EXPECT_TRUE(wp.open("test-ipc-waiter")); + EXPECT_TRUE(wp.wait_if([] { return true; })); wp.close(); }); } ipc::detail::waiter_wrapper wp { &w }; - QVERIFY(wp.open("test-ipc-waiter")); + EXPECT_TRUE(wp.open("test-ipc-waiter")); std::cout << "waiting for broadcast...\n"; std::this_thread::sleep_for(std::chrono::seconds(1)); - QVERIFY(wp.broadcast()); + EXPECT_TRUE(wp.broadcast()); for (auto& t : ts) t.join(); wp.close();

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