mirror of
https://github.com/google/googletest.git
synced 2025-01-21 15:11:57 +08:00
Merge branch 'fix_death_test_child_mingw_wer_issue1116' of https://github.com/tanzislam/googletest into fix_death_test_child_mingw_wer_issue1116
This commit is contained in:
commit
6d089311ca
16
.gitignore
vendored
16
.gitignore
vendored
@ -22,3 +22,19 @@ Win32-Debug/
|
||||
Win32-Release/
|
||||
x64-Debug/
|
||||
x64-Release/
|
||||
|
||||
# Ignore autoconf / automake files
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
configure
|
||||
build-aux/
|
||||
autom4te.cache/
|
||||
googletest/m4/libtool.m4
|
||||
googletest/m4/ltoptions.m4
|
||||
googletest/m4/ltsugar.m4
|
||||
googletest/m4/ltversion.m4
|
||||
googletest/m4/lt~obsolete.m4
|
||||
|
||||
# Ignore generated directories.
|
||||
googlemock/fused-src/
|
||||
googletest/fused-src/
|
||||
|
19
.travis.yml
19
.travis.yml
@ -12,40 +12,47 @@ matrix:
|
||||
include:
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
sudo: true
|
||||
cache:
|
||||
sudo : true
|
||||
install: ./ci/install-linux.sh && ./ci/log-config.sh
|
||||
script: ./ci/build-linux-bazel.sh
|
||||
- os: linux
|
||||
compiler: clang
|
||||
sudo: true
|
||||
cache:
|
||||
sudo : true
|
||||
install: ./ci/install-linux.sh && ./ci/log-config.sh
|
||||
script: ./ci/build-linux-bazel.sh
|
||||
- os: linux
|
||||
group: deprecated-2017Q4
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Debug VERBOSE=1
|
||||
install: ./ci/install-linux.sh && ./ci/log-config.sh
|
||||
script: ./ci/build-linux-autotools.sh
|
||||
- os: linux
|
||||
group: deprecated-2017Q4
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
|
||||
env: BUILD_TYPE=Debug VERBOSE=1 CXX_FLAGS=-std=c++11
|
||||
- os: linux
|
||||
group: deprecated-2017Q4
|
||||
compiler: clang
|
||||
env: BUILD_TYPE=Debug VERBOSE=1
|
||||
- os: linux
|
||||
group: deprecated-2017Q4
|
||||
compiler: clang
|
||||
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Debug VERBOSE=1
|
||||
if: type != pull_request
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
|
||||
if: type != pull_request
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env: BUILD_TYPE=Debug VERBOSE=1
|
||||
if: type != pull_request
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
|
||||
if: type != pull_request
|
||||
|
||||
# These are the install and build (script) phases for the most common entries in the matrix. They could be included
|
||||
# in each entry in the matrix, but that is just repetitive.
|
||||
|
34
BUILD.bazel
34
BUILD.bazel
@ -37,10 +37,21 @@ package(default_visibility = ["//visibility:public"])
|
||||
licenses(["notice"])
|
||||
|
||||
config_setting(
|
||||
name = "win",
|
||||
name = "windows",
|
||||
values = { "cpu": "x64_windows" },
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "windows_msvc",
|
||||
values = {"cpu": "x64_windows_msvc"},
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "has_absl",
|
||||
values = {"define": "absl=1"},
|
||||
)
|
||||
|
||||
|
||||
# Google Test including Google Mock
|
||||
cc_library(
|
||||
name = "gtest",
|
||||
@ -65,7 +76,8 @@ cc_library(
|
||||
]),
|
||||
copts = select(
|
||||
{
|
||||
":win": [],
|
||||
":windows": [],
|
||||
":windows_msvc": [],
|
||||
"//conditions:default": ["-pthread"],
|
||||
},
|
||||
),
|
||||
@ -76,11 +88,27 @@ cc_library(
|
||||
"googletest/include",
|
||||
],
|
||||
linkopts = select({
|
||||
":win": [],
|
||||
":windows": [],
|
||||
":windows_msvc": [],
|
||||
"//conditions:default": [
|
||||
"-pthread",
|
||||
],
|
||||
}),
|
||||
defines = select ({
|
||||
":has_absl": [
|
||||
"GTEST_HAS_ABSL=1",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}
|
||||
),
|
||||
deps = select ({
|
||||
":has_absl": [
|
||||
"@com_google_absl//absl/types:optional",
|
||||
"@com_google_absl//absl/strings"
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
cc_library(
|
||||
|
14
Makefile.am
Normal file
14
Makefile.am
Normal file
@ -0,0 +1,14 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
# Build . before src so that our all-local and clean-local hooks kicks in at
|
||||
# the right time.
|
||||
SUBDIRS = googletest googlemock
|
||||
|
||||
EXTRA_DIST = \
|
||||
BUILD.bazel \
|
||||
CMakeLists.txt \
|
||||
README.md \
|
||||
WORKSPACE
|
@ -103,7 +103,7 @@ package (as described below):
|
||||
|
||||
### Windows Requirements ###
|
||||
|
||||
* Microsoft Visual C++ 2010 or newer
|
||||
* Microsoft Visual C++ 2015 or newer
|
||||
|
||||
### Cygwin Requirements ###
|
||||
|
||||
|
@ -1 +1,8 @@
|
||||
workspace(name = "com_google_googletest")
|
||||
|
||||
# Abseil
|
||||
http_archive(
|
||||
name = "com_google_absl",
|
||||
urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"],
|
||||
strip_prefix = "abseil-cpp-master",
|
||||
)
|
||||
|
37
appveyor.yml
37
appveyor.yml
@ -11,28 +11,15 @@ environment:
|
||||
- compiler: msvc-15-seh
|
||||
generator: "Visual Studio 15 2017 Win64"
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
enabled_on_pr: yes
|
||||
|
||||
- compiler: msvc-14-seh
|
||||
generator: "Visual Studio 14 2015"
|
||||
enabled_on_pr: yes
|
||||
|
||||
- compiler: msvc-14-seh
|
||||
generator: "Visual Studio 14 2015 Win64"
|
||||
|
||||
- compiler: msvc-12-seh
|
||||
generator: "Visual Studio 12 2013"
|
||||
|
||||
- compiler: msvc-12-seh
|
||||
generator: "Visual Studio 12 2013 Win64"
|
||||
|
||||
- compiler: msvc-11-seh
|
||||
generator: "Visual Studio 11 2012"
|
||||
|
||||
- compiler: msvc-11-seh
|
||||
generator: "Visual Studio 11 2012 Win64"
|
||||
|
||||
- compiler: msvc-10-seh
|
||||
generator: "Visual Studio 10 2010"
|
||||
|
||||
- compiler: gcc-5.3.0-posix
|
||||
generator: "MinGW Makefiles"
|
||||
cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin'
|
||||
@ -43,7 +30,6 @@ environment:
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
#- Release
|
||||
|
||||
build:
|
||||
verbosity: minimal
|
||||
@ -52,6 +38,14 @@ install:
|
||||
- ps: |
|
||||
Write-Output "Compiler: $env:compiler"
|
||||
Write-Output "Generator: $env:generator"
|
||||
if (-not (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER)) {
|
||||
Write-Output "This is *NOT* a pull request build"
|
||||
} else {
|
||||
Write-Output "This is a pull request build"
|
||||
if (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes") {
|
||||
Write-Output "PR builds are *NOT* explicitly enabled"
|
||||
}
|
||||
}
|
||||
|
||||
# git bash conflicts with MinGW makefiles
|
||||
if ($env:generator -eq "MinGW Makefiles") {
|
||||
@ -63,6 +57,10 @@ install:
|
||||
|
||||
build_script:
|
||||
- ps: |
|
||||
# Only enable some builds for pull requests, the AppVeyor queue is too long.
|
||||
if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) {
|
||||
return
|
||||
}
|
||||
md _build -Force | Out-Null
|
||||
cd _build
|
||||
|
||||
@ -74,13 +72,18 @@ build_script:
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Exec: $ErrorMessage"
|
||||
}
|
||||
& cmake --build . --config $env:configuration
|
||||
$cmake_parallel = if ($env:generator -eq "MinGW Makefiles") {"-j2"} else {"/m"}
|
||||
& cmake --build . --config $env:configuration -- $cmake_parallel
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Exec: $ErrorMessage"
|
||||
}
|
||||
|
||||
test_script:
|
||||
- ps: |
|
||||
# Only enable some builds for pull requests, the AppVeyor queue is too long.
|
||||
if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) {
|
||||
return
|
||||
}
|
||||
if ($env:generator -eq "MinGW Makefiles") {
|
||||
return # No test available for MinGW
|
||||
}
|
||||
|
44
ci/build-linux-autotools.sh
Executable file
44
ci/build-linux-autotools.sh
Executable file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
. ci/get-nprocessors.sh
|
||||
|
||||
# Create the configuration script
|
||||
autoreconf -i
|
||||
|
||||
# Run in a subdirectory to keep the sources clean
|
||||
mkdir build || true
|
||||
cd build
|
||||
../configure
|
||||
|
||||
make -j ${NPROCESSORS:-2}
|
@ -33,3 +33,4 @@ set -e
|
||||
|
||||
bazel build --curses=no //...:all
|
||||
bazel test --curses=no //...:all
|
||||
bazel test --curses=no //...:all --define absl=1
|
||||
|
48
ci/get-nprocessors.sh
Executable file
48
ci/get-nprocessors.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
# 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.
|
||||
|
||||
# This file is typically sourced by another script.
|
||||
# if possible, ask for the precise number of processors,
|
||||
# otherwise take 2 processors as reasonable default; see
|
||||
# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
NPROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
|
||||
else
|
||||
NPROCESSORS=2
|
||||
fi
|
||||
|
||||
# as of 2017-09-04 Travis CI reports 32 processors, but GCC build
|
||||
# crashes if parallelized too much (maybe memory consumption problem),
|
||||
# so limit to 4 processors for the time being.
|
||||
if [ $NPROCESSORS -gt 4 ] ; then
|
||||
echo "$0:Note: Limiting processors to use by make from $NPROCESSORS to 4."
|
||||
NPROCESSORS=4
|
||||
fi
|
@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env sh
|
||||
set -evx
|
||||
|
||||
. ci/get-nprocessors.sh
|
||||
|
||||
# if possible, ask for the precise number of processors,
|
||||
# otherwise take 2 processors as reasonable default; see
|
||||
# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization
|
||||
|
16
configure.ac
Normal file
16
configure.ac
Normal file
@ -0,0 +1,16 @@
|
||||
AC_INIT([Google C++ Mocking and Testing Frameworks],
|
||||
[1.8.0],
|
||||
[googlemock@googlegroups.com],
|
||||
[googletest])
|
||||
|
||||
# Provide various options to initialize the Autoconf and configure processes.
|
||||
AC_PREREQ([2.59])
|
||||
AC_CONFIG_SRCDIR([./README.md])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_SUBDIRS([googletest googlemock])
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
# Output the generated files. No further autoconf macros may be used.
|
||||
AC_OUTPUT
|
@ -88,16 +88,23 @@ endif()
|
||||
# Google Mock libraries. We build them using more strict warnings than what
|
||||
# are used for other targets, to ensure that Google Mock can be compiled by
|
||||
# a user aggressive about warnings.
|
||||
cxx_library(gmock
|
||||
"${cxx_strict}"
|
||||
"${gtest_dir}/src/gtest-all.cc"
|
||||
src/gmock-all.cc)
|
||||
if (MSVC)
|
||||
cxx_library(gmock
|
||||
"${cxx_strict}"
|
||||
"${gtest_dir}/src/gtest-all.cc"
|
||||
src/gmock-all.cc)
|
||||
|
||||
cxx_library(gmock_main
|
||||
"${cxx_strict}"
|
||||
"${gtest_dir}/src/gtest-all.cc"
|
||||
src/gmock-all.cc
|
||||
src/gmock_main.cc)
|
||||
cxx_library(gmock_main
|
||||
"${cxx_strict}"
|
||||
"${gtest_dir}/src/gtest-all.cc"
|
||||
src/gmock-all.cc
|
||||
src/gmock_main.cc)
|
||||
else()
|
||||
cxx_library(gmock "${cxx_strict}" src/gmock-all.cc)
|
||||
target_link_libraries(gmock gtest)
|
||||
cxx_library(gmock_main "${cxx_strict}" src/gmock_main.cc)
|
||||
target_link_libraries(gmock_main gmock)
|
||||
endif()
|
||||
|
||||
# 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
|
||||
@ -177,23 +184,33 @@ if (gmock_build_tests)
|
||||
############################################################
|
||||
# C++ tests built with non-standard compiler flags.
|
||||
|
||||
cxx_library(gmock_main_no_exception "${cxx_no_exception}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
cxx_library(gmock_main_no_rtti "${cxx_no_rtti}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
if (NOT MSVC OR MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010.
|
||||
# Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that
|
||||
# conflict with our own definitions. Therefore using our own tuple does not
|
||||
# work on those compilers.
|
||||
cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}"
|
||||
if (MSVC)
|
||||
cxx_library(gmock_main_no_exception "${cxx_no_exception}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
cxx_test_with_flags(gmock_use_own_tuple_test "${cxx_use_own_tuple}"
|
||||
gmock_main_use_own_tuple test/gmock-spec-builders_test.cc)
|
||||
endif()
|
||||
cxx_library(gmock_main_no_rtti "${cxx_no_rtti}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
if (MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010.
|
||||
# Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that
|
||||
# conflict with our own definitions. Therefore using our own tuple does not
|
||||
# work on those compilers.
|
||||
cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
cxx_test_with_flags(gmock_use_own_tuple_test "${cxx_use_own_tuple}"
|
||||
gmock_main_use_own_tuple test/gmock-spec-builders_test.cc)
|
||||
endif()
|
||||
else()
|
||||
cxx_library(gmock_main_no_exception "${cxx_no_exception}" src/gmock_main.cc)
|
||||
target_link_libraries(gmock_main_no_exception gmock)
|
||||
|
||||
cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" src/gmock_main.cc)
|
||||
target_link_libraries(gmock_main_no_rtti gmock)
|
||||
|
||||
cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}" src/gmock_main.cc)
|
||||
target_link_libraries(gmock_main_use_own_tuple gmock)
|
||||
endif()
|
||||
cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}"
|
||||
gmock_main_no_exception test/gmock-more-actions_test.cc)
|
||||
|
||||
|
@ -129,7 +129,7 @@ AS_IF([test "x${HAVE_BUILT_GTEST}" = "xyes"],
|
||||
GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`
|
||||
GTEST_LIBS=`${GTEST_CONFIG} --libs`
|
||||
GTEST_VERSION=`${GTEST_CONFIG} --version`],
|
||||
[AC_CONFIG_SUBDIRS([../googletest])
|
||||
[
|
||||
# GTEST_CONFIG needs to be executable both in a Makefile environment and
|
||||
# in a shell script environment, so resolve an absolute path for it here.
|
||||
GTEST_CONFIG="`pwd -P`/../googletest/scripts/gtest-config"
|
||||
|
@ -178,6 +178,8 @@ divided into several categories:
|
||||
|`Ne(value)` |`argument != value`|
|
||||
|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).|
|
||||
|`NotNull()` |`argument` is a non-null pointer (raw or smart).|
|
||||
|`VariantWith<T>(m)` |`argument` is `variant<>` that holds the alternative of
|
||||
type T with a value matching `m`.|
|
||||
|`Ref(variable)` |`argument` is a reference to `variable`.|
|
||||
|`TypedEq<type>(value)`|`argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded.|
|
||||
|
||||
|
@ -1231,7 +1231,7 @@ that references the implementation object dies, the implementation
|
||||
object will be deleted.
|
||||
|
||||
Therefore, if you have some complex matcher that you want to use again
|
||||
and again, there is no need to build it everytime. Just assign it to a
|
||||
and again, there is no need to build it every time. Just assign it to a
|
||||
matcher variable and use that variable repeatedly! For example,
|
||||
|
||||
```
|
||||
@ -1403,7 +1403,7 @@ edge from node A to node B wherever A must occur before B, we can get
|
||||
a DAG. We use the term "sequence" to mean a directed path in this
|
||||
DAG. Now, if we decompose the DAG into sequences, we just need to know
|
||||
which sequences each `EXPECT_CALL()` belongs to in order to be able to
|
||||
reconstruct the orginal DAG.
|
||||
reconstruct the original DAG.
|
||||
|
||||
So, to specify the partial order on the expectations we need to do two
|
||||
things: first to define some `Sequence` objects, and then for each
|
||||
@ -2182,7 +2182,7 @@ the implementation object dies, the implementation object will be
|
||||
deleted.
|
||||
|
||||
If you have some complex action that you want to use again and again,
|
||||
you may not have to build it from scratch everytime. If the action
|
||||
you may not have to build it from scratch every time. If the action
|
||||
doesn't have an internal state (i.e. if it always does the same thing
|
||||
no matter how many times it has been called), you can assign it to an
|
||||
action variable and use that variable repeatedly. For example:
|
||||
|
@ -47,10 +47,9 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#if GTEST_HAS_STD_INITIALIZER_LIST_
|
||||
# include <initializer_list> // NOLINT -- must be after gtest.h
|
||||
@ -515,7 +514,7 @@ template <typename T, typename M>
|
||||
class MatcherCastImpl {
|
||||
public:
|
||||
static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
|
||||
// M can be a polymorhic matcher, in which case we want to use
|
||||
// M can be a polymorphic matcher, in which case we want to use
|
||||
// its conversion operator to create Matcher<T>. Or it can be a value
|
||||
// that should be passed to the Matcher<T>'s constructor.
|
||||
//
|
||||
@ -1551,7 +1550,7 @@ class BothOfMatcherImpl : public MatcherInterface<T> {
|
||||
// MatcherList provides mechanisms for storing a variable number of matchers in
|
||||
// a list structure (ListType) and creating a combining matcher from such a
|
||||
// list.
|
||||
// The template is defined recursively using the following template paramters:
|
||||
// The template is defined recursively using the following template parameters:
|
||||
// * kSize is the length of the MatcherList.
|
||||
// * Head is the type of the first matcher of the list.
|
||||
// * Tail denotes the types of the remaining matchers of the list.
|
||||
@ -2380,7 +2379,7 @@ class ResultOfMatcher {
|
||||
|
||||
private:
|
||||
// Functors often define operator() as non-const method even though
|
||||
// they are actualy stateless. But we need to use them even when
|
||||
// they are actually stateless. But we need to use them even when
|
||||
// 'this' is a const pointer. It's the user's responsibility not to
|
||||
// use stateful callables with ResultOf(), which does't guarantee
|
||||
// how many times the callable will be invoked.
|
||||
@ -3304,14 +3303,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
|
||||
GTEST_API_ ElementMatcherPairs
|
||||
FindMaxBipartiteMatching(const MatchMatrix& g);
|
||||
|
||||
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
|
||||
MatchResultListener* listener);
|
||||
struct UnorderedMatcherRequire {
|
||||
enum Flags {
|
||||
Superset = 1 << 0,
|
||||
Subset = 1 << 1,
|
||||
ExactMatch = Superset | Subset,
|
||||
};
|
||||
};
|
||||
|
||||
// Untyped base class for implementing UnorderedElementsAre. By
|
||||
// putting logic that's not specific to the element type here, we
|
||||
// reduce binary bloat and increase compilation speed.
|
||||
class GTEST_API_ UnorderedElementsAreMatcherImplBase {
|
||||
protected:
|
||||
explicit UnorderedElementsAreMatcherImplBase(
|
||||
UnorderedMatcherRequire::Flags matcher_flags)
|
||||
: match_flags_(matcher_flags) {}
|
||||
|
||||
// A vector of matcher describers, one for each element matcher.
|
||||
// Does not own the describers (and thus can be used only when the
|
||||
// element matchers are alive).
|
||||
@ -3323,9 +3331,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
|
||||
// Describes the negation of this UnorderedElementsAre matcher.
|
||||
void DescribeNegationToImpl(::std::ostream* os) const;
|
||||
|
||||
bool VerifyAllElementsAndMatchersAreMatched(
|
||||
const ::std::vector<std::string>& element_printouts,
|
||||
const MatchMatrix& matrix, MatchResultListener* listener) const;
|
||||
bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,
|
||||
const MatchMatrix& matrix,
|
||||
MatchResultListener* listener) const;
|
||||
|
||||
bool FindPairing(const MatchMatrix& matrix,
|
||||
MatchResultListener* listener) const;
|
||||
|
||||
MatcherDescriberVec& matcher_describers() {
|
||||
return matcher_describers_;
|
||||
@ -3335,13 +3346,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
|
||||
return Message() << n << " element" << (n == 1 ? "" : "s");
|
||||
}
|
||||
|
||||
UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
|
||||
|
||||
private:
|
||||
UnorderedMatcherRequire::Flags match_flags_;
|
||||
MatcherDescriberVec matcher_describers_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
|
||||
};
|
||||
|
||||
// Implements unordered ElementsAre and unordered ElementsAreArray.
|
||||
// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
|
||||
// IsSupersetOf.
|
||||
template <typename Container>
|
||||
class UnorderedElementsAreMatcherImpl
|
||||
: public MatcherInterface<Container>,
|
||||
@ -3354,10 +3369,10 @@ class UnorderedElementsAreMatcherImpl
|
||||
typedef typename StlContainer::const_iterator StlContainerConstIterator;
|
||||
typedef typename StlContainer::value_type Element;
|
||||
|
||||
// Constructs the matcher from a sequence of element values or
|
||||
// element matchers.
|
||||
template <typename InputIter>
|
||||
UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) {
|
||||
UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
|
||||
InputIter first, InputIter last)
|
||||
: UnorderedElementsAreMatcherImplBase(matcher_flags) {
|
||||
for (; first != last; ++first) {
|
||||
matchers_.push_back(MatcherCast<const Element&>(*first));
|
||||
matcher_describers().push_back(matchers_.back().GetDescriber());
|
||||
@ -3378,34 +3393,32 @@ class UnorderedElementsAreMatcherImpl
|
||||
MatchResultListener* listener) const {
|
||||
StlContainerReference stl_container = View::ConstReference(container);
|
||||
::std::vector<std::string> element_printouts;
|
||||
MatchMatrix matrix = AnalyzeElements(stl_container.begin(),
|
||||
stl_container.end(),
|
||||
&element_printouts,
|
||||
listener);
|
||||
MatchMatrix matrix =
|
||||
AnalyzeElements(stl_container.begin(), stl_container.end(),
|
||||
&element_printouts, listener);
|
||||
|
||||
const size_t actual_count = matrix.LhsSize();
|
||||
if (actual_count == 0 && matchers_.empty()) {
|
||||
if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
|
||||
return true;
|
||||
}
|
||||
if (actual_count != matchers_.size()) {
|
||||
// The element count doesn't match. If the container is empty,
|
||||
// there's no need to explain anything as Google Mock already
|
||||
// prints the empty container. Otherwise we just need to show
|
||||
// how many elements there actually are.
|
||||
if (actual_count != 0 && listener->IsInterested()) {
|
||||
*listener << "which has " << Elements(actual_count);
|
||||
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
if (matrix.LhsSize() != matrix.RhsSize()) {
|
||||
// The element count doesn't match. If the container is empty,
|
||||
// there's no need to explain anything as Google Mock already
|
||||
// prints the empty container. Otherwise we just need to show
|
||||
// how many elements there actually are.
|
||||
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
|
||||
*listener << "which has " << Elements(matrix.LhsSize());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return VerifyAllElementsAndMatchersAreMatched(element_printouts,
|
||||
matrix, listener) &&
|
||||
return VerifyMatchMatrix(element_printouts, matrix, listener) &&
|
||||
FindPairing(matrix, listener);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef ::std::vector<Matcher<const Element&> > MatcherVec;
|
||||
|
||||
template <typename ElementIter>
|
||||
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
|
||||
::std::vector<std::string>* element_printouts,
|
||||
@ -3432,7 +3445,7 @@ class UnorderedElementsAreMatcherImpl
|
||||
return matrix;
|
||||
}
|
||||
|
||||
MatcherVec matchers_;
|
||||
::std::vector<Matcher<const Element&> > matchers_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
|
||||
};
|
||||
@ -3465,7 +3478,7 @@ class UnorderedElementsAreMatcher {
|
||||
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
|
||||
::std::back_inserter(matchers));
|
||||
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
|
||||
matchers.begin(), matchers.end()));
|
||||
UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end()));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -3498,24 +3511,23 @@ class ElementsAreMatcher {
|
||||
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
|
||||
};
|
||||
|
||||
// Implements UnorderedElementsAreArray().
|
||||
// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
|
||||
template <typename T>
|
||||
class UnorderedElementsAreArrayMatcher {
|
||||
public:
|
||||
UnorderedElementsAreArrayMatcher() {}
|
||||
|
||||
template <typename Iter>
|
||||
UnorderedElementsAreArrayMatcher(Iter first, Iter last)
|
||||
: matchers_(first, last) {}
|
||||
UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
|
||||
Iter first, Iter last)
|
||||
: match_flags_(match_flags), matchers_(first, last) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
return MakeMatcher(
|
||||
new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(),
|
||||
matchers_.end()));
|
||||
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
|
||||
match_flags_, matchers_.begin(), matchers_.end()));
|
||||
}
|
||||
|
||||
private:
|
||||
UnorderedMatcherRequire::Flags match_flags_;
|
||||
::std::vector<T> matchers_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
|
||||
@ -3624,9 +3636,69 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
|
||||
const char* matcher_name,
|
||||
const Strings& param_values);
|
||||
|
||||
namespace variant_matcher {
|
||||
// Overloads to allow VariantMatcher to do proper ADL lookup.
|
||||
template <typename T>
|
||||
void holds_alternative() {}
|
||||
template <typename T>
|
||||
void get() {}
|
||||
|
||||
// Implements a matcher that checks the value of a variant<> type variable.
|
||||
template <typename T>
|
||||
class VariantMatcher {
|
||||
public:
|
||||
explicit VariantMatcher(::testing::Matcher<const T&> matcher)
|
||||
: matcher_(internal::move(matcher)) {}
|
||||
|
||||
template <typename Variant>
|
||||
bool MatchAndExplain(const Variant& value,
|
||||
::testing::MatchResultListener* listener) const {
|
||||
if (!listener->IsInterested()) {
|
||||
return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));
|
||||
}
|
||||
|
||||
if (!holds_alternative<T>(value)) {
|
||||
*listener << "whose value is not of type '" << GetTypeName() << "'";
|
||||
return false;
|
||||
}
|
||||
|
||||
const T& elem = get<T>(value);
|
||||
StringMatchResultListener elem_listener;
|
||||
const bool match = matcher_.MatchAndExplain(elem, &elem_listener);
|
||||
*listener << "whose value " << PrintToString(elem)
|
||||
<< (match ? " matches" : " doesn't match");
|
||||
PrintIfNotEmpty(elem_listener.str(), listener->stream());
|
||||
return match;
|
||||
}
|
||||
|
||||
void DescribeTo(std::ostream* os) const {
|
||||
*os << "is a variant<> with value of type '" << GetTypeName()
|
||||
<< "' and the value ";
|
||||
matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const {
|
||||
*os << "is a variant<> with value of type other than '" << GetTypeName()
|
||||
<< "' or the value ";
|
||||
matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
private:
|
||||
static string GetTypeName() {
|
||||
#if GTEST_HAS_RTTI
|
||||
return internal::GetTypeName<T>();
|
||||
#endif
|
||||
return "the element type";
|
||||
}
|
||||
|
||||
const ::testing::Matcher<const T&> matcher_;
|
||||
};
|
||||
|
||||
} // namespace variant_matcher
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// ElementsAreArray(first, last)
|
||||
// ElementsAreArray(iterator_first, iterator_last)
|
||||
// ElementsAreArray(pointer, count)
|
||||
// ElementsAreArray(array)
|
||||
// ElementsAreArray(container)
|
||||
@ -3675,20 +3747,26 @@ ElementsAreArray(::std::initializer_list<T> xs) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// UnorderedElementsAreArray(first, last)
|
||||
// UnorderedElementsAreArray(iterator_first, iterator_last)
|
||||
// UnorderedElementsAreArray(pointer, count)
|
||||
// UnorderedElementsAreArray(array)
|
||||
// UnorderedElementsAreArray(container)
|
||||
// UnorderedElementsAreArray({ e1, e2, ..., en })
|
||||
//
|
||||
// The UnorderedElementsAreArray() functions are like
|
||||
// ElementsAreArray(...), but allow matching the elements in any order.
|
||||
// UnorderedElementsAreArray() verifies that a bijective mapping onto a
|
||||
// collection of matchers exists.
|
||||
//
|
||||
// The matchers can be specified as an array, a pointer and count, a container,
|
||||
// an initializer list, or an STL iterator range. In each of these cases, the
|
||||
// underlying matchers can be either values or matchers.
|
||||
|
||||
template <typename Iter>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<
|
||||
typename ::std::iterator_traits<Iter>::value_type>
|
||||
UnorderedElementsAreArray(Iter first, Iter last) {
|
||||
typedef typename ::std::iterator_traits<Iter>::value_type T;
|
||||
return internal::UnorderedElementsAreArrayMatcher<T>(first, last);
|
||||
return internal::UnorderedElementsAreArrayMatcher<T>(
|
||||
internal::UnorderedMatcherRequire::ExactMatch, first, last);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -3730,7 +3808,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) {
|
||||
const internal::AnythingMatcher _ = {};
|
||||
// Creates a matcher that matches any value of the given type T.
|
||||
template <typename T>
|
||||
inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); }
|
||||
inline Matcher<T> A() {
|
||||
return Matcher<T>(new internal::AnyMatcherImpl<T>());
|
||||
}
|
||||
|
||||
// Creates a matcher that matches any value of the given type T.
|
||||
template <typename T>
|
||||
@ -4300,6 +4380,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
|
||||
return internal::ContainsMatcher<M>(matcher);
|
||||
}
|
||||
|
||||
// IsSupersetOf(iterator_first, iterator_last)
|
||||
// IsSupersetOf(pointer, count)
|
||||
// IsSupersetOf(array)
|
||||
// IsSupersetOf(container)
|
||||
// IsSupersetOf({e1, e2, ..., en})
|
||||
//
|
||||
// IsSupersetOf() verifies that a surjective partial mapping onto a collection
|
||||
// of matchers exists. In other words, a container matches
|
||||
// IsSupersetOf({e1, ..., en}) if and only if there is a permutation
|
||||
// {y1, ..., yn} of some of the container's elements where y1 matches e1,
|
||||
// ..., and yn matches en. Obviously, the size of the container must be >= n
|
||||
// in order to have a match. Examples:
|
||||
//
|
||||
// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and
|
||||
// 1 matches Ne(0).
|
||||
// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches
|
||||
// both Eq(1) and Lt(2). The reason is that different matchers must be used
|
||||
// for elements in different slots of the container.
|
||||
// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches
|
||||
// Eq(1) and (the second) 1 matches Lt(2).
|
||||
// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)
|
||||
// Gt(1) and 3 matches (the second) Gt(1).
|
||||
//
|
||||
// The matchers can be specified as an array, a pointer and count, a container,
|
||||
// an initializer list, or an STL iterator range. In each of these cases, the
|
||||
// underlying matchers can be either values or matchers.
|
||||
|
||||
template <typename Iter>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<
|
||||
typename ::std::iterator_traits<Iter>::value_type>
|
||||
IsSupersetOf(Iter first, Iter last) {
|
||||
typedef typename ::std::iterator_traits<Iter>::value_type T;
|
||||
return internal::UnorderedElementsAreArrayMatcher<T>(
|
||||
internal::UnorderedMatcherRequire::Superset, first, last);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
|
||||
const T* pointer, size_t count) {
|
||||
return IsSupersetOf(pointer, pointer + count);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
|
||||
const T (&array)[N]) {
|
||||
return IsSupersetOf(array, N);
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<
|
||||
typename Container::value_type>
|
||||
IsSupersetOf(const Container& container) {
|
||||
return IsSupersetOf(container.begin(), container.end());
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_INITIALIZER_LIST_
|
||||
template <typename T>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
|
||||
::std::initializer_list<T> xs) {
|
||||
return IsSupersetOf(xs.begin(), xs.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
// IsSubsetOf(iterator_first, iterator_last)
|
||||
// IsSubsetOf(pointer, count)
|
||||
// IsSubsetOf(array)
|
||||
// IsSubsetOf(container)
|
||||
// IsSubsetOf({e1, e2, ..., en})
|
||||
//
|
||||
// IsSubsetOf() verifies that an injective mapping onto a collection of matchers
|
||||
// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and
|
||||
// only if there is a subset of matchers {m1, ..., mk} which would match the
|
||||
// container using UnorderedElementsAre. Obviously, the size of the container
|
||||
// must be <= n in order to have a match. Examples:
|
||||
//
|
||||
// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).
|
||||
// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1
|
||||
// matches Lt(0).
|
||||
// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both
|
||||
// match Gt(0). The reason is that different matchers must be used for
|
||||
// elements in different slots of the container.
|
||||
//
|
||||
// The matchers can be specified as an array, a pointer and count, a container,
|
||||
// an initializer list, or an STL iterator range. In each of these cases, the
|
||||
// underlying matchers can be either values or matchers.
|
||||
|
||||
template <typename Iter>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<
|
||||
typename ::std::iterator_traits<Iter>::value_type>
|
||||
IsSubsetOf(Iter first, Iter last) {
|
||||
typedef typename ::std::iterator_traits<Iter>::value_type T;
|
||||
return internal::UnorderedElementsAreArrayMatcher<T>(
|
||||
internal::UnorderedMatcherRequire::Subset, first, last);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
|
||||
const T* pointer, size_t count) {
|
||||
return IsSubsetOf(pointer, pointer + count);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
|
||||
const T (&array)[N]) {
|
||||
return IsSubsetOf(array, N);
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<
|
||||
typename Container::value_type>
|
||||
IsSubsetOf(const Container& container) {
|
||||
return IsSubsetOf(container.begin(), container.end());
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_INITIALIZER_LIST_
|
||||
template <typename T>
|
||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
|
||||
::std::initializer_list<T> xs) {
|
||||
return IsSubsetOf(xs.begin(), xs.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Matches an STL-style container or a native array that contains only
|
||||
// elements matching the given value or matcher.
|
||||
//
|
||||
@ -4398,6 +4600,17 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
|
||||
template <typename InnerMatcher>
|
||||
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
|
||||
|
||||
// Returns a matcher that matches the value of a variant<> type variable.
|
||||
// The matcher implementation uses ADL to find the holds_alternative and get
|
||||
// functions.
|
||||
// It is compatible with std::variant.
|
||||
template <typename T>
|
||||
PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
|
||||
const Matcher<const T&>& matcher) {
|
||||
return MakePolymorphicMatcher(
|
||||
internal::variant_matcher::VariantMatcher<T>(matcher));
|
||||
}
|
||||
|
||||
// These macros allow using matchers to check values in Google Test
|
||||
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
|
||||
// succeed iff the value matches the matcher. If the assertion fails,
|
||||
|
@ -53,6 +53,22 @@ MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Define a matcher that matches a value that evaluates in boolean
|
||||
// context to true. Useful for types that define "explicit operator
|
||||
// bool" operators and so can't be compared for equality with true
|
||||
// and false.
|
||||
MATCHER(IsTrue, negation ? "is false" : "is true") {
|
||||
return static_cast<bool>(arg);
|
||||
}
|
||||
|
||||
// Define a matcher that matches a value that evaluates in boolean
|
||||
// context to false. Useful for types that define "explicit operator
|
||||
// bool" operators and so can't be compared for equality with true
|
||||
// and false.
|
||||
MATCHER(IsFalse, negation ? "is true" : "is false") {
|
||||
return !static_cast<bool>(arg);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
|
@ -65,11 +65,6 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
# include <stdexcept> // NOLINT
|
||||
#endif
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
@ -77,6 +72,10 @@
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
# include <stdexcept> // NOLINT
|
||||
#endif
|
||||
|
||||
namespace testing {
|
||||
|
||||
// An abstract handle of an expectation.
|
||||
|
@ -59,8 +59,8 @@
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
#include "gmock/gmock-generated-actions.h"
|
||||
#include "gmock/gmock-generated-function-mockers.h"
|
||||
#include "gmock/gmock-generated-nice-strict.h"
|
||||
#include "gmock/gmock-generated-matchers.h"
|
||||
#include "gmock/gmock-generated-nice-strict.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-more-actions.h"
|
||||
#include "gmock/gmock-more-matchers.h"
|
||||
|
@ -90,42 +90,48 @@ struct MatcherTuple< ::testing::tuple<A1, A2, A3> > {
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4> > {
|
||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
|
||||
Matcher<A4> > type;
|
||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4> >
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5> > {
|
||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5> > type;
|
||||
Matcher<A5> >
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
|
||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6> > type;
|
||||
Matcher<A5>, Matcher<A6> >
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
|
||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7> >
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
|
||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> >
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
|
||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>,
|
||||
Matcher<A9> >
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
@ -133,8 +139,9 @@ template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||
A10> > {
|
||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
|
||||
Matcher<A10> > type;
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>,
|
||||
Matcher<A9>, Matcher<A10> >
|
||||
type;
|
||||
};
|
||||
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include <stdio.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
|
||||
#include "gmock/internal/gmock-generated-internal-utils.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
@ -49,11 +48,15 @@
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
GTEST_API_ std::string JoinAsTuple(const Strings& fields);
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name);
|
||||
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
|
||||
|
||||
// PointeeOf<Pointer>::type is the type of a value pointed to by a
|
||||
// Pointer, which can be either a smart pointer or a raw pointer. The
|
||||
@ -503,8 +506,38 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
|
||||
template <bool kValue>
|
||||
struct BooleanConstant {};
|
||||
|
||||
// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
|
||||
// reduce code size.
|
||||
void IllegalDoDefault(const char* file, int line);
|
||||
|
||||
#if GTEST_LANG_CXX11
|
||||
// Helper types for Apply() below.
|
||||
template <size_t... Is> struct int_pack { typedef int_pack type; };
|
||||
|
||||
template <class Pack, size_t I> struct append;
|
||||
template <size_t... Is, size_t I>
|
||||
struct append<int_pack<Is...>, I> : int_pack<Is..., I> {};
|
||||
|
||||
template <size_t C>
|
||||
struct make_int_pack : append<typename make_int_pack<C - 1>::type, C - 1> {};
|
||||
template <> struct make_int_pack<0> : int_pack<> {};
|
||||
|
||||
template <typename F, typename Tuple, size_t... Idx>
|
||||
auto ApplyImpl(F&& f, Tuple&& args, int_pack<Idx...>) -> decltype(
|
||||
std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) {
|
||||
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
||||
}
|
||||
|
||||
// Apply the function to a tuple of arguments.
|
||||
template <typename F, typename Tuple>
|
||||
auto Apply(F&& f, Tuple&& args)
|
||||
-> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||
make_int_pack<std::tuple_size<Tuple>::value>())) {
|
||||
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||
make_int_pack<std::tuple_size<Tuple>::value>());
|
||||
}
|
||||
#endif
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
|
||||
|
@ -50,15 +50,11 @@
|
||||
// portability utilities to Google Test's gtest-port.h instead of
|
||||
// here, as Google Mock depends on Google Test. Only add a utility
|
||||
// here if it's truly specific to Google Mock.
|
||||
|
||||
#include "gtest/internal/gtest-linked_ptr.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gmock/internal/custom/gmock-port.h"
|
||||
|
||||
// To avoid conditional compilation everywhere, we make it
|
||||
// gmock-port.h's responsibility to #include the header implementing
|
||||
// tr1/tuple. gmock-port.h does this via gtest-port.h, which is
|
||||
// guaranteed to pull in the tuple header.
|
||||
|
||||
// For MS Visual C++, check the compiler version. At least VS 2003 is
|
||||
// required to compile Google Mock.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1310
|
||||
@ -72,18 +68,18 @@
|
||||
#if !defined(GMOCK_DECLARE_bool_)
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
||||
# define GMOCK_DECLARE_int32_(name) \
|
||||
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
# define GMOCK_DECLARE_string_(name) \
|
||||
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
# define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
# define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
# define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
||||
|
||||
#endif // !defined(GMOCK_DECLARE_bool_)
|
||||
|
@ -338,7 +338,7 @@ class Class(_GenericDeclaration):
|
||||
# TODO(nnorwitz): handle namespaces, etc.
|
||||
if self.bases:
|
||||
for token_list in self.bases:
|
||||
# TODO(nnorwitz): bases are tokens, do name comparision.
|
||||
# TODO(nnorwitz): bases are tokens, do name comparison.
|
||||
for token in token_list:
|
||||
if token.name == node.name:
|
||||
return True
|
||||
@ -381,7 +381,7 @@ class Function(_GenericDeclaration):
|
||||
|
||||
def Requires(self, node):
|
||||
if self.parameters:
|
||||
# TODO(nnorwitz): parameters are tokens, do name comparision.
|
||||
# TODO(nnorwitz): parameters are tokens, do name comparison.
|
||||
for p in self.parameters:
|
||||
if p.name == node.name:
|
||||
return True
|
||||
@ -858,7 +858,7 @@ class AstBuilder(object):
|
||||
last_token = self._GetNextToken()
|
||||
return tokens, last_token
|
||||
|
||||
# TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary.
|
||||
# TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necessary.
|
||||
def _IgnoreUpTo(self, token_type, token):
|
||||
unused_tokens = self._GetTokensUpTo(token_type, token)
|
||||
|
||||
|
@ -47,6 +47,25 @@
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
GTEST_API_ std::string JoinAsTuple(const Strings& fields) {
|
||||
switch (fields.size()) {
|
||||
case 0:
|
||||
return "";
|
||||
case 1:
|
||||
return fields[0];
|
||||
default:
|
||||
std::string result = "(" + fields[0];
|
||||
for (size_t i = 1; i < fields.size(); i++) {
|
||||
result += ", ";
|
||||
result += fields[i];
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "gmock/gmock-generated-matchers.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
@ -100,25 +101,6 @@ Matcher<StringPiece>::Matcher(StringPiece s) {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
GTEST_API_ string JoinAsTuple(const Strings& fields) {
|
||||
switch (fields.size()) {
|
||||
case 0:
|
||||
return "";
|
||||
case 1:
|
||||
return fields[0];
|
||||
default:
|
||||
string result = "(" + fields[0];
|
||||
for (size_t i = 1; i < fields.size(); i++) {
|
||||
result += ", ";
|
||||
result += fields[i];
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the description for a matcher defined using the MATCHER*()
|
||||
// macro where the user-supplied description string is "", if
|
||||
// 'negation' is false; otherwise returns the description of the
|
||||
@ -200,8 +182,7 @@ class MaxBipartiteMatchState {
|
||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||
: graph_(&graph),
|
||||
left_(graph_->LhsSize(), kUnused),
|
||||
right_(graph_->RhsSize(), kUnused) {
|
||||
}
|
||||
right_(graph_->RhsSize(), kUnused) {}
|
||||
|
||||
// Returns the edges of a maximal match, each in the form {left, right}.
|
||||
ElementMatcherPairs Compute() {
|
||||
@ -258,10 +239,8 @@ class MaxBipartiteMatchState {
|
||||
//
|
||||
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
|
||||
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
|
||||
if ((*seen)[irhs])
|
||||
continue;
|
||||
if (!graph_->HasEdge(ilhs, irhs))
|
||||
continue;
|
||||
if ((*seen)[irhs]) continue;
|
||||
if (!graph_->HasEdge(ilhs, irhs)) continue;
|
||||
// There's an available edge from ilhs to irhs.
|
||||
(*seen)[irhs] = 1;
|
||||
// Next a search is performed to determine whether
|
||||
@ -304,8 +283,7 @@ class MaxBipartiteMatchState {
|
||||
|
||||
const size_t MaxBipartiteMatchState::kUnused;
|
||||
|
||||
GTEST_API_ ElementMatcherPairs
|
||||
FindMaxBipartiteMatching(const MatchMatrix& g) {
|
||||
GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {
|
||||
return MaxBipartiteMatchState(g).Compute();
|
||||
}
|
||||
|
||||
@ -314,7 +292,7 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
||||
typedef ElementMatcherPairs::const_iterator Iter;
|
||||
::std::ostream& os = *stream;
|
||||
os << "{";
|
||||
const char *sep = "";
|
||||
const char* sep = "";
|
||||
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||
os << sep << "\n ("
|
||||
<< "element #" << it->first << ", "
|
||||
@ -324,38 +302,6 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
||||
os << "\n}";
|
||||
}
|
||||
|
||||
// Tries to find a pairing, and explains the result.
|
||||
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
|
||||
MatchResultListener* listener) {
|
||||
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
|
||||
|
||||
size_t max_flow = matches.size();
|
||||
bool result = (max_flow == matrix.RhsSize());
|
||||
|
||||
if (!result) {
|
||||
if (listener->IsInterested()) {
|
||||
*listener << "where no permutation of the elements can "
|
||||
"satisfy all matchers, and the closest match is "
|
||||
<< max_flow << " of " << matrix.RhsSize()
|
||||
<< " matchers with the pairings:\n";
|
||||
LogElementMatcherPairVec(matches, listener->stream());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (matches.size() > 1) {
|
||||
if (listener->IsInterested()) {
|
||||
const char *sep = "where:\n";
|
||||
for (size_t mi = 0; mi < matches.size(); ++mi) {
|
||||
*listener << sep << " - element #" << matches[mi].first
|
||||
<< " is matched by matcher #" << matches[mi].second;
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MatchMatrix::NextGraph() {
|
||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||
@ -381,7 +327,7 @@ void MatchMatrix::Randomize() {
|
||||
|
||||
std::string MatchMatrix::DebugString() const {
|
||||
::std::stringstream ss;
|
||||
const char *sep = "";
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i < LhsSize(); ++i) {
|
||||
ss << sep;
|
||||
for (size_t j = 0; j < RhsSize(); ++j) {
|
||||
@ -394,44 +340,83 @@ std::string MatchMatrix::DebugString() const {
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
|
||||
::std::ostream* os) const {
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "is empty";
|
||||
return;
|
||||
switch (match_flags()) {
|
||||
case UnorderedMatcherRequire::ExactMatch:
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "is empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "has " << Elements(1) << " and that element ";
|
||||
matcher_describers_[0]->DescribeTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "has " << Elements(matcher_describers_.size())
|
||||
<< " and there exists some permutation of elements such that:\n";
|
||||
break;
|
||||
case UnorderedMatcherRequire::Superset:
|
||||
*os << "a surjection from elements to requirements exists such that:\n";
|
||||
break;
|
||||
case UnorderedMatcherRequire::Subset:
|
||||
*os << "an injection from elements to requirements exists such that:\n";
|
||||
break;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "has " << Elements(1) << " and that element ";
|
||||
matcher_describers_[0]->DescribeTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "has " << Elements(matcher_describers_.size())
|
||||
<< " and there exists some permutation of elements such that:\n";
|
||||
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep << " - element #" << i << " ";
|
||||
*os << sep;
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
*os << " - element #" << i << " ";
|
||||
} else {
|
||||
*os << " - an element ";
|
||||
}
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
sep = ", and\n";
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
sep = ", and\n";
|
||||
} else {
|
||||
sep = "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
||||
::std::ostream* os) const {
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "isn't empty";
|
||||
return;
|
||||
switch (match_flags()) {
|
||||
case UnorderedMatcherRequire::ExactMatch:
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "isn't empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "doesn't have " << Elements(1) << ", or has " << Elements(1)
|
||||
<< " that ";
|
||||
matcher_describers_[0]->DescribeNegationTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "doesn't have " << Elements(matcher_describers_.size())
|
||||
<< ", or there exists no permutation of elements such that:\n";
|
||||
break;
|
||||
case UnorderedMatcherRequire::Superset:
|
||||
*os << "no surjection from elements to requirements exists such that:\n";
|
||||
break;
|
||||
case UnorderedMatcherRequire::Subset:
|
||||
*os << "no injection from elements to requirements exists such that:\n";
|
||||
break;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "doesn't have " << Elements(1)
|
||||
<< ", or has " << Elements(1) << " that ";
|
||||
matcher_describers_[0]->DescribeNegationTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "doesn't have " << Elements(matcher_describers_.size())
|
||||
<< ", or there exists no permutation of elements such that:\n";
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep << " - element #" << i << " ";
|
||||
*os << sep;
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
*os << " - element #" << i << " ";
|
||||
} else {
|
||||
*os << " - an element ";
|
||||
}
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
sep = ", and\n";
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
sep = ", and\n";
|
||||
} else {
|
||||
sep = "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,10 +425,9 @@ void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
||||
// and better error reporting.
|
||||
// Returns false, writing an explanation to 'listener', if and only
|
||||
// if the success criteria are not met.
|
||||
bool UnorderedElementsAreMatcherImplBase::
|
||||
VerifyAllElementsAndMatchersAreMatched(
|
||||
const ::std::vector<std::string>& element_printouts,
|
||||
const MatchMatrix& matrix, MatchResultListener* listener) const {
|
||||
bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
|
||||
const ::std::vector<std::string>& element_printouts,
|
||||
const MatchMatrix& matrix, MatchResultListener* listener) const {
|
||||
bool result = true;
|
||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||
@ -456,12 +440,11 @@ bool UnorderedElementsAreMatcherImplBase::
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (match_flags() & UnorderedMatcherRequire::Superset) {
|
||||
const char* sep =
|
||||
"where the following matchers don't match any elements:\n";
|
||||
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
|
||||
if (matcher_matched[mi])
|
||||
continue;
|
||||
if (matcher_matched[mi]) continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << sep << "matcher #" << mi << ": ";
|
||||
@ -471,7 +454,7 @@ bool UnorderedElementsAreMatcherImplBase::
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (match_flags() & UnorderedMatcherRequire::Subset) {
|
||||
const char* sep =
|
||||
"where the following elements don't match any matchers:\n";
|
||||
const char* outer_sep = "";
|
||||
@ -479,8 +462,7 @@ bool UnorderedElementsAreMatcherImplBase::
|
||||
outer_sep = "\nand ";
|
||||
}
|
||||
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
|
||||
if (element_matched[ei])
|
||||
continue;
|
||||
if (element_matched[ei]) continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << outer_sep << sep << "element #" << ei << ": "
|
||||
@ -493,5 +475,46 @@ bool UnorderedElementsAreMatcherImplBase::
|
||||
return result;
|
||||
}
|
||||
|
||||
bool UnorderedElementsAreMatcherImplBase::FindPairing(
|
||||
const MatchMatrix& matrix, MatchResultListener* listener) const {
|
||||
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
|
||||
|
||||
size_t max_flow = matches.size();
|
||||
if ((match_flags() & UnorderedMatcherRequire::Superset) &&
|
||||
max_flow < matrix.RhsSize()) {
|
||||
if (listener->IsInterested()) {
|
||||
*listener << "where no permutation of the elements can satisfy all "
|
||||
"matchers, and the closest match is "
|
||||
<< max_flow << " of " << matrix.RhsSize()
|
||||
<< " matchers with the pairings:\n";
|
||||
LogElementMatcherPairVec(matches, listener->stream());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if ((match_flags() & UnorderedMatcherRequire::Subset) &&
|
||||
max_flow < matrix.LhsSize()) {
|
||||
if (listener->IsInterested()) {
|
||||
*listener
|
||||
<< "where not all elements can be matched, and the closest match is "
|
||||
<< max_flow << " of " << matrix.RhsSize()
|
||||
<< " matchers with the pairings:\n";
|
||||
LogElementMatcherPairVec(matches, listener->stream());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (matches.size() > 1) {
|
||||
if (listener->IsInterested()) {
|
||||
const char* sep = "where:\n";
|
||||
for (size_t mi = 0; mi < matches.size(); ++mi) {
|
||||
*listener << sep << " - element #" << matches[mi].first
|
||||
<< " is matched by matcher #" << matches[mi].second;
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
@ -508,7 +508,7 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
||||
return expectations_met;
|
||||
}
|
||||
|
||||
CallReaction intToCallReaction(int mock_behavior) {
|
||||
static CallReaction intToCallReaction(int mock_behavior) {
|
||||
if (mock_behavior >= kAllow && mock_behavior <= kFail) {
|
||||
return static_cast<internal::CallReaction>(mock_behavior);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2017 Google Inc.
|
||||
# Copyright 2017 Google Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
#
|
||||
@ -29,7 +29,7 @@
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Author: misterg@google.com (Gennadiy Civil)
|
||||
#
|
||||
#
|
||||
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
|
||||
|
||||
licenses(["notice"])
|
||||
@ -45,10 +45,79 @@ cc_test(
|
||||
],
|
||||
),
|
||||
linkopts = select({
|
||||
"//:win": [],
|
||||
"//:windows": [],
|
||||
"//:windows_msvc": [],
|
||||
"//conditions:default": [
|
||||
"-pthread",
|
||||
],
|
||||
}),
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
# Py tests
|
||||
|
||||
py_library(
|
||||
name = "gmock_test_utils",
|
||||
testonly = 1,
|
||||
srcs = ["gmock_test_utils.py"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gmock_leak_test_",
|
||||
testonly = 1,
|
||||
srcs = ["gmock_leak_test_.cc"],
|
||||
deps = [
|
||||
"//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gmock_leak_test",
|
||||
size = "medium",
|
||||
srcs = ["gmock_leak_test.py"],
|
||||
data = [
|
||||
":gmock_leak_test_",
|
||||
":gmock_test_utils",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "gmock_link_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"gmock_link2_test.cc",
|
||||
"gmock_link_test.cc",
|
||||
"gmock_link_test.h",
|
||||
],
|
||||
deps = [
|
||||
"//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gmock_output_test_",
|
||||
srcs = ["gmock_output_test_.cc"],
|
||||
deps = [
|
||||
"//:gtest",
|
||||
],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gmock_output_test",
|
||||
size = "medium",
|
||||
srcs = ["gmock_output_test.py"],
|
||||
data = [
|
||||
":gmock_output_test_",
|
||||
":gmock_output_test_golden.txt",
|
||||
],
|
||||
deps = [":gmock_test_utils"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "gmock_test",
|
||||
size = "small",
|
||||
srcs = ["gmock_test.cc"],
|
||||
deps = [
|
||||
"//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
@ -751,7 +751,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
|
||||
}
|
||||
|
||||
// Tests that DoDefault() returns the default value set by
|
||||
// DefaultValue<T>::Set() when it's not overriden by an ON_CALL().
|
||||
// DefaultValue<T>::Set() when it's not overridden by an ON_CALL().
|
||||
TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) {
|
||||
DefaultValue<int>::Set(1);
|
||||
MockClass mock;
|
||||
|
@ -44,15 +44,7 @@
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// their code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
#if GTEST_OS_CYGWIN
|
||||
# include <sys/types.h> // For ssize_t. NOLINT
|
||||
|
@ -65,10 +65,6 @@
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace internal {
|
||||
GTEST_API_ string JoinAsTuple(const Strings& fields);
|
||||
} // namespace internal
|
||||
|
||||
namespace gmock_matchers_test {
|
||||
|
||||
using std::greater;
|
||||
@ -150,7 +146,6 @@ using testing::internal::ExplainMatchFailureTupleTo;
|
||||
using testing::internal::FloatingEqMatcher;
|
||||
using testing::internal::FormatMatcherDescription;
|
||||
using testing::internal::IsReadableTypeName;
|
||||
using testing::internal::JoinAsTuple;
|
||||
using testing::internal::linked_ptr;
|
||||
using testing::internal::MatchMatrix;
|
||||
using testing::internal::RE;
|
||||
@ -876,9 +871,9 @@ class Unprintable {
|
||||
char c_;
|
||||
};
|
||||
|
||||
inline bool operator==(const Unprintable& /* lhs */,
|
||||
const Unprintable& /* rhs */) {
|
||||
return true;
|
||||
inline bool operator==(const Unprintable& /* lhs */,
|
||||
const Unprintable& /* rhs */) {
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(EqTest, CanDescribeSelf) {
|
||||
@ -919,7 +914,7 @@ TEST(TypedEqTest, CanDescribeSelf) {
|
||||
// Type<T>::IsTypeOf(v) compiles iff the type of value v is T, where T
|
||||
// is a "bare" type (i.e. not in the form of const U or U&). If v's
|
||||
// type is not T, the compiler will generate a message about
|
||||
// "undefined referece".
|
||||
// "undefined reference".
|
||||
template <typename T>
|
||||
struct Type {
|
||||
static bool IsTypeOf(const T& /* v */) { return true; }
|
||||
@ -1428,7 +1423,7 @@ TEST(PairTest, MatchesCorrectly) {
|
||||
EXPECT_THAT(p, Pair(25, "foo"));
|
||||
EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o")));
|
||||
|
||||
// 'first' doesnt' match, but 'second' matches.
|
||||
// 'first' does not match, but 'second' matches.
|
||||
EXPECT_THAT(p, Not(Pair(42, "foo")));
|
||||
EXPECT_THAT(p, Not(Pair(Lt(25), "foo")));
|
||||
|
||||
@ -4267,7 +4262,7 @@ TYPED_TEST(ContainerEqTest, DuplicateDifference) {
|
||||
#endif // GTEST_HAS_TYPED_TEST
|
||||
|
||||
// Tests that mutliple missing values are reported.
|
||||
// Using just vector here, so order is predicatble.
|
||||
// Using just vector here, so order is predictable.
|
||||
TEST(ContainerEqExtraTest, MultipleValuesMissing) {
|
||||
static const int vals[] = {1, 1, 2, 3, 5, 8};
|
||||
static const int test_vals[] = {2, 1, 5};
|
||||
@ -4280,7 +4275,7 @@ TEST(ContainerEqExtraTest, MultipleValuesMissing) {
|
||||
}
|
||||
|
||||
// Tests that added values are reported.
|
||||
// Using just vector here, so order is predicatble.
|
||||
// Using just vector here, so order is predictable.
|
||||
TEST(ContainerEqExtraTest, MultipleValuesAdded) {
|
||||
static const int vals[] = {1, 1, 2, 3, 5, 8};
|
||||
static const int test_vals[] = {1, 2, 92, 3, 5, 8, 46};
|
||||
@ -5272,28 +5267,6 @@ TEST(IsReadableTypeNameTest, ReturnsFalseForLongFunctionTypeNames) {
|
||||
EXPECT_FALSE(IsReadableTypeName("void (&)(int, bool, char, float)"));
|
||||
}
|
||||
|
||||
// Tests JoinAsTuple().
|
||||
|
||||
TEST(JoinAsTupleTest, JoinsEmptyTuple) {
|
||||
EXPECT_EQ("", JoinAsTuple(Strings()));
|
||||
}
|
||||
|
||||
TEST(JoinAsTupleTest, JoinsOneTuple) {
|
||||
const char* fields[] = {"1"};
|
||||
EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1)));
|
||||
}
|
||||
|
||||
TEST(JoinAsTupleTest, JoinsTwoTuple) {
|
||||
const char* fields[] = {"1", "a"};
|
||||
EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2)));
|
||||
}
|
||||
|
||||
TEST(JoinAsTupleTest, JoinsTenTuple) {
|
||||
const char* fields[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
|
||||
EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)",
|
||||
JoinAsTuple(Strings(fields, fields + 10)));
|
||||
}
|
||||
|
||||
// Tests FormatMatcherDescription().
|
||||
|
||||
TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) {
|
||||
@ -5682,5 +5655,69 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) {
|
||||
EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs));
|
||||
}
|
||||
|
||||
class SampleVariantIntString {
|
||||
public:
|
||||
SampleVariantIntString(int i) : i_(i), has_int_(true) {}
|
||||
SampleVariantIntString(const std::string& s) : s_(s), has_int_(false) {}
|
||||
|
||||
template <typename T>
|
||||
friend bool holds_alternative(const SampleVariantIntString& value) {
|
||||
return value.has_int_ == internal::IsSame<T, int>::value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend const T& get(const SampleVariantIntString& value) {
|
||||
return value.get_impl(static_cast<T*>(NULL));
|
||||
}
|
||||
|
||||
private:
|
||||
const int& get_impl(int*) const { return i_; }
|
||||
const std::string& get_impl(std::string*) const { return s_; }
|
||||
|
||||
int i_;
|
||||
std::string s_;
|
||||
bool has_int_;
|
||||
};
|
||||
|
||||
TEST(VariantTest, DescribesSelf) {
|
||||
const Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
|
||||
EXPECT_THAT(Describe(m), ContainsRegex("is a variant<> with value of type "
|
||||
"'.*' and the value is equal to 1"));
|
||||
}
|
||||
|
||||
TEST(VariantTest, ExplainsSelf) {
|
||||
const Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
|
||||
EXPECT_THAT(Explain(m, SampleVariantIntString(1)),
|
||||
ContainsRegex("whose value 1"));
|
||||
EXPECT_THAT(Explain(m, SampleVariantIntString("A")),
|
||||
HasSubstr("whose value is not of type '"));
|
||||
EXPECT_THAT(Explain(m, SampleVariantIntString(2)),
|
||||
"whose value 2 doesn't match");
|
||||
}
|
||||
|
||||
TEST(VariantTest, FullMatch) {
|
||||
Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
|
||||
EXPECT_TRUE(m.Matches(SampleVariantIntString(1)));
|
||||
|
||||
m = VariantWith<std::string>(Eq("1"));
|
||||
EXPECT_TRUE(m.Matches(SampleVariantIntString("1")));
|
||||
}
|
||||
|
||||
TEST(VariantTest, TypeDoesNotMatch) {
|
||||
Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
|
||||
EXPECT_FALSE(m.Matches(SampleVariantIntString("1")));
|
||||
|
||||
m = VariantWith<std::string>(Eq("1"));
|
||||
EXPECT_FALSE(m.Matches(SampleVariantIntString(1)));
|
||||
}
|
||||
|
||||
TEST(VariantTest, InnerDoesNotMatch) {
|
||||
Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
|
||||
EXPECT_FALSE(m.Matches(SampleVariantIntString(2)));
|
||||
|
||||
m = VariantWith<std::string>(Eq("1"));
|
||||
EXPECT_FALSE(m.Matches(SampleVariantIntString("2")));
|
||||
}
|
||||
|
||||
} // namespace gmock_matchers_test
|
||||
} // namespace testing
|
||||
|
@ -120,13 +120,15 @@
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
using testing::_;
|
||||
using testing::A;
|
||||
using testing::Action;
|
||||
using testing::AllOf;
|
||||
using testing::AnyOf;
|
||||
using testing::Assign;
|
||||
@ -148,6 +150,8 @@ using testing::Invoke;
|
||||
using testing::InvokeArgument;
|
||||
using testing::InvokeWithoutArgs;
|
||||
using testing::IsNull;
|
||||
using testing::IsSubsetOf;
|
||||
using testing::IsSupersetOf;
|
||||
using testing::Le;
|
||||
using testing::Lt;
|
||||
using testing::Matcher;
|
||||
@ -592,6 +596,22 @@ TEST(LinkTest, TestMatcherElementsAreArray) {
|
||||
ON_CALL(mock, VoidFromVector(ElementsAreArray(arr))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the IsSubsetOf matcher.
|
||||
TEST(LinkTest, TestMatcherIsSubsetOf) {
|
||||
Mock mock;
|
||||
char arr[] = {'a', 'b'};
|
||||
|
||||
ON_CALL(mock, VoidFromVector(IsSubsetOf(arr))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the IsSupersetOf matcher.
|
||||
TEST(LinkTest, TestMatcherIsSupersetOf) {
|
||||
Mock mock;
|
||||
char arr[] = {'a', 'b'};
|
||||
|
||||
ON_CALL(mock, VoidFromVector(IsSupersetOf(arr))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the ContainerEq matcher.
|
||||
TEST(LinkTest, TestMatcherContainerEq) {
|
||||
Mock mock;
|
||||
|
@ -31,11 +31,11 @@
|
||||
|
||||
"""Tests the text output of Google C++ Mocking Framework.
|
||||
|
||||
SYNOPSIS
|
||||
gmock_output_test.py --build_dir=BUILD/DIR --gengolden
|
||||
# where BUILD/DIR contains the built gmock_output_test_ file.
|
||||
gmock_output_test.py --gengolden
|
||||
gmock_output_test.py
|
||||
To update the golden file:
|
||||
gmock_output_test.py --build_dir=BUILD/DIR --gengolden
|
||||
# where BUILD/DIR contains the built gmock_output_test_ file.
|
||||
gmock_output_test.py --gengolden
|
||||
gmock_output_test.py
|
||||
"""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
@ -176,5 +176,8 @@ if __name__ == '__main__':
|
||||
golden_file = open(GOLDEN_PATH, 'wb')
|
||||
golden_file.write(output)
|
||||
golden_file.close()
|
||||
# Suppress the error "googletest was imported but a call to its main()
|
||||
# was never detected."
|
||||
os._exit(0)
|
||||
else:
|
||||
gmock_test_utils.Main()
|
||||
|
@ -33,12 +33,13 @@
|
||||
// threads concurrently.
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
namespace {
|
||||
|
||||
// From <gtest/internal/gtest-port.h>.
|
||||
// From "gtest/internal/gtest-port.h".
|
||||
using ::testing::internal::ThreadWithParam;
|
||||
|
||||
// The maximum number of test threads (not including helper threads)
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include <string>
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/internal/custom/gtest.h"
|
||||
|
||||
#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||
|
||||
@ -51,9 +52,9 @@ void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
||||
const ::std::string& expected_gmock_verbose) {
|
||||
const ::std::string old_verbose = GMOCK_FLAG(verbose);
|
||||
|
||||
int argc = M;
|
||||
int argc = M - 1;
|
||||
InitGoogleMock(&argc, const_cast<Char**>(argv));
|
||||
ASSERT_EQ(N, argc) << "The new argv has wrong number of elements.";
|
||||
ASSERT_EQ(N - 1, argc) << "The new argv has wrong number of elements.";
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
EXPECT_STREQ(new_argv[i], argv[i]);
|
||||
|
@ -1,5 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2006, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
@ -36,19 +34,19 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
# Determines path to gtest_test_utils and imports it.
|
||||
SCRIPT_DIR = os.path.dirname(__file__) or '.'
|
||||
|
||||
# isdir resolves symbolic links.
|
||||
gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../gtest/test')
|
||||
gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../googletest/test')
|
||||
if os.path.isdir(gtest_tests_util_dir):
|
||||
GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir
|
||||
else:
|
||||
GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../gtest/test')
|
||||
|
||||
GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../googletest/test')
|
||||
sys.path.append(GTEST_TESTS_UTIL_DIR)
|
||||
import gtest_test_utils # pylint: disable-msg=C6204
|
||||
|
||||
# pylint: disable=C6204
|
||||
import gtest_test_utils
|
||||
|
||||
|
||||
def GetSourceDir():
|
||||
|
@ -27,8 +27,6 @@ option(
|
||||
"Build gtest with internal symbols hidden in shared libraries."
|
||||
OFF)
|
||||
|
||||
set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Generate debug library name with a postfix.")
|
||||
|
||||
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
||||
include(cmake/hermetic_build.cmake OPTIONAL)
|
||||
|
||||
@ -306,7 +304,9 @@ if (gtest_build_tests)
|
||||
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(gtest_json_outfiles_test)
|
||||
|
||||
cxx_executable(gtest_xml_output_unittest_ test gtest)
|
||||
py_test(gtest_xml_output_unittest)
|
||||
py_test(gtest_json_output_unittest)
|
||||
endif()
|
||||
|
@ -34,6 +34,7 @@ EXTRA_DIST += $(GTEST_SRC)
|
||||
# Sample files that we don't compile.
|
||||
EXTRA_DIST += \
|
||||
samples/prime_tables.h \
|
||||
samples/sample1_unittest.cc \
|
||||
samples/sample2_unittest.cc \
|
||||
samples/sample3_unittest.cc \
|
||||
samples/sample4_unittest.cc \
|
||||
@ -120,16 +121,16 @@ EXTRA_DIST += \
|
||||
|
||||
# MSVC project files
|
||||
EXTRA_DIST += \
|
||||
msvc/gtest-md.sln \
|
||||
msvc/gtest-md.vcproj \
|
||||
msvc/gtest.sln \
|
||||
msvc/gtest.vcproj \
|
||||
msvc/gtest_main-md.vcproj \
|
||||
msvc/gtest_main.vcproj \
|
||||
msvc/gtest_prod_test-md.vcproj \
|
||||
msvc/gtest_prod_test.vcproj \
|
||||
msvc/gtest_unittest-md.vcproj \
|
||||
msvc/gtest_unittest.vcproj
|
||||
msvc/2010/gtest-md.sln \
|
||||
msvc/2010/gtest-md.vcxproj \
|
||||
msvc/2010/gtest.sln \
|
||||
msvc/2010/gtest.vcxproj \
|
||||
msvc/2010/gtest_main-md.vcxproj \
|
||||
msvc/2010/gtest_main.vcxproj \
|
||||
msvc/2010/gtest_prod_test-md.vcxproj \
|
||||
msvc/2010/gtest_prod_test.vcxproj \
|
||||
msvc/2010/gtest_unittest-md.vcxproj \
|
||||
msvc/2010/gtest_unittest.vcxproj
|
||||
|
||||
# xcode project files
|
||||
EXTRA_DIST += \
|
||||
@ -223,33 +224,61 @@ lib_libgtest_main_la_LIBADD = lib/libgtest.la
|
||||
# TESTS -- Programs run automatically by "make check"
|
||||
# check_PROGRAMS -- Programs built by "make check" but not necessarily run
|
||||
|
||||
noinst_LTLIBRARIES = samples/libsamples.la
|
||||
|
||||
samples_libsamples_la_SOURCES = \
|
||||
samples/sample1.cc \
|
||||
samples/sample1.h \
|
||||
samples/sample2.cc \
|
||||
samples/sample2.h \
|
||||
samples/sample3-inl.h \
|
||||
samples/sample4.cc \
|
||||
samples/sample4.h
|
||||
|
||||
TESTS=
|
||||
TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \
|
||||
GTEST_BUILD_DIR="$(top_builddir)/test"
|
||||
check_PROGRAMS=
|
||||
|
||||
# A simple sample on using gtest.
|
||||
TESTS += samples/sample1_unittest
|
||||
check_PROGRAMS += samples/sample1_unittest
|
||||
samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc
|
||||
samples_sample1_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la \
|
||||
samples/libsamples.la
|
||||
TESTS += samples/sample1_unittest \
|
||||
samples/sample2_unittest \
|
||||
samples/sample3_unittest \
|
||||
samples/sample4_unittest \
|
||||
samples/sample5_unittest \
|
||||
samples/sample6_unittest \
|
||||
samples/sample7_unittest \
|
||||
samples/sample8_unittest \
|
||||
samples/sample9_unittest \
|
||||
samples/sample10_unittest
|
||||
check_PROGRAMS += samples/sample1_unittest \
|
||||
samples/sample2_unittest \
|
||||
samples/sample3_unittest \
|
||||
samples/sample4_unittest \
|
||||
samples/sample5_unittest \
|
||||
samples/sample6_unittest \
|
||||
samples/sample7_unittest \
|
||||
samples/sample8_unittest \
|
||||
samples/sample9_unittest \
|
||||
samples/sample10_unittest
|
||||
|
||||
# Another sample. It also verifies that libgtest works.
|
||||
TESTS += samples/sample10_unittest
|
||||
check_PROGRAMS += samples/sample10_unittest
|
||||
samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc samples/sample1.cc
|
||||
samples_sample1_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample2_unittest_SOURCES = samples/sample2_unittest.cc samples/sample2.cc
|
||||
samples_sample2_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample3_unittest_SOURCES = samples/sample3_unittest.cc
|
||||
samples_sample3_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample4_unittest_SOURCES = samples/sample4_unittest.cc samples/sample4.cc
|
||||
samples_sample4_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample5_unittest_SOURCES = samples/sample5_unittest.cc samples/sample1.cc
|
||||
samples_sample5_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample6_unittest_SOURCES = samples/sample6_unittest.cc
|
||||
samples_sample6_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample7_unittest_SOURCES = samples/sample7_unittest.cc
|
||||
samples_sample7_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
samples_sample8_unittest_SOURCES = samples/sample8_unittest.cc
|
||||
samples_sample8_unittest_LDADD = lib/libgtest_main.la \
|
||||
lib/libgtest.la
|
||||
|
||||
# Also verify that libgtest works by itself.
|
||||
samples_sample9_unittest_SOURCES = samples/sample9_unittest.cc
|
||||
samples_sample9_unittest_LDADD = lib/libgtest.la
|
||||
samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc
|
||||
samples_sample10_unittest_LDADD = lib/libgtest.la
|
||||
|
||||
|
@ -91,10 +91,13 @@ macro(config_compiler_and_linker)
|
||||
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 "-D_HAS_EXCEPTIONS=0")
|
||||
set(cxx_no_exception_flags "-EHs-c- -D_HAS_EXCEPTIONS=0")
|
||||
set(cxx_no_rtti_flags "-GR-")
|
||||
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
|
||||
@ -155,6 +158,10 @@ function(cxx_library_with_type name type cxx_flags)
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${cxx_flags}")
|
||||
# Generate debug library name with a postfix.
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
DEBUG_POSTFIX "d")
|
||||
if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED")
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
|
@ -787,15 +787,17 @@ 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:
|
||||
your tests. A better solution is to use the `SCOPED_TRACE` macro or
|
||||
the `ScopedTrace` utility:
|
||||
|
||||
| `SCOPED_TRACE(`_message_`);` |
|
||||
|:-----------------------------|
|
||||
| `SCOPED_TRACE(`_message_`);` | `::testing::ScopedTrace trace(`_"file\_path"_`, `_line\_number_`, `_message_`);` |
|
||||
|:-----------------------------|:---------------------------------------------------------------------------------|
|
||||
|
||||
where _message_ can be anything streamable to `std::ostream`. This
|
||||
macro will cause the current file name, line number, and the given
|
||||
message to be added in every failure message. The effect will be
|
||||
undone when the control leaves the current lexical scope.
|
||||
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,
|
||||
|
||||
@ -870,13 +872,33 @@ TEST(FooTest, Bar) {
|
||||
}
|
||||
```
|
||||
|
||||
Since we don't use exceptions, it is technically impossible to
|
||||
implement the intended behavior here. To alleviate this, Google Test
|
||||
provides two solutions. You could use either the
|
||||
`(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the
|
||||
`HasFatalFailure()` function. They are described in the following two
|
||||
To alleviate this, gUnit 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_*`
|
||||
@ -1949,6 +1971,17 @@ variable to `0` has the same effect.
|
||||
_Availability:_ Linux, Windows, Mac. (In Google Test 1.3.0 and lower,
|
||||
the default behavior is that the elapsed time is **not** printed.)
|
||||
|
||||
**Availability**: Linux, Windows, Mac.
|
||||
|
||||
#### Suppressing UTF-8 Text Output
|
||||
|
||||
In case of assertion failures, gUnit 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 `--gunit_print_utf8=0` or set the `GUNIT_PRINT_UTF8`
|
||||
environment variable to `0`.
|
||||
|
||||
### Generating an XML Report ###
|
||||
|
||||
Google Test can emit a detailed XML report to a file in addition to its normal
|
||||
@ -2027,6 +2060,207 @@ Things to note:
|
||||
|
||||
_Availability:_ Linux, Windows, Mac.
|
||||
|
||||
#### Generating an JSON Report {#JsonReport}
|
||||
|
||||
gUnit can also emit a JSON report as an alternative format to XML. To generate
|
||||
the JSON report, set the `GUNIT_OUTPUT` environment variable or the
|
||||
`--gunit_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)\x0A Actual: 3\x0AExpected: 2",
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"message": "Value of: add(1, -1)\x0A Actual: 1\x0AExpected: 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.
|
||||
|
||||
**Availability**: Linux, Windows, Mac.
|
||||
|
||||
## Controlling How Failures Are Reported ##
|
||||
|
||||
### Turning Assertion Failures into Break-Points ###
|
||||
|
@ -12,5 +12,5 @@ the respective git branch/tag).**
|
||||
|
||||
To contribute code to Google Test, read:
|
||||
|
||||
* [CONTRIBUTING](../CONTRIBUTING.md) -- read this _before_ writing your first patch.
|
||||
* [CONTRIBUTING](../../CONTRIBUTING.md) -- read this _before_ writing your first patch.
|
||||
* [PumpManual](PumpManual.md) -- how we generate some of Google Test's source files.
|
||||
|
@ -460,7 +460,7 @@ following benefits:
|
||||
You may still want to use `SetUp()/TearDown()` in the following rare cases:
|
||||
* 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 assertion macros throw an exception when flag `--gtest_throw_on_failure` is specified. Therefore, you shouldn't use Google Test assertions in a destructor if you plan to run your tests with this flag.
|
||||
* In a constructor or destructor, you cannot make a virtual function call on this object. (You can call a method declared as virtual, but it will be statically bound.) Therefore, if you need to call a method that will be overriden in a derived class, you have to use `SetUp()/TearDown()`.
|
||||
* In a constructor or destructor, you cannot make a virtual function call on this object. (You can call a method declared as virtual, but it will be statically bound.) Therefore, if you need to call a method that will be overridden in a derived class, you have to use `SetUp()/TearDown()`.
|
||||
|
||||
## The compiler complains "no matching function to call" when I use ASSERT\_PREDn. How do I fix it? ##
|
||||
|
||||
|
@ -239,7 +239,7 @@ To create a test:
|
||||
1. 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.
|
||||
|
||||
```
|
||||
TEST(test_case_name, test_name) {
|
||||
TEST(testCaseName, testName) {
|
||||
... test body ...
|
||||
}
|
||||
```
|
||||
|
@ -102,7 +102,7 @@ GTEST_API_ bool InDeathTestChild();
|
||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||
// which uses the POSIX extended regex syntax.
|
||||
//
|
||||
// On other platforms (e.g. Windows), we only support a simple regex
|
||||
// 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
|
||||
@ -272,6 +272,54 @@ class GTEST_API_ KilledBySignal {
|
||||
# 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
|
||||
// iff 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 iff 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
|
||||
@ -284,9 +332,9 @@ class GTEST_API_ KilledBySignal {
|
||||
ASSERT_DEATH(statement, regex)
|
||||
#else
|
||||
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
|
||||
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
|
||||
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
|
||||
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
@ -196,7 +196,6 @@ class GTEST_API_ Message {
|
||||
std::string GetString() const;
|
||||
|
||||
private:
|
||||
|
||||
#if GTEST_OS_SYMBIAN
|
||||
// These are needed as the Nokia Symbian Compiler cannot decide between
|
||||
// const T& and const T* in a function template. The Nokia compiler _can_
|
||||
|
@ -38,6 +38,7 @@
|
||||
//
|
||||
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||
//
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
|
||||
@ -79,7 +80,7 @@ TEST_P(FooTest, HasBlahBlah) {
|
||||
// Finally, you can use INSTANTIATE_TEST_CASE_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
|
||||
// (surprise!) parameter generators. Here is a summary of them, which
|
||||
// are all in the testing namespace:
|
||||
//
|
||||
//
|
||||
@ -268,7 +269,7 @@ internal::ParamGenerator<T> Range(T start, T end) {
|
||||
// each with C-string values of "foo", "bar", and "baz":
|
||||
//
|
||||
// const char* strings[] = {"foo", "bar", "baz"};
|
||||
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
|
||||
// INSTANTIATE_TEST_CASE_P(StringSequence, StringTest, ValuesIn(strings));
|
||||
//
|
||||
// This instantiates tests from test case StlStringTest
|
||||
// each with STL strings with values "a" and "b":
|
||||
@ -1407,30 +1408,32 @@ internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
|
||||
// type testing::TestParamInfo<class ParamType>, 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.
|
||||
// returns the value of testing::PrintToString(GetParam()).
|
||||
//
|
||||
// Note: test names must be non-empty, unique, and may only contain ASCII
|
||||
// alphanumeric characters or underscore.
|
||||
// alphanumeric characters or underscore. Because PrintToString adds quotes
|
||||
// to std::string and C strings, it won't work for these types.
|
||||
|
||||
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
|
||||
::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
||||
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
||||
::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
||||
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
||||
return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
|
||||
(__VA_ARGS__)(info); \
|
||||
} \
|
||||
int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||
GetTestCasePatternHolder<test_case_name>(\
|
||||
#test_case_name, \
|
||||
::testing::internal::CodeLocation(\
|
||||
__FILE__, __LINE__))->AddTestCaseInstantiation(\
|
||||
#prefix, \
|
||||
>est_##prefix##test_case_name##_EvalGenerator_, \
|
||||
>est_##prefix##test_case_name##_EvalGenerateName_, \
|
||||
__FILE__, __LINE__)
|
||||
#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
|
||||
static ::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
||||
gtest_##prefix##test_case_name##_EvalGenerator_() { \
|
||||
return generator; \
|
||||
} \
|
||||
static ::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
||||
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
||||
return ::testing::internal::GetParamNameGen<test_case_name::ParamType>( \
|
||||
__VA_ARGS__)(info); \
|
||||
} \
|
||||
static int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::UnitTest::GetInstance() \
|
||||
->parameterized_test_registry() \
|
||||
.GetTestCasePatternHolder<test_case_name>( \
|
||||
#test_case_name, \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||
->AddTestCaseInstantiation( \
|
||||
#prefix, >est_##prefix##test_case_name##_EvalGenerator_, \
|
||||
>est_##prefix##test_case_name##_EvalGenerateName_, __FILE__, \
|
||||
__LINE__)
|
||||
|
||||
} // namespace testing
|
||||
|
||||
|
@ -78,7 +78,7 @@ TEST_P(FooTest, HasBlahBlah) {
|
||||
// Finally, you can use INSTANTIATE_TEST_CASE_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
|
||||
// (surprise!) parameter generators. Here is a summary of them, which
|
||||
// are all in the testing namespace:
|
||||
//
|
||||
//
|
||||
@ -267,7 +267,7 @@ internal::ParamGenerator<T> Range(T start, T end) {
|
||||
// each with C-string values of "foo", "bar", and "baz":
|
||||
//
|
||||
// const char* strings[] = {"foo", "bar", "baz"};
|
||||
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
|
||||
// INSTANTIATE_TEST_CASE_P(StringSequence, StringTest, ValuesIn(strings));
|
||||
//
|
||||
// This instantiates tests from test case StlStringTest
|
||||
// each with STL strings with values "a" and "b":
|
||||
@ -480,14 +480,14 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
|
||||
// to std::string and C strings, it won't work for these types.
|
||||
|
||||
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
|
||||
::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
||||
static ::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
||||
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
||||
::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
||||
static ::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
||||
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
||||
return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
|
||||
(__VA_ARGS__)(info); \
|
||||
} \
|
||||
int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
static int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||
GetTestCasePatternHolder<test_case_name>(\
|
||||
#test_case_name, \
|
||||
|
@ -46,6 +46,10 @@
|
||||
// 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.
|
||||
@ -107,6 +111,11 @@
|
||||
# include <tuple>
|
||||
#endif
|
||||
|
||||
#if GTEST_HAS_ABSL
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Definitions in the 'internal' and 'internal2' name spaces are
|
||||
@ -125,7 +134,11 @@ enum TypeKind {
|
||||
kProtobuf, // a protobuf type
|
||||
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
|
||||
// (e.g. a named or unnamed enum type)
|
||||
kOtherType // anything else
|
||||
#if GTEST_HAS_ABSL
|
||||
kConvertibleToStringView, // a type implicitly convertible to
|
||||
// absl::string_view
|
||||
#endif
|
||||
kOtherType // anything else
|
||||
};
|
||||
|
||||
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
|
||||
@ -138,7 +151,7 @@ class TypeWithoutFormatter {
|
||||
// This default version is called when kTypeKind is kOtherType.
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
PrintBytesInObjectTo(static_cast<const unsigned char*>(
|
||||
reinterpret_cast<const void *>(&value)),
|
||||
reinterpret_cast<const void*>(&value)),
|
||||
sizeof(value), os);
|
||||
}
|
||||
};
|
||||
@ -176,6 +189,19 @@ class TypeWithoutFormatter<T, kConvertibleToInteger> {
|
||||
}
|
||||
};
|
||||
|
||||
#if GTEST_HAS_ABSL
|
||||
template <typename T>
|
||||
class TypeWithoutFormatter<T, kConvertibleToStringView> {
|
||||
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
|
||||
@ -203,10 +229,19 @@ class TypeWithoutFormatter<T, kConvertibleToInteger> {
|
||||
template <typename Char, typename CharTraits, typename T>
|
||||
::std::basic_ostream<Char, CharTraits>& operator<<(
|
||||
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
|
||||
TypeWithoutFormatter<T,
|
||||
(internal::IsAProtocolMessage<T>::value ? kProtobuf :
|
||||
internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?
|
||||
kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);
|
||||
TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
|
||||
? kProtobuf
|
||||
: internal::ImplicitlyConvertible<
|
||||
const T&, internal::BiggestInt>::value
|
||||
? kConvertibleToInteger
|
||||
:
|
||||
#if GTEST_HAS_ABSL
|
||||
internal::ImplicitlyConvertible<
|
||||
const T&, absl::string_view>::value
|
||||
? kConvertibleToStringView
|
||||
:
|
||||
#endif
|
||||
kOtherType)>::PrintValue(x, &os);
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -428,12 +463,8 @@ void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
|
||||
} 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*. However, we cannot cast it to const void* directly,
|
||||
// even using reinterpret_cast, as earlier versions of gcc
|
||||
// (e.g. 3.4.5) cannot compile the cast when p is a function
|
||||
// pointer. Casting to UInt64 first solves the problem.
|
||||
*os << reinterpret_cast<const void*>(
|
||||
reinterpret_cast<internal::UInt64>(p));
|
||||
// void*.
|
||||
*os << reinterpret_cast<const void*>(p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -461,17 +492,15 @@ 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 recursive and other container types here, prior
|
||||
// to we check for protocol message types in our operator<<. The rationale is:
|
||||
// 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. To prevent an infinite runtime recursion
|
||||
// during the output of recursive container types, we check first for
|
||||
// those.
|
||||
// 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.
|
||||
@ -489,8 +518,8 @@ void PrintTo(const T& value, ::std::ostream* os) {
|
||||
#else
|
||||
: !internal::ImplicitlyConvertible<T, const void*>::value
|
||||
#endif
|
||||
? kPrintFunctionPointer
|
||||
: kPrintPointer>(),
|
||||
? kPrintFunctionPointer
|
||||
: kPrintPointer>(),
|
||||
value, os);
|
||||
}
|
||||
|
||||
@ -598,6 +627,13 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* 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
|
||||
|
||||
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
||||
// Helper function for printing a tuple. T must be instantiated with
|
||||
// a tuple type.
|
||||
@ -727,6 +763,26 @@ class UniversalPrinter {
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||
};
|
||||
|
||||
#if GTEST_HAS_ABSL
|
||||
|
||||
// Printer for absl::optional
|
||||
|
||||
template <typename T>
|
||||
class UniversalPrinter<::absl::optional<T>> {
|
||||
public:
|
||||
static void Print(const ::absl::optional<T>& value, ::std::ostream* os) {
|
||||
*os << '(';
|
||||
if (!value) {
|
||||
*os << "nullopt";
|
||||
} else {
|
||||
UniversalPrint(*value, os);
|
||||
}
|
||||
*os << ')';
|
||||
}
|
||||
};
|
||||
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||
// elements, starting at address 'begin'.
|
||||
template <typename T>
|
||||
@ -873,7 +929,7 @@ void UniversalPrint(const T& value, ::std::ostream* os) {
|
||||
UniversalPrinter<T1>::Print(value, os);
|
||||
}
|
||||
|
||||
typedef ::std::vector<string> Strings;
|
||||
typedef ::std::vector< ::std::string> Strings;
|
||||
|
||||
// TuplePolicy<TupleT> must provide:
|
||||
// - tuple_size
|
||||
@ -993,6 +1049,16 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
||||
|
||||
} // namespace internal
|
||||
|
||||
#if GTEST_HAS_ABSL
|
||||
namespace internal2 {
|
||||
template <typename T>
|
||||
void TypeWithoutFormatter<T, kConvertibleToStringView>::PrintValue(
|
||||
const T& value, ::std::ostream* os) {
|
||||
internal::PrintTo(absl::string_view(value), os);
|
||||
}
|
||||
} // namespace internal2
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
::std::string PrintToString(const T& value) {
|
||||
::std::stringstream ss;
|
||||
|
@ -243,7 +243,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
||||
} \
|
||||
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) \
|
||||
GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames( \
|
||||
__FILE__, __LINE__, #__VA_ARGS__)
|
||||
|
||||
// The 'Types' template argument below must have spaces around it
|
||||
|
@ -115,6 +115,9 @@ GTEST_DECLARE_string_(output);
|
||||
// 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);
|
||||
|
||||
@ -135,7 +138,7 @@ 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.
|
||||
// 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
|
||||
@ -259,7 +262,9 @@ class GTEST_API_ AssertionResult {
|
||||
// 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).
|
||||
//
|
||||
@ -276,7 +281,9 @@ class GTEST_API_ AssertionResult {
|
||||
/*enabler*/ = NULL)
|
||||
: success_(success) {}
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1910
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||
#endif
|
||||
|
||||
// Assignment operator.
|
||||
AssertionResult& operator=(AssertionResult other) {
|
||||
@ -345,6 +352,15 @@ GTEST_API_ AssertionResult AssertionFailure();
|
||||
// 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 TestCases, and
|
||||
@ -355,7 +371,7 @@ GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
|
||||
// this for you.
|
||||
//
|
||||
// The only time you derive from Test is when defining a test fixture
|
||||
// to be used a TEST_F. For example:
|
||||
// to be used in a TEST_F. For example:
|
||||
//
|
||||
// class FooTest : public testing::Test {
|
||||
// protected:
|
||||
@ -550,9 +566,8 @@ class GTEST_API_ TestResult {
|
||||
// Returns the elapsed time, in milliseconds.
|
||||
TimeInMillis elapsed_time() const { return elapsed_time_; }
|
||||
|
||||
// Returns the i-th test part result among all the results. i can range
|
||||
// from 0 to test_property_count() - 1. If i is not in that range, aborts
|
||||
// the program.
|
||||
// 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
|
||||
@ -675,6 +690,9 @@ class GTEST_API_ TestInfo {
|
||||
// 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.
|
||||
@ -695,10 +713,9 @@ class GTEST_API_ TestInfo {
|
||||
|
||||
// Returns true iff this test will appear in the XML report.
|
||||
bool is_reportable() const {
|
||||
// For now, the XML report includes all tests matching the filter.
|
||||
// In the future, we may trim tests that are excluded because of
|
||||
// sharding.
|
||||
return matches_filter_;
|
||||
// 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.
|
||||
@ -762,6 +779,7 @@ class GTEST_API_ TestInfo {
|
||||
bool is_disabled_; // True iff 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
|
||||
|
||||
@ -986,6 +1004,18 @@ class Environment {
|
||||
virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
|
||||
};
|
||||
|
||||
#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 {
|
||||
@ -1014,6 +1044,8 @@ class TestEventListener {
|
||||
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.
|
||||
@ -1287,9 +1319,9 @@ class GTEST_API_ UnitTest {
|
||||
|
||||
// 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::ScopedTrace;
|
||||
friend class internal::StreamingListenerTest;
|
||||
friend class internal::UnitTestRecordPropertyTestHelper;
|
||||
friend Environment* AddGlobalTestEnvironment(Environment* env);
|
||||
@ -1778,7 +1810,6 @@ template <typename T>
|
||||
class TestWithParam : public Test, public WithParamInterface<T> {
|
||||
};
|
||||
|
||||
|
||||
// Macros for indicating success/failure in test code.
|
||||
|
||||
// ADD_FAILURE unconditionally adds a failure to the current test.
|
||||
@ -1851,22 +1882,18 @@ class TestWithParam : public Test, public WithParamInterface<T> {
|
||||
// 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_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_TEST_BOOLEAN_(condition, #condition, false, true, \
|
||||
GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_FALSE(condition) \
|
||||
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
|
||||
GTEST_FATAL_FAILURE_)
|
||||
|
||||
// Includes the auto-generated header that implements a family of
|
||||
// generic predicate assertion macros.
|
||||
#include "gtest/gtest_pred_impl.h"
|
||||
|
||||
// Macros for testing equalities and inequalities.
|
||||
//
|
||||
// * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2
|
||||
@ -1908,8 +1935,8 @@ class TestWithParam : public Test, public WithParamInterface<T> {
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// EXPECT_NE(5, Foo());
|
||||
// EXPECT_EQ(NULL, a_pointer);
|
||||
// EXPECT_NE(Foo(), 5);
|
||||
// EXPECT_EQ(a_pointer, NULL);
|
||||
// ASSERT_LT(i, array_size);
|
||||
// ASSERT_GT(records.size(), 0) << "There is no record left.";
|
||||
|
||||
@ -2095,6 +2122,57 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
|
||||
#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 <typename T>
|
||||
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)");
|
||||
}
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
ScopedTrace(const char* file, int line, const ::string& message) {
|
||||
PushTrace(file, line, message);
|
||||
}
|
||||
#endif
|
||||
|
||||
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
|
||||
@ -2106,9 +2184,14 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
|
||||
// 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::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
|
||||
__FILE__, __LINE__, ::testing::Message() << (message))
|
||||
::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
|
||||
__FILE__, __LINE__, (message))
|
||||
|
||||
|
||||
// Compile-time assertion for type equality.
|
||||
// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
|
||||
@ -2203,8 +2286,8 @@ bool StaticAssertTypeEq() {
|
||||
// }
|
||||
//
|
||||
// TEST_F(FooTest, ReturnsElementCountCorrectly) {
|
||||
// EXPECT_EQ(0, a_.size());
|
||||
// EXPECT_EQ(1, b_.size());
|
||||
// EXPECT_EQ(a_.size(), 0);
|
||||
// EXPECT_EQ(b_.size(), 1);
|
||||
// }
|
||||
|
||||
#define TEST_F(test_fixture, test_name)\
|
||||
|
@ -27,7 +27,7 @@
|
||||
// (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 10/31/2011 by command
|
||||
// This file is AUTOMATICALLY GENERATED on 01/02/2018 by command
|
||||
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||
//
|
||||
// Implements a family of generic predicate assertion macros.
|
||||
@ -35,10 +35,9 @@
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
|
||||
// Makes sure this header is not included before gtest.h.
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// This header implements a family of generic predicate assertion
|
||||
// macros:
|
||||
@ -66,8 +65,6 @@
|
||||
// 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.
|
||||
@ -355,4 +352,6 @@ AssertionResult AssertPred5Helper(const char* pred_text,
|
||||
|
||||
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
|
@ -40,17 +40,20 @@
|
||||
//
|
||||
// class MyClass {
|
||||
// private:
|
||||
// void MyMethod();
|
||||
// FRIEND_TEST(MyClassTest, MyMethod);
|
||||
// void PrivateMethod();
|
||||
// FRIEND_TEST(MyClassTest, PrivateMethodWorks);
|
||||
// };
|
||||
//
|
||||
// class MyClassTest : public testing::Test {
|
||||
// // ...
|
||||
// };
|
||||
//
|
||||
// TEST_F(MyClassTest, MyMethod) {
|
||||
// // Can call MyClass::MyMethod() here.
|
||||
// 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
|
||||
|
@ -61,6 +61,9 @@
|
||||
// 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.
|
||||
//
|
||||
|
@ -36,7 +36,7 @@
|
||||
// GTEST_CUSTOM_TEMPDIR_FUNCTION_ - An override for testing::TempDir().
|
||||
// See testing::TempDir for semantics and
|
||||
// signature.
|
||||
//
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
||||
|
@ -27,7 +27,6 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
@ -264,53 +263,6 @@ class InternalRunDeathTestFlag {
|
||||
// the flag is specified; otherwise returns NULL.
|
||||
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
|
||||
|
||||
#else // 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
|
||||
// iff 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.
|
||||
//
|
||||
// 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 iff 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()
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
} // namespace internal
|
||||
|
@ -27,14 +27,13 @@
|
||||
// (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: keith.ray@gmail.com (Keith Ray)
|
||||
//
|
||||
// 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>.
|
||||
// This file is #included in gtest/internal/gtest-internal.h.
|
||||
// Do not include this header file separately!
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
|
@ -27,7 +27,6 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
@ -61,8 +60,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/internal/gtest-string.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
|
||||
@ -96,7 +95,6 @@ template <typename T>
|
||||
namespace internal {
|
||||
|
||||
struct TraceInfo; // Information about a trace point.
|
||||
class ScopedTrace; // Implements scoped trace.
|
||||
class TestInfoImpl; // Opaque implementation of TestInfo
|
||||
class UnitTestImpl; // Opaque implementation of UnitTest
|
||||
|
||||
@ -152,30 +150,11 @@ class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {
|
||||
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// A helper class for creating scoped traces in user programs.
|
||||
class GTEST_API_ ScopedTrace {
|
||||
public:
|
||||
// The c'tor pushes the given source file location and message onto
|
||||
// a trace stack maintained by Google Test.
|
||||
ScopedTrace(const char* file, int line, const Message& 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:
|
||||
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.
|
||||
|
||||
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.
|
||||
// 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<EditType> CalculateOptimalEdits(
|
||||
@ -628,7 +607,7 @@ class TypeParameterizedTest {
|
||||
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
||||
// length of Types.
|
||||
static bool Register(const char* prefix,
|
||||
CodeLocation code_location,
|
||||
const CodeLocation& code_location,
|
||||
const char* case_name, const char* test_names,
|
||||
int index) {
|
||||
typedef typename Types::Head Type;
|
||||
@ -659,7 +638,7 @@ class TypeParameterizedTest {
|
||||
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
||||
class TypeParameterizedTest<Fixture, TestSel, Types0> {
|
||||
public:
|
||||
static bool Register(const char* /*prefix*/, CodeLocation,
|
||||
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
||||
const char* /*case_name*/, const char* /*test_names*/,
|
||||
int /*index*/) {
|
||||
return true;
|
||||
@ -705,7 +684,7 @@ class TypeParameterizedTestCase {
|
||||
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
||||
class TypeParameterizedTestCase<Fixture, Templates0, Types> {
|
||||
public:
|
||||
static bool Register(const char* /*prefix*/, CodeLocation,
|
||||
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
||||
const TypedTestCasePState* /*state*/,
|
||||
const char* /*case_name*/, const char* /*test_names*/) {
|
||||
return true;
|
||||
@ -824,31 +803,6 @@ struct RemoveConst<T[N]> {
|
||||
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
|
||||
GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))
|
||||
|
||||
// Adds reference to a type if it is not a reference type,
|
||||
// otherwise leaves it unchanged. This is the same as
|
||||
// tr1::add_reference, which is not widely available yet.
|
||||
template <typename T>
|
||||
struct AddReference { typedef T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct AddReference<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper around AddReference that works when the argument T
|
||||
// depends on template parameters.
|
||||
#define GTEST_ADD_REFERENCE_(T) \
|
||||
typename ::testing::internal::AddReference<T>::type
|
||||
|
||||
// Adds a reference to const on top of T as necessary. For example,
|
||||
// it transforms
|
||||
//
|
||||
// char ==> const char&
|
||||
// const char ==> const char&
|
||||
// char& ==> const char&
|
||||
// const char& ==> const char&
|
||||
//
|
||||
// The argument T must depend on some template parameters.
|
||||
#define GTEST_REFERENCE_TO_CONST_(T) \
|
||||
GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T))
|
||||
|
||||
// ImplicitlyConvertible<From, To>::value is a compile-time bool
|
||||
// constant that's true iff type From can be implicitly converted to
|
||||
// type To.
|
||||
@ -1096,7 +1050,7 @@ class NativeArray {
|
||||
private:
|
||||
enum {
|
||||
kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper<
|
||||
Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value,
|
||||
Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value
|
||||
};
|
||||
|
||||
// Initializes this object with a copy of the input.
|
||||
|
@ -3203,7 +3203,7 @@ class CartesianProductGenerator2
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -3235,7 +3235,7 @@ class CartesianProductGenerator2
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType(*current1_, *current2_);
|
||||
current_value_.reset(new ParamType(*current1_, *current2_));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -3257,7 +3257,7 @@ class CartesianProductGenerator2
|
||||
const typename ParamGenerator<T2>::iterator begin2_;
|
||||
const typename ParamGenerator<T2>::iterator end2_;
|
||||
typename ParamGenerator<T2>::iterator current2_;
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator2::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
@ -3326,7 +3326,7 @@ class CartesianProductGenerator3
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -3362,7 +3362,7 @@ class CartesianProductGenerator3
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType(*current1_, *current2_, *current3_);
|
||||
current_value_.reset(new ParamType(*current1_, *current2_, *current3_));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -3388,7 +3388,7 @@ class CartesianProductGenerator3
|
||||
const typename ParamGenerator<T3>::iterator begin3_;
|
||||
const typename ParamGenerator<T3>::iterator end3_;
|
||||
typename ParamGenerator<T3>::iterator current3_;
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator3::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
@ -3467,7 +3467,7 @@ class CartesianProductGenerator4
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -3507,8 +3507,8 @@ class CartesianProductGenerator4
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_);
|
||||
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -3538,7 +3538,7 @@ class CartesianProductGenerator4
|
||||
const typename ParamGenerator<T4>::iterator begin4_;
|
||||
const typename ParamGenerator<T4>::iterator end4_;
|
||||
typename ParamGenerator<T4>::iterator current4_;
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator4::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
@ -3625,7 +3625,7 @@ class CartesianProductGenerator5
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -3669,8 +3669,8 @@ class CartesianProductGenerator5
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_);
|
||||
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -3704,7 +3704,7 @@ class CartesianProductGenerator5
|
||||
const typename ParamGenerator<T5>::iterator begin5_;
|
||||
const typename ParamGenerator<T5>::iterator end5_;
|
||||
typename ParamGenerator<T5>::iterator current5_;
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator5::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
@ -3802,7 +3802,7 @@ class CartesianProductGenerator6
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -3850,8 +3850,8 @@ class CartesianProductGenerator6
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_, *current6_);
|
||||
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_, *current6_));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -3889,7 +3889,7 @@ class CartesianProductGenerator6
|
||||
const typename ParamGenerator<T6>::iterator begin6_;
|
||||
const typename ParamGenerator<T6>::iterator end6_;
|
||||
typename ParamGenerator<T6>::iterator current6_;
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator6::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
@ -3996,7 +3996,7 @@ class CartesianProductGenerator7
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -4048,8 +4048,8 @@ class CartesianProductGenerator7
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_, *current6_, *current7_);
|
||||
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_, *current6_, *current7_));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -4091,7 +4091,7 @@ class CartesianProductGenerator7
|
||||
const typename ParamGenerator<T7>::iterator begin7_;
|
||||
const typename ParamGenerator<T7>::iterator end7_;
|
||||
typename ParamGenerator<T7>::iterator current7_;
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator7::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
@ -4209,7 +4209,7 @@ class CartesianProductGenerator8
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -4265,8 +4265,8 @@ class CartesianProductGenerator8
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_, *current6_, *current7_, *current8_);
|
||||
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_, *current6_, *current7_, *current8_));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -4312,7 +4312,7 @@ class CartesianProductGenerator8
|
||||
const typename ParamGenerator<T8>::iterator begin8_;
|
||||
const typename ParamGenerator<T8>::iterator end8_;
|
||||
typename ParamGenerator<T8>::iterator current8_;
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator8::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
@ -4438,7 +4438,7 @@ class CartesianProductGenerator9
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -4498,9 +4498,9 @@ class CartesianProductGenerator9
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
||||
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_, *current6_, *current7_, *current8_,
|
||||
*current9_);
|
||||
*current9_));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -4550,7 +4550,7 @@ class CartesianProductGenerator9
|
||||
const typename ParamGenerator<T9>::iterator begin9_;
|
||||
const typename ParamGenerator<T9>::iterator end9_;
|
||||
typename ParamGenerator<T9>::iterator current9_;
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator9::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
@ -4685,7 +4685,7 @@ class CartesianProductGenerator10
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -4749,9 +4749,9 @@ class CartesianProductGenerator10
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
||||
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||
*current4_, *current5_, *current6_, *current7_, *current8_,
|
||||
*current9_, *current10_);
|
||||
*current9_, *current10_));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -4805,7 +4805,7 @@ class CartesianProductGenerator10
|
||||
const typename ParamGenerator<T10>::iterator begin10_;
|
||||
const typename ParamGenerator<T10>::iterator end10_;
|
||||
typename ParamGenerator<T10>::iterator current10_;
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator10::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
|
@ -160,7 +160,7 @@ $for k [[
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
@ -192,7 +192,7 @@ $for k [[
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType($for j, [[*current$(j)_]]);
|
||||
current_value_.reset(new ParamType($for j, [[*current$(j)_]]));
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
@ -217,7 +217,7 @@ $for j [[
|
||||
typename ParamGenerator<T$j>::iterator current$(j)_;
|
||||
]]
|
||||
|
||||
ParamType current_value_;
|
||||
linked_ptr<ParamType> current_value_;
|
||||
}; // class CartesianProductGenerator$i::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
|
@ -54,6 +54,9 @@
|
||||
# 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.
|
||||
|
@ -73,11 +73,9 @@
|
||||
// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions
|
||||
// are enabled.
|
||||
// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string
|
||||
// is/isn't available (some systems define
|
||||
// ::string, which is different to std::string).
|
||||
// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
|
||||
// is/isn't available (some systems define
|
||||
// ::wstring, which is different to std::wstring).
|
||||
// is/isn't available
|
||||
// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::wstring
|
||||
// is/isn't available
|
||||
// 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 <pthread.h>
|
||||
@ -109,6 +107,12 @@
|
||||
// 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
|
||||
// --------------------------
|
||||
@ -178,7 +182,7 @@
|
||||
// GTEST_HAS_POSIX_RE (see above) which users can
|
||||
// define themselves.
|
||||
// GTEST_USES_SIMPLE_RE - our own simple regex is used;
|
||||
// the above two are mutually exclusive.
|
||||
// the above RE\b(s) are mutually exclusive.
|
||||
// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
|
||||
|
||||
// Misc public macros
|
||||
@ -207,6 +211,7 @@
|
||||
//
|
||||
// C++11 feature wrappers:
|
||||
//
|
||||
// testing::internal::forward - portability wrapper for std::forward.
|
||||
// testing::internal::move - portability wrapper for std::move.
|
||||
//
|
||||
// Synchronization:
|
||||
@ -272,10 +277,12 @@
|
||||
# include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
// Brings in the definition of HAS_GLOBAL_STRING. This must be done
|
||||
// BEFORE we test HAS_GLOBAL_STRING.
|
||||
#include <string> // NOLINT
|
||||
#include <algorithm> // NOLINT
|
||||
#include <iostream> // NOLINT
|
||||
#include <sstream> // NOLINT
|
||||
#include <string> // NOLINT
|
||||
#include <utility>
|
||||
#include <vector> // NOLINT
|
||||
|
||||
@ -464,8 +471,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#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(__BORLANDC__)
|
||||
// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
|
||||
# if defined(_MSC_VER) && defined(_CPPUNWIND)
|
||||
// MSVC defines _CPPUNWIND to 1 iff 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
|
||||
@ -611,8 +621,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
//
|
||||
// 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 || \
|
||||
#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)
|
||||
#endif // GTEST_HAS_PTHREAD
|
||||
|
||||
@ -806,9 +816,9 @@ using ::std::tuple_size;
|
||||
// Google Test does not support death tests for VC 7.1 and earlier as
|
||||
// abort() in a VC 7.1 application compiled as GUI in debug config
|
||||
// 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 >= 1400) || \
|
||||
#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
|
||||
(GTEST_OS_MAC && !GTEST_OS_IOS) || \
|
||||
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
|
||||
GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
|
||||
GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NETBSD)
|
||||
# define GTEST_HAS_DEATH_TEST 1
|
||||
@ -824,10 +834,11 @@ using ::std::tuple_size;
|
||||
# define GTEST_HAS_TYPED_TEST_P 1
|
||||
#endif
|
||||
|
||||
// Determines whether to support Combine().
|
||||
// The implementation doesn't work on Sun Studio since it doesn't
|
||||
// understand templated conversion operators.
|
||||
#if GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
|
||||
// Determines whether to support Combine(). This only makes sense when
|
||||
// value-parameterized tests are enabled. The implementation doesn't
|
||||
// work on Sun Studio since it doesn't understand templated conversion
|
||||
// operators.
|
||||
#if (GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_) && !defined(__SUNPRO_CC)
|
||||
# define GTEST_HAS_COMBINE 1
|
||||
#endif
|
||||
|
||||
@ -879,7 +890,7 @@ using ::std::tuple_size;
|
||||
#endif
|
||||
|
||||
// Use this annotation before a function that takes a printf format string.
|
||||
#if defined(__GNUC__) && !defined(COMPILER_ICC)
|
||||
#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
|
||||
@ -972,6 +983,10 @@ using ::std::tuple_size;
|
||||
# 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))
|
||||
@ -980,7 +995,7 @@ using ::std::tuple_size;
|
||||
#endif
|
||||
|
||||
// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.
|
||||
#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)
|
||||
#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
|
||||
# define GTEST_HAS_CXXABI_H_ 1
|
||||
#else
|
||||
# define GTEST_HAS_CXXABI_H_ 0
|
||||
@ -1126,6 +1141,16 @@ struct StaticAssertTypeEqHelper<T, T> {
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
// Same as std::is_same<>.
|
||||
template <typename T, typename U>
|
||||
struct IsSame {
|
||||
enum { value = false };
|
||||
};
|
||||
template <typename T>
|
||||
struct IsSame<T, T> {
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
// Evaluates to the number of elements in 'array'.
|
||||
#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
@ -1189,6 +1214,10 @@ class scoped_ptr {
|
||||
|
||||
// Defines RE.
|
||||
|
||||
#if GTEST_USES_PCRE
|
||||
using ::RE;
|
||||
#elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE
|
||||
|
||||
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
|
||||
// Regular Expression syntax.
|
||||
class GTEST_API_ RE {
|
||||
@ -1200,11 +1229,11 @@ class GTEST_API_ RE {
|
||||
// Constructs an RE from a string.
|
||||
RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
# if GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT
|
||||
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
# endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
RE(const char* regex) { Init(regex); } // NOLINT
|
||||
~RE();
|
||||
@ -1226,7 +1255,7 @@ class GTEST_API_ RE {
|
||||
return PartialMatch(str.c_str(), re);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
# if GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
static bool FullMatch(const ::string& str, const RE& re) {
|
||||
return FullMatch(str.c_str(), re);
|
||||
@ -1235,7 +1264,7 @@ class GTEST_API_ RE {
|
||||
return PartialMatch(str.c_str(), re);
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
# endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
static bool FullMatch(const char* str, const RE& re);
|
||||
static bool PartialMatch(const char* str, const RE& re);
|
||||
@ -1249,20 +1278,22 @@ class GTEST_API_ RE {
|
||||
const char* pattern_;
|
||||
bool is_valid_;
|
||||
|
||||
#if GTEST_USES_POSIX_RE
|
||||
# if GTEST_USES_POSIX_RE
|
||||
|
||||
regex_t full_regex_; // For FullMatch().
|
||||
regex_t partial_regex_; // For PartialMatch().
|
||||
|
||||
#else // GTEST_USES_SIMPLE_RE
|
||||
# else // GTEST_USES_SIMPLE_RE
|
||||
|
||||
const char* full_pattern_; // For FullMatch();
|
||||
|
||||
#endif
|
||||
# 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);
|
||||
@ -1348,13 +1379,57 @@ inline void FlushInfoLog() { fflush(NULL); }
|
||||
GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
|
||||
<< gtest_error
|
||||
|
||||
// Adds reference to a type if it is not a reference type,
|
||||
// otherwise leaves it unchanged. This is the same as
|
||||
// tr1::add_reference, which is not widely available yet.
|
||||
template <typename T>
|
||||
struct AddReference { typedef T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct AddReference<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper around AddReference that works when the argument T
|
||||
// depends on template parameters.
|
||||
#define GTEST_ADD_REFERENCE_(T) \
|
||||
typename ::testing::internal::AddReference<T>::type
|
||||
|
||||
// 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 <typename T>
|
||||
struct ConstRef { typedef const T& type; };
|
||||
template <typename T>
|
||||
struct ConstRef<T&> { typedef T& type; };
|
||||
|
||||
// The argument T must depend on some template parameters.
|
||||
#define GTEST_REFERENCE_TO_CONST_(T) \
|
||||
typename ::testing::internal::ConstRef<T>::type
|
||||
|
||||
#if GTEST_HAS_STD_MOVE_
|
||||
using std::forward;
|
||||
using std::move;
|
||||
|
||||
template <typename T>
|
||||
struct RvalueRef {
|
||||
typedef T&& type;
|
||||
};
|
||||
#else // GTEST_HAS_STD_MOVE_
|
||||
template <typename T>
|
||||
const T& move(const T& t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct RvalueRef {
|
||||
typedef const T& type;
|
||||
};
|
||||
#endif // GTEST_HAS_STD_MOVE_
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
@ -1455,7 +1530,6 @@ 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);
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
@ -35,7 +34,8 @@
|
||||
// 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/gtest-internal.h>.
|
||||
// This header file is #included by
|
||||
// gtest/internal/gtest-internal.h.
|
||||
// It should not be #included by other files.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
|
@ -103,11 +103,15 @@ class PreCalculatedPrimeTable : public PrimeTable {
|
||||
::std::fill(is_prime_, is_prime_ + is_prime_size_, true);
|
||||
is_prime_[0] = is_prime_[1] = false;
|
||||
|
||||
for (int i = 2; i <= max; i++) {
|
||||
// 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.
|
||||
for (int j = 2*i; j <= max; j += i) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -29,10 +29,12 @@
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "sample4.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
// Tests the Increment() method.
|
||||
|
||||
TEST(Counter, Increment) {
|
||||
Counter c;
|
||||
|
||||
@ -43,4 +45,5 @@ TEST(Counter, Increment) {
|
||||
EXPECT_EQ(1, c.Increment());
|
||||
EXPECT_EQ(2, c.Increment());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -46,9 +46,9 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include "sample3-inl.h"
|
||||
#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
|
||||
|
@ -66,22 +66,18 @@
|
||||
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick exists to
|
||||
// prevent the accidental inclusion of gtest-internal-inl.h in the
|
||||
// user's code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Constants.
|
||||
|
||||
// The default death test style.
|
||||
static const char kDefaultDeathTestStyle[] = "fast";
|
||||
//
|
||||
// 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,
|
||||
@ -259,7 +255,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
|
||||
// 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.
|
||||
void DeathTestAbort(const std::string& message) {
|
||||
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.
|
||||
@ -563,7 +559,13 @@ bool DeathTestImpl::Passed(bool status_ok) {
|
||||
break;
|
||||
case DIED:
|
||||
if (status_ok) {
|
||||
# if GTEST_USES_PCRE
|
||||
// PCRE regexes support embedded NULs.
|
||||
// GTEST_USES_PCRE is defined only in google3 mode
|
||||
const bool matched = RE::PartialMatch(error_message, *regex());
|
||||
# else
|
||||
const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
|
||||
# endif // GTEST_USES_PCRE
|
||||
if (matched) {
|
||||
success = true;
|
||||
} else {
|
||||
@ -985,6 +987,7 @@ static int ExecDeathTestChildMain(void* child_arg) {
|
||||
}
|
||||
# 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
|
||||
@ -994,20 +997,22 @@ static int ExecDeathTestChildMain(void* child_arg) {
|
||||
// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
|
||||
// StackLowerThanAddress into StackGrowsDown, which then doesn't give
|
||||
// correct answer.
|
||||
void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_;
|
||||
void StackLowerThanAddress(const void* ptr, bool* result) {
|
||||
static void StackLowerThanAddress(const void* ptr,
|
||||
bool* result) GTEST_NO_INLINE_;
|
||||
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_
|
||||
bool StackGrowsDown() {
|
||||
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
|
||||
@ -1223,7 +1228,7 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
|
||||
// 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.
|
||||
int GetStatusFileDescriptor(unsigned int parent_process_id,
|
||||
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,
|
||||
|
@ -26,14 +26,12 @@
|
||||
// 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.
|
||||
//
|
||||
// Authors: keith.ray@gmail.com (Keith Ray)
|
||||
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/internal/gtest-filepath.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gtest/gtest-message.h"
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
# include <windows.h>
|
||||
@ -48,6 +46,8 @@
|
||||
# include <climits> // 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)
|
||||
@ -58,8 +58,6 @@
|
||||
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
@ -130,7 +128,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Returns a pointer to the last occurence of a valid path separator in
|
||||
// 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 {
|
||||
|
@ -37,14 +37,6 @@
|
||||
#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
|
||||
#define GTEST_SRC_GTEST_INTERNAL_INL_H_
|
||||
|
||||
// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is
|
||||
// part of Google Test's implementation; otherwise it's undefined.
|
||||
#if !GTEST_IMPLEMENTATION_
|
||||
// If this file is included from the user's code, just say no.
|
||||
# error "gtest-internal-inl.h is part of Google Test's internal implementation."
|
||||
# error "It must not be included except by Google Test itself."
|
||||
#endif // GTEST_IMPLEMENTATION_
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
# include <errno.h>
|
||||
#endif // !_WIN32_WCE
|
||||
@ -67,7 +59,7 @@
|
||||
# include <windows.h> // NOLINT
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
#include "gtest/gtest.h" // NOLINT
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
|
||||
namespace testing {
|
||||
@ -94,6 +86,7 @@ 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";
|
||||
@ -174,6 +167,7 @@ class GTestFlagSaver {
|
||||
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);
|
||||
@ -195,6 +189,7 @@ class GTestFlagSaver {
|
||||
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_;
|
||||
@ -216,6 +211,7 @@ class GTestFlagSaver {
|
||||
bool list_tests_;
|
||||
std::string output_;
|
||||
bool print_time_;
|
||||
bool print_utf8_;
|
||||
internal::Int32 random_seed_;
|
||||
internal::Int32 repeat_;
|
||||
bool shuffle_;
|
||||
@ -1028,7 +1024,7 @@ class TestResultAccessor {
|
||||
#if GTEST_CAN_STREAM_RESULTS_
|
||||
|
||||
// Streams test results to the given port on the given host machine.
|
||||
class GTEST_API_ StreamingListener : public EmptyTestEventListener {
|
||||
class StreamingListener : public EmptyTestEventListener {
|
||||
public:
|
||||
// Abstract base class for writing strings to a socket.
|
||||
class AbstractSocketWriter {
|
||||
|
@ -67,15 +67,7 @@
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick exists to
|
||||
// prevent the accidental inclusion of gtest-internal-inl.h in the
|
||||
// user's code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
@ -671,7 +663,7 @@ bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
|
||||
}
|
||||
|
||||
// Helper function used by ValidateRegex() to format error messages.
|
||||
std::string FormatRegexSyntaxError(const char* regex, int index) {
|
||||
static std::string FormatRegexSyntaxError(const char* regex, int index) {
|
||||
return (Message() << "Syntax error at index " << index
|
||||
<< " in simple regular expression \"" << regex << "\": ").GetString();
|
||||
}
|
||||
@ -923,6 +915,7 @@ GTestLog::~GTestLog() {
|
||||
posix::Abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Disable Microsoft deprecation warnings for POSIX functions called from
|
||||
// this class (creat, dup, dup2, and close)
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
|
||||
@ -1015,7 +1008,8 @@ static CapturedStream* g_captured_stderr = NULL;
|
||||
static CapturedStream* g_captured_stdout = NULL;
|
||||
|
||||
// Starts capturing an output stream (stdout/stderr).
|
||||
void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
|
||||
static void CaptureStream(int fd, const char* stream_name,
|
||||
CapturedStream** stream) {
|
||||
if (*stream != NULL) {
|
||||
GTEST_LOG_(FATAL) << "Only one " << stream_name
|
||||
<< " capturer can exist at a time.";
|
||||
@ -1024,7 +1018,7 @@ void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
|
||||
}
|
||||
|
||||
// Stops capturing the output stream and returns the captured string.
|
||||
std::string GetCapturedStream(CapturedStream** captured_stream) {
|
||||
static std::string GetCapturedStream(CapturedStream** captured_stream) {
|
||||
const std::string content = (*captured_stream)->GetCapturedString();
|
||||
|
||||
delete *captured_stream;
|
||||
@ -1055,6 +1049,10 @@ std::string GetCapturedStderr() {
|
||||
|
||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
size_t GetFileSize(FILE* file) {
|
||||
fseek(file, 0, SEEK_END);
|
||||
return static_cast<size_t>(ftell(file));
|
||||
|
@ -43,12 +43,13 @@
|
||||
// defines Foo.
|
||||
|
||||
#include "gtest/gtest-printers.h"
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <cctype>
|
||||
#include <cwchar>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "src/gtest-internal-inl.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
@ -123,7 +124,7 @@ 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 hexidecimal escape sequence (e.g. '\x7F'), or
|
||||
// - as a hexadecimal escape sequence (e.g. '\x7F'), or
|
||||
// - as a special escape sequence (e.g. '\r', '\n').
|
||||
enum CharFormat {
|
||||
kAsIs,
|
||||
@ -230,7 +231,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
|
||||
return;
|
||||
*os << " (" << static_cast<int>(c);
|
||||
|
||||
// For more convenience, we print c's code again in hexidecimal,
|
||||
// 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)) {
|
||||
@ -262,11 +263,12 @@ template <typename CharType>
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
||||
static void PrintCharsAsStringTo(
|
||||
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)) {
|
||||
@ -276,8 +278,13 @@ static void PrintCharsAsStringTo(
|
||||
*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
|
||||
@ -347,15 +354,90 @@ void PrintTo(const wchar_t* s, ostream* os) {
|
||||
}
|
||||
#endif // wchar_t is native
|
||||
|
||||
namespace {
|
||||
|
||||
bool ContainsUnprintableControlCodes(const char* str, size_t length) {
|
||||
const unsigned char *s = reinterpret_cast<const unsigned char *>(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<const unsigned char *>(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
|
||||
|
||||
// Prints a ::string object.
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
void PrintStringTo(const ::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
||||
if (GTEST_FLAG(print_utf8)) {
|
||||
ConditionalPrintAsText(s.data(), s.size(), os);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
||||
if (GTEST_FLAG(print_utf8)) {
|
||||
ConditionalPrintAsText(s.data(), s.size(), os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prints a ::wstring object.
|
||||
|
@ -32,15 +32,7 @@
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
|
||||
#include "gtest/gtest-test-part.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick exists to
|
||||
// prevent the accidental inclusion of gtest-internal-inl.h in the
|
||||
// user's code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
namespace testing {
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include "gtest/gtest-typed-test.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
@ -133,14 +133,7 @@
|
||||
# include <sys/types.h> // NOLINT
|
||||
#endif
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// their code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
# define vsnprintf _vsnprintf
|
||||
@ -167,8 +160,10 @@ static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
|
||||
// A test filter that matches everything.
|
||||
static const char kUniversalFilter[] = "*";
|
||||
|
||||
// The default output file for XML output.
|
||||
static const char kDefaultOutputFile[] = "test_detail.xml";
|
||||
// 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";
|
||||
@ -238,9 +233,9 @@ GTEST_DEFINE_bool_(list_tests, false,
|
||||
GTEST_DEFINE_string_(
|
||||
output,
|
||||
internal::StringFromGTestEnv("output", ""),
|
||||
"A format (currently must be \"xml\"), optionally followed "
|
||||
"by a colon and an output file name or directory. A directory "
|
||||
"is indicated by a trailing pathname separator. "
|
||||
"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 "
|
||||
@ -253,6 +248,12 @@ GTEST_DEFINE_bool_(
|
||||
"True iff " GTEST_NAME_
|
||||
" should display elapsed time in text output.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
print_utf8,
|
||||
internal::BoolFromGTestEnv("print_utf8", true),
|
||||
"True iff " GTEST_NAME_
|
||||
" prints UTF8 characters as text.");
|
||||
|
||||
GTEST_DEFINE_int32_(
|
||||
random_seed,
|
||||
internal::Int32FromGTestEnv("random_seed", 0),
|
||||
@ -294,7 +295,7 @@ GTEST_DEFINE_bool_(
|
||||
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.");
|
||||
"otherwise. For use with an external test framework.");
|
||||
|
||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||
GTEST_DEFINE_string_(
|
||||
@ -429,12 +430,17 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
||||
if (gtest_output_flag == NULL)
|
||||
return "";
|
||||
|
||||
std::string format = GetOutputFormat();
|
||||
if (format.empty())
|
||||
format = std::string(kDefaultOutputFormat);
|
||||
|
||||
const char* const colon = strchr(gtest_output_flag, ':');
|
||||
if (colon == NULL)
|
||||
return internal::FilePath::ConcatPaths(
|
||||
return internal::FilePath::MakeFileName(
|
||||
internal::FilePath(
|
||||
UnitTest::GetInstance()->original_working_dir()),
|
||||
internal::FilePath(kDefaultOutputFile)).string();
|
||||
internal::FilePath(kDefaultOutputFile), 0,
|
||||
format.c_str()).string();
|
||||
|
||||
internal::FilePath output_name(colon + 1);
|
||||
if (!output_name.IsAbsolutePath())
|
||||
@ -629,12 +635,12 @@ 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.
|
||||
AssertionResult HasOneFailure(const char* /* results_expr */,
|
||||
const char* /* type_expr */,
|
||||
const char* /* substr_expr */,
|
||||
const TestPartResultArray& results,
|
||||
TestPartResult::Type type,
|
||||
const std::string& substr) {
|
||||
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");
|
||||
@ -1662,7 +1668,7 @@ namespace {
|
||||
AssertionResult HRESULTFailureHelper(const char* expr,
|
||||
const char* expected,
|
||||
long hr) { // NOLINT
|
||||
# if GTEST_OS_WINDOWS_MOBILE
|
||||
# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE
|
||||
|
||||
// Windows CE doesn't support FormatMessage.
|
||||
const char error_text[] = "";
|
||||
@ -1719,7 +1725,7 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT
|
||||
// Utility functions for encoding Unicode text (wide strings) in
|
||||
// UTF-8.
|
||||
|
||||
// A Unicode code-point can have upto 21 bits, and is encoded 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
|
||||
@ -2137,8 +2143,9 @@ static std::string FormatWordList(const std::vector<std::string>& words) {
|
||||
return word_list.GetString();
|
||||
}
|
||||
|
||||
bool ValidateTestPropertyName(const std::string& property_name,
|
||||
const std::vector<std::string>& reserved_names) {
|
||||
static bool ValidateTestPropertyName(
|
||||
const std::string& property_name,
|
||||
const std::vector<std::string>& 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
|
||||
@ -2435,6 +2442,8 @@ Result HandleExceptionsInMethodIfSupported(
|
||||
#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
|
||||
@ -2569,12 +2578,10 @@ void ReportInvalidTestCaseType(const char* test_case_name,
|
||||
<< "probably rename one of the classes to put the tests into different\n"
|
||||
<< "test cases.";
|
||||
|
||||
GTEST_LOG_(ERROR)
|
||||
<< FormatFileLocation(code_location.file.c_str(),
|
||||
code_location.line)
|
||||
<< " " << errors.GetString();
|
||||
GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(),
|
||||
code_location.line)
|
||||
<< " " << errors.GetString();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
namespace {
|
||||
@ -2883,7 +2890,7 @@ enum GTestColor {
|
||||
!GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW
|
||||
|
||||
// Returns the character attribute for the given color.
|
||||
WORD GetColorAttribute(GTestColor color) {
|
||||
static WORD GetColorAttribute(GTestColor color) {
|
||||
switch (color) {
|
||||
case COLOR_RED: return FOREGROUND_RED;
|
||||
case COLOR_GREEN: return FOREGROUND_GREEN;
|
||||
@ -2892,18 +2899,18 @@ WORD GetColorAttribute(GTestColor color) {
|
||||
}
|
||||
}
|
||||
|
||||
int GetBitOffset(WORD color_mask) {
|
||||
static int GetBitOffset(WORD color_mask) {
|
||||
if (color_mask == 0) return 0;
|
||||
|
||||
int bitOffset = 0;
|
||||
while((color_mask & 1) == 0) {
|
||||
while ((color_mask & 1) == 0) {
|
||||
color_mask >>= 1;
|
||||
++bitOffset;
|
||||
}
|
||||
return bitOffset;
|
||||
}
|
||||
|
||||
WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
|
||||
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;
|
||||
@ -2918,12 +2925,12 @@ WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
|
||||
}
|
||||
return new_color;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
// Returns the ANSI color code for the given color. COLOR_DEFAULT is
|
||||
// an invalid input.
|
||||
const char* GetAnsiColorCode(GTestColor color) {
|
||||
static const char* GetAnsiColorCode(GTestColor color) {
|
||||
switch (color) {
|
||||
case COLOR_RED: return "1";
|
||||
case COLOR_GREEN: return "2";
|
||||
@ -2976,7 +2983,7 @@ bool ShouldUseColor(bool stdout_is_tty) {
|
||||
// This routine must actually emit the characters rather than return a string
|
||||
// that would be colored when printed, as can be done on Linux.
|
||||
GTEST_ATTRIBUTE_PRINTF_(2, 3)
|
||||
void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
||||
static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
@ -3005,7 +3012,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
||||
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.
|
||||
@ -3030,7 +3037,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
||||
static const char kTypeParamLabel[] = "TypeParam";
|
||||
static const char kValueParamLabel[] = "GetParam()";
|
||||
|
||||
void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
|
||||
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();
|
||||
|
||||
@ -3104,7 +3111,6 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
|
||||
"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(),
|
||||
@ -3471,8 +3477,8 @@ void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
||||
// 3. To interpret the meaning of errno in a thread-safe way,
|
||||
// we need the strerror_r() function, which is not available on
|
||||
// Windows.
|
||||
GTEST_LOG_(FATAL) << "Unable to open file \""
|
||||
<< output_file_ << "\"";
|
||||
|
||||
GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file_ << "\"";
|
||||
}
|
||||
std::stringstream stream;
|
||||
PrintXmlUnitTest(&stream, unit_test);
|
||||
@ -3771,6 +3777,352 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
|
||||
|
||||
// End XmlUnitTestResultPrinter
|
||||
|
||||
|
||||
// This class generates an JSON output file.
|
||||
class JsonUnitTestResultPrinter : public EmptyTestEventListener {
|
||||
public:
|
||||
explicit JsonUnitTestResultPrinter(const char* output_file);
|
||||
|
||||
virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
|
||||
|
||||
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_case_name,
|
||||
const TestInfo& test_info);
|
||||
|
||||
// Prints a JSON representation of a TestCase object
|
||||
static void PrintJsonTestCase(::std::ostream* stream,
|
||||
const TestCase& test_case);
|
||||
|
||||
// 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 = NULL;
|
||||
FilePath output_file(output_file_);
|
||||
FilePath output_dir(output_file.RemoveFileName());
|
||||
|
||||
if (output_dir.CreateDirectoriesRecursively()) {
|
||||
jsonout = posix::FOpen(output_file_.c_str(), "w");
|
||||
}
|
||||
if (jsonout == NULL) {
|
||||
// TODO(phosek): report the reason of the failure.
|
||||
//
|
||||
// We don't do it for now as:
|
||||
//
|
||||
// 1. There is no urgent need for it.
|
||||
// 2. It's a bit involved to make the errno variable thread-safe on
|
||||
// all three operating systems (Linux, Windows, and Mac OS).
|
||||
// 3. To interpret the meaning of errno in a thread-safe way,
|
||||
// we need the strerror_r() function, which is not available on
|
||||
// Windows.
|
||||
GTEST_LOG_(FATAL) << "Unable to open file \""
|
||||
<< 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<unsigned char>(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<double>(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<time_t>(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(int 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<std::string>& allowed_names =
|
||||
GetReservedAttributesForElement(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<std::string>& allowed_names =
|
||||
GetReservedAttributesForElement(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_case_name,
|
||||
const TestInfo& test_info) {
|
||||
const TestResult& result = *test_info.result();
|
||||
const std::string kTestcase = "testcase";
|
||||
const std::string kIndent = Indent(10);
|
||||
|
||||
*stream << Indent(8) << "{\n";
|
||||
OutputJsonKey(stream, kTestcase, "name", test_info.name(), kIndent);
|
||||
|
||||
if (test_info.value_param() != NULL) {
|
||||
OutputJsonKey(stream, kTestcase, "value_param",
|
||||
test_info.value_param(), kIndent);
|
||||
}
|
||||
if (test_info.type_param() != NULL) {
|
||||
OutputJsonKey(stream, kTestcase, "type_param", test_info.type_param(),
|
||||
kIndent);
|
||||
}
|
||||
|
||||
OutputJsonKey(stream, kTestcase, "status",
|
||||
test_info.should_run() ? "RUN" : "NOTRUN", kIndent);
|
||||
OutputJsonKey(stream, kTestcase, "time",
|
||||
FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);
|
||||
OutputJsonKey(stream, kTestcase, "classname", test_case_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 TestCase object
|
||||
void JsonUnitTestResultPrinter::PrintJsonTestCase(std::ostream* stream,
|
||||
const TestCase& test_case) {
|
||||
const std::string kTestsuite = "testsuite";
|
||||
const std::string kIndent = Indent(6);
|
||||
|
||||
*stream << Indent(4) << "{\n";
|
||||
OutputJsonKey(stream, kTestsuite, "name", test_case.name(), kIndent);
|
||||
OutputJsonKey(stream, kTestsuite, "tests", test_case.reportable_test_count(),
|
||||
kIndent);
|
||||
OutputJsonKey(stream, kTestsuite, "failures", test_case.failed_test_count(),
|
||||
kIndent);
|
||||
OutputJsonKey(stream, kTestsuite, "disabled",
|
||||
test_case.reportable_disabled_test_count(), kIndent);
|
||||
OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent);
|
||||
OutputJsonKey(stream, kTestsuite, "time",
|
||||
FormatTimeInMillisAsDuration(test_case.elapsed_time()), kIndent,
|
||||
false);
|
||||
*stream << TestPropertiesAsJson(test_case.ad_hoc_test_result(), kIndent)
|
||||
<< ",\n";
|
||||
|
||||
*stream << kIndent << "\"" << kTestsuite << "\": [\n";
|
||||
|
||||
bool comma = false;
|
||||
for (int i = 0; i < test_case.total_test_count(); ++i) {
|
||||
if (test_case.GetTestInfo(i)->is_reportable()) {
|
||||
if (comma) {
|
||||
*stream << ",\n";
|
||||
} else {
|
||||
comma = true;
|
||||
}
|
||||
OutputJsonTestInfo(stream, test_case.name(), *test_case.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_case_count(); ++i) {
|
||||
if (unit_test.GetTestCase(i)->reportable_test_count() > 0) {
|
||||
if (comma) {
|
||||
*stream << ",\n";
|
||||
} else {
|
||||
comma = true;
|
||||
}
|
||||
PrintJsonTestCase(stream, *unit_test.GetTestCase(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,
|
||||
@ -3841,27 +4193,6 @@ void StreamingListener::SocketWriter::MakeConnection() {
|
||||
// End of class Streaming Listener
|
||||
#endif // GTEST_CAN_STREAM_RESULTS__
|
||||
|
||||
// Class ScopedTrace
|
||||
|
||||
// Pushes the given source file location and message onto a per-thread
|
||||
// trace stack maintained by Google Test.
|
||||
ScopedTrace::ScopedTrace(const char* file, int line, const Message& message)
|
||||
GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
|
||||
TraceInfo trace;
|
||||
trace.file = file;
|
||||
trace.line = line;
|
||||
trace.message = message.GetString();
|
||||
|
||||
UnitTest::GetInstance()->PushGTestTrace(trace);
|
||||
}
|
||||
|
||||
// Pops the info pushed by the c'tor.
|
||||
ScopedTrace::~ScopedTrace()
|
||||
GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
|
||||
UnitTest::GetInstance()->PopGTestTrace();
|
||||
}
|
||||
|
||||
|
||||
// class OsStackTraceGetter
|
||||
|
||||
const char* const OsStackTraceGetterInterface::kElidedFramesMarker =
|
||||
@ -4418,10 +4749,12 @@ void UnitTestImpl::ConfigureXmlOutput() {
|
||||
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.";
|
||||
GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
|
||||
<< output_format << "\" ignored.";
|
||||
}
|
||||
}
|
||||
|
||||
@ -4436,8 +4769,7 @@ void UnitTestImpl::ConfigureStreamingOutput() {
|
||||
listeners()->Append(new StreamingListener(target.substr(0, pos),
|
||||
target.substr(pos+1)));
|
||||
} else {
|
||||
GTEST_LOG_(WARNING) << "unrecognized streaming target \""
|
||||
<< target
|
||||
GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target
|
||||
<< "\" ignored.";
|
||||
}
|
||||
}
|
||||
@ -4567,7 +4899,7 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); }
|
||||
bool UnitTestImpl::RunAllTests() {
|
||||
// Makes sure InitGoogleTest() was called.
|
||||
if (!GTestIsInitialized()) {
|
||||
GTEST_LOG_(ERROR) <<
|
||||
GTEST_LOG_(ERROR) <<
|
||||
"\nThis test program did NOT call ::testing::InitGoogleTest "
|
||||
"before calling RUN_ALL_TESTS(). Please fix it.";
|
||||
return false;
|
||||
@ -4840,10 +5172,11 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
||||
(GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
|
||||
matches_filter;
|
||||
|
||||
const bool is_selected = is_runnable &&
|
||||
(shard_tests == IGNORE_SHARDING_PROTOCOL ||
|
||||
ShouldRunTestOnShard(total_shards, shard_index,
|
||||
num_runnable_tests));
|
||||
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;
|
||||
@ -5028,9 +5361,9 @@ bool SkipPrefix(const char* prefix, const char** pstr) {
|
||||
// part can be omitted.
|
||||
//
|
||||
// Returns the value of the flag, or NULL if the parsing failed.
|
||||
const char* ParseFlagValue(const char* str,
|
||||
const char* flag,
|
||||
bool def_optional) {
|
||||
static const char* ParseFlagValue(const char* str,
|
||||
const char* flag,
|
||||
bool def_optional) {
|
||||
// str and flag must not be NULL.
|
||||
if (str == NULL || flag == NULL) return NULL;
|
||||
|
||||
@ -5066,7 +5399,7 @@ const char* ParseFlagValue(const char* str,
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
bool ParseBoolFlag(const char* str, const char* flag, bool* 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);
|
||||
|
||||
@ -5100,7 +5433,9 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value) {
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
bool ParseStringFlag(const char* str, const char* flag, std::string* value) {
|
||||
static bool ParseStringFlag(const char* str,
|
||||
const char* flag,
|
||||
std::string* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseFlagValue(str, flag, false);
|
||||
|
||||
@ -5202,10 +5537,10 @@ static const char kColorEncodedHelpMessage[] =
|
||||
" 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=xml@Y[@G:@YDIRECTORY_PATH@G"
|
||||
" @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G"
|
||||
GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
|
||||
" Generate an XML report in the given directory or with the given file\n"
|
||||
" name. @YFILE_PATH@D defaults to @Gtest_detail.xml@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_details.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"
|
||||
@ -5219,7 +5554,8 @@ static const char kColorEncodedHelpMessage[] =
|
||||
" @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.\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"
|
||||
@ -5236,7 +5572,7 @@ static const char kColorEncodedHelpMessage[] =
|
||||
"(not one in your own code or tests), please report it to\n"
|
||||
"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
|
||||
|
||||
bool ParseGoogleTestFlag(const char* const arg) {
|
||||
static bool ParseGoogleTestFlag(const char* const arg) {
|
||||
return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
|
||||
>EST_FLAG(also_run_disabled_tests)) ||
|
||||
ParseBoolFlag(arg, kBreakOnFailureFlag,
|
||||
@ -5254,6 +5590,7 @@ bool ParseGoogleTestFlag(const char* const arg) {
|
||||
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)) ||
|
||||
@ -5266,11 +5603,10 @@ bool ParseGoogleTestFlag(const char* const arg) {
|
||||
}
|
||||
|
||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||
void LoadFlagsFromFile(const std::string& path) {
|
||||
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)
|
||||
GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile)
|
||||
<< "\"";
|
||||
}
|
||||
std::string contents(ReadEntireFile(flagfile));
|
||||
@ -5401,8 +5737,9 @@ void InitGoogleTest(int* argc, wchar_t** argv) {
|
||||
|
||||
std::string TempDir() {
|
||||
#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
|
||||
return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
|
||||
return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
|
||||
#endif
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
return "\\temp\\";
|
||||
#elif GTEST_OS_WINDOWS
|
||||
@ -5420,4 +5757,23 @@ std::string TempDir() {
|
||||
#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
|
||||
|
@ -26,9 +26,9 @@
|
||||
// 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 <stdio.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
GTEST_API_ int main(int argc, char **argv) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2017 Google Inc.
|
||||
# Copyright 2017 Google Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
#
|
||||
@ -57,13 +57,15 @@ cc_test(
|
||||
"gtest-param-test_test.cc",
|
||||
],
|
||||
) + select({
|
||||
"//:win": [],
|
||||
"//:windows": [],
|
||||
"//:windows_msvc": [],
|
||||
"//conditions:default": [
|
||||
"gtest-tuple_test.cc",
|
||||
],
|
||||
}),
|
||||
copts = select({
|
||||
"//:win": ["-DGTEST_USE_OWN_TR1_TUPLE=0"],
|
||||
"//:windows": ["-DGTEST_USE_OWN_TR1_TUPLE=0"],
|
||||
"//:windows_msvc": ["-DGTEST_USE_OWN_TR1_TUPLE=0"],
|
||||
"//conditions:default": ["-DGTEST_USE_OWN_TR1_TUPLE=1"],
|
||||
}),
|
||||
includes = [
|
||||
@ -73,7 +75,8 @@ cc_test(
|
||||
"googletest/test",
|
||||
],
|
||||
linkopts = select({
|
||||
"//:win": [],
|
||||
"//:windows": [],
|
||||
"//:windows_msvc": [],
|
||||
"//conditions:default": [
|
||||
"-pthread",
|
||||
],
|
||||
@ -116,3 +119,262 @@ cc_test(
|
||||
"//: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 = "gtest_output_test_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_output_test_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gtest_output_test",
|
||||
size = "small",
|
||||
srcs = ["gtest_output_test.py"],
|
||||
data = [
|
||||
"gtest_output_test_golden_lin.txt",
|
||||
":gtest_output_test_",
|
||||
],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gtest_color_test_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_color_test_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
py_test(
|
||||
name = "gtest_color_test",
|
||||
size = "small",
|
||||
srcs = ["gtest_color_test.py"],
|
||||
data = [":gtest_color_test_"],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gtest_env_var_test_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_env_var_test_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gtest_env_var_test",
|
||||
size = "small",
|
||||
srcs = ["gtest_env_var_test.py"],
|
||||
data = [":gtest_env_var_test_"],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gtest_filter_unittest_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_filter_unittest_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gtest_filter_unittest",
|
||||
size = "small",
|
||||
srcs = ["gtest_filter_unittest.py"],
|
||||
data = [":gtest_filter_unittest_"],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gtest_break_on_failure_unittest_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_break_on_failure_unittest_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gtest_break_on_failure_unittest",
|
||||
size = "small",
|
||||
srcs = ["gtest_break_on_failure_unittest.py"],
|
||||
data = [":gtest_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 = "gtest_throw_on_failure_test_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_throw_on_failure_test_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gtest_throw_on_failure_test",
|
||||
size = "small",
|
||||
srcs = ["gtest_throw_on_failure_test.py"],
|
||||
data = [":gtest_throw_on_failure_test_"],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gtest_list_tests_unittest_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_list_tests_unittest_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gtest_list_tests_unittest",
|
||||
size = "small",
|
||||
srcs = ["gtest_list_tests_unittest.py"],
|
||||
data = [":gtest_list_tests_unittest_"],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gtest_shuffle_test_",
|
||||
srcs = ["gtest_shuffle_test_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gtest_shuffle_test",
|
||||
size = "small",
|
||||
srcs = ["gtest_shuffle_test.py"],
|
||||
data = [":gtest_shuffle_test_"],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gtest_catch_exceptions_no_ex_test_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_catch_exceptions_test_.cc"],
|
||||
deps = ["//:gtest_main"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gtest_catch_exceptions_ex_test_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_catch_exceptions_test_.cc"],
|
||||
copts = ["-fexceptions"],
|
||||
deps = ["//:gtest_main"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gtest_catch_exceptions_test",
|
||||
size = "small",
|
||||
srcs = ["gtest_catch_exceptions_test.py"],
|
||||
data = [
|
||||
":gtest_catch_exceptions_ex_test_",
|
||||
":gtest_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",
|
||||
],
|
||||
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 = "gtest_uninitialized_test_",
|
||||
testonly = 1,
|
||||
srcs = ["gtest_uninitialized_test_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gtest_uninitialized_test",
|
||||
size = "medium",
|
||||
srcs = ["gtest_uninitialized_test.py"],
|
||||
data = [":gtest_uninitialized_test_"],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
@ -56,15 +56,7 @@ using testing::internal::AlwaysTrue;
|
||||
# endif // GTEST_OS_LINUX
|
||||
|
||||
# include "gtest/gtest-spi.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// their code.
|
||||
# define GTEST_IMPLEMENTATION_ 1
|
||||
# include "src/gtest-internal-inl.h"
|
||||
# undef GTEST_IMPLEMENTATION_
|
||||
|
||||
namespace posix = ::testing::internal::posix;
|
||||
|
||||
@ -313,14 +305,14 @@ void DieWithEmbeddedNul() {
|
||||
}
|
||||
|
||||
# if GTEST_USES_PCRE
|
||||
|
||||
// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error
|
||||
// message has a NUL character in it.
|
||||
TEST_F(TestForDeathTest, EmbeddedNulInMessage) {
|
||||
// TODO(wan@google.com): <regex.h> doesn't support matching strings
|
||||
// with embedded NUL characters - find a way to workaround it.
|
||||
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
|
||||
@ -625,7 +617,11 @@ TEST_F(TestForDeathTest, ReturnIsFailure) {
|
||||
TEST_F(TestForDeathTest, TestExpectDebugDeath) {
|
||||
int sideeffect = 0;
|
||||
|
||||
EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12")
|
||||
// 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
|
||||
|
@ -27,28 +27,18 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: keith.ray@gmail.com (Keith Ray)
|
||||
//
|
||||
// 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_unittest.cc, to avoid changing
|
||||
// build or make-files for some existing Google Test clients. Do not
|
||||
// #include this file anywhere else!
|
||||
// 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"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// their code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
# include <windows.h> // NOLINT
|
||||
|
@ -27,7 +27,6 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: keith.ray@gmail.com (Keith Ray)
|
||||
//
|
||||
// Google Test UnitTestOptions tests
|
||||
//
|
||||
@ -46,14 +45,7 @@
|
||||
# include <direct.h>
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// their code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
@ -33,8 +33,7 @@
|
||||
// Google Test work.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "test/gtest-param-test_test.h"
|
||||
#include "gtest-param-test_test.h"
|
||||
|
||||
using ::testing::Values;
|
||||
using ::testing::internal::ParamGenerator;
|
||||
@ -59,3 +58,4 @@ INSTANTIATE_TEST_CASE_P(MultiplesOf33,
|
||||
INSTANTIATE_TEST_CASE_P(Sequence2,
|
||||
InstantiationInMultipleTranslaionUnitsTest,
|
||||
Values(42*3, 42*4, 42*5));
|
||||
|
||||
|
@ -42,11 +42,7 @@
|
||||
# include <string>
|
||||
# include <vector>
|
||||
|
||||
// To include gtest-internal-inl.h.
|
||||
# define GTEST_IMPLEMENTATION_ 1
|
||||
# include "src/gtest-internal-inl.h" // for UnitTestOptions
|
||||
# undef GTEST_IMPLEMENTATION_
|
||||
|
||||
# include "test/gtest-param-test_test.h"
|
||||
|
||||
using ::std::vector;
|
||||
@ -540,6 +536,51 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) {
|
||||
VerifyGenerator(gen, expected_values);
|
||||
}
|
||||
|
||||
#if GTEST_LANG_CXX11
|
||||
|
||||
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<tuple<int, NonDefaultConstructAssignString> > gen =
|
||||
Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"),
|
||||
NonDefaultConstructAssignString("B")));
|
||||
|
||||
ParamGenerator<tuple<int, NonDefaultConstructAssignString> >::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());
|
||||
}
|
||||
|
||||
#endif // GTEST_LANG_CXX11
|
||||
# endif // GTEST_HAS_COMBINE
|
||||
|
||||
// Tests that an generator produces correct sequence after being
|
||||
@ -815,8 +856,8 @@ class CustomFunctorNamingTest : public TestWithParam<std::string> {};
|
||||
TEST_P(CustomFunctorNamingTest, CustomTestNames) {}
|
||||
|
||||
struct CustomParamNameFunctor {
|
||||
std::string operator()(const ::testing::TestParamInfo<std::string>& info) {
|
||||
return info.param;
|
||||
std::string operator()(const ::testing::TestParamInfo<std::string>& inf) {
|
||||
return inf.param;
|
||||
}
|
||||
};
|
||||
|
||||
@ -833,8 +874,8 @@ INSTANTIATE_TEST_CASE_P(AllAllowedCharacters,
|
||||
CustomParamNameFunctor());
|
||||
|
||||
inline std::string CustomParamNameFunction(
|
||||
const ::testing::TestParamInfo<std::string>& info) {
|
||||
return info.param;
|
||||
const ::testing::TestParamInfo<std::string>& inf) {
|
||||
return inf.param;
|
||||
}
|
||||
|
||||
class CustomFunctionNamingTest : public TestWithParam<std::string> {};
|
||||
@ -852,11 +893,10 @@ INSTANTIATE_TEST_CASE_P(CustomParamNameFunction,
|
||||
class CustomLambdaNamingTest : public TestWithParam<std::string> {};
|
||||
TEST_P(CustomLambdaNamingTest, CustomTestNames) {}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(CustomParamNameLambda,
|
||||
CustomLambdaNamingTest,
|
||||
INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest,
|
||||
Values(std::string("LambdaName")),
|
||||
[](const ::testing::TestParamInfo<std::string>& tpinfo) {
|
||||
return tpinfo.param;
|
||||
[](const ::testing::TestParamInfo<std::string>& inf) {
|
||||
return inf.param;
|
||||
});
|
||||
|
||||
#endif // GTEST_LANG_CXX11
|
||||
@ -1023,6 +1063,7 @@ TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5));
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Used in TestGenerationTest test case.
|
||||
AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
|
||||
|
@ -45,15 +45,7 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// their code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
using std::make_pair;
|
||||
using std::pair;
|
||||
@ -75,8 +67,8 @@ TEST(IsXDigitTest, WorksForNarrowAscii) {
|
||||
}
|
||||
|
||||
TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) {
|
||||
EXPECT_FALSE(IsXDigit('\x80'));
|
||||
EXPECT_FALSE(IsXDigit(static_cast<char>('0' | '\x80')));
|
||||
EXPECT_FALSE(IsXDigit(static_cast<char>(0x80)));
|
||||
EXPECT_FALSE(IsXDigit(static_cast<char>('0' | 0x80)));
|
||||
}
|
||||
|
||||
TEST(IsXDigitTest, WorksForWideAscii) {
|
||||
|
@ -52,13 +52,13 @@
|
||||
|
||||
// hash_map and hash_set are available under Visual C++, or on Linux.
|
||||
#if GTEST_HAS_UNORDERED_MAP_
|
||||
# include <unordered_map> // NOLINT
|
||||
# include <unordered_map> // NOLINT
|
||||
#elif GTEST_HAS_HASH_MAP_
|
||||
# include <hash_map> // NOLINT
|
||||
#endif // GTEST_HAS_HASH_MAP_
|
||||
|
||||
#if GTEST_HAS_UNORDERED_SET_
|
||||
# include <unordered_set> // NOLINT
|
||||
# include <unordered_set> // NOLINT
|
||||
#elif GTEST_HAS_HASH_SET_
|
||||
# include <hash_set> // NOLINT
|
||||
#endif // GTEST_HAS_HASH_SET_
|
||||
@ -192,13 +192,12 @@ inline ::std::ostream& operator<<(::std::ostream& os,
|
||||
return os << "StreamableTemplateInFoo: " << x.value();
|
||||
}
|
||||
|
||||
// A user-defined streamable but recursivly-defined container type in
|
||||
// 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
|
||||
{
|
||||
struct iterator {
|
||||
typedef PathLike value_type;
|
||||
};
|
||||
typedef iterator const_iterator;
|
||||
@ -208,9 +207,7 @@ class PathLike {
|
||||
iterator begin() const { return iterator(); }
|
||||
iterator end() const { return iterator(); }
|
||||
|
||||
friend
|
||||
::std::ostream& operator<<(::std::ostream& os, const PathLike&)
|
||||
{
|
||||
friend ::std::ostream& operator<<(::std::ostream& os, const PathLike&) {
|
||||
return os << "Streamable-PathLike";
|
||||
}
|
||||
};
|
||||
@ -250,9 +247,9 @@ using ::testing::internal::string;
|
||||
#if GTEST_HAS_UNORDERED_MAP_
|
||||
|
||||
#define GTEST_HAS_HASH_MAP_ 1
|
||||
template<class Key, class T>
|
||||
template <class Key, class T>
|
||||
using hash_map = ::std::unordered_map<Key, T>;
|
||||
template<class Key, class T>
|
||||
template <class Key, class T>
|
||||
using hash_multimap = ::std::unordered_multimap<Key, T>;
|
||||
|
||||
#elif GTEST_HAS_HASH_MAP_
|
||||
@ -270,19 +267,19 @@ using ::stdext::hash_multimap;
|
||||
#if GTEST_HAS_UNORDERED_SET_
|
||||
|
||||
#define GTEST_HAS_HASH_SET_ 1
|
||||
template<class Key>
|
||||
template <class Key>
|
||||
using hash_set = ::std::unordered_set<Key>;
|
||||
template<class Key>
|
||||
template <class Key>
|
||||
using hash_multiset = ::std::unordered_multiset<Key>;
|
||||
|
||||
#elif GTEST_HAS_HASH_SET_
|
||||
|
||||
#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
|
||||
using ::std::hash_set;
|
||||
using ::std::hash_multiset;
|
||||
using ::std::hash_map;
|
||||
using ::std::hash_multimap;
|
||||
#elif _MSC_VER
|
||||
using ::stdext::hash_set;
|
||||
using ::stdext::hash_multiset;
|
||||
using ::stdext::hash_map;
|
||||
using ::stdext::hash_multimap;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -840,22 +837,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) {
|
||||
EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STRING_PIECE_
|
||||
#if GTEST_HAS_ABSL
|
||||
|
||||
// Tests printing StringPiece.
|
||||
// Tests printing ::absl::string_view.
|
||||
|
||||
TEST(PrintStringPieceTest, SimpleStringPiece) {
|
||||
const StringPiece sp = "Hello";
|
||||
TEST(PrintStringViewTest, SimpleStringView) {
|
||||
const ::absl::string_view sp = "Hello";
|
||||
EXPECT_EQ("\"Hello\"", Print(sp));
|
||||
}
|
||||
|
||||
TEST(PrintStringPieceTest, UnprintableCharacters) {
|
||||
TEST(PrintStringViewTest, UnprintableCharacters) {
|
||||
const char str[] = "NUL (\0) and \r\t";
|
||||
const StringPiece sp(str, sizeof(str) - 1);
|
||||
const ::absl::string_view sp(str, sizeof(str) - 1);
|
||||
EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp));
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_STRING_PIECE_
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
// Tests printing STL containers.
|
||||
|
||||
@ -1092,7 +1089,7 @@ TEST(PrintTr1TupleTest, VariousSizes) {
|
||||
::std::tr1::tuple<bool, char, short, testing::internal::Int32, // NOLINT
|
||||
testing::internal::Int64, float, double, const char*, void*,
|
||||
std::string>
|
||||
t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str,
|
||||
t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, // NOLINT
|
||||
ImplicitCast_<void*>(NULL), "10");
|
||||
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
|
||||
" pointing to \"8\", NULL, \"10\")",
|
||||
@ -1152,7 +1149,7 @@ TEST(PrintStdTupleTest, VariousSizes) {
|
||||
::std::tuple<bool, char, short, testing::internal::Int32, // NOLINT
|
||||
testing::internal::Int64, float, double, const char*, void*,
|
||||
std::string>
|
||||
t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str,
|
||||
t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, // NOLINT
|
||||
ImplicitCast_<void*>(NULL), "10");
|
||||
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
|
||||
" pointing to \"8\", NULL, \"10\")",
|
||||
@ -1330,7 +1327,7 @@ TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) {
|
||||
}
|
||||
|
||||
// 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 comparision is by
|
||||
// In this case we want to print it as a raw pointer, as the comparison is by
|
||||
// pointer.
|
||||
|
||||
// char pointer vs pointer
|
||||
@ -1555,6 +1552,78 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) {
|
||||
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) {
|
||||
@ -1696,5 +1765,17 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
|
||||
|
||||
#endif // GTEST_HAS_STD_TUPLE_
|
||||
|
||||
#if GTEST_HAS_ABSL
|
||||
|
||||
TEST(PrintOptionalTest, Basic) {
|
||||
absl::optional<int> value;
|
||||
EXPECT_EQ("(nullopt)", PrintToString(value));
|
||||
value = {7};
|
||||
EXPECT_EQ("(7)", PrintToString(value));
|
||||
EXPECT_EQ("(1.1)", PrintToString(absl::optional<double>{1.1}));
|
||||
EXPECT_EQ("(\"A\")", PrintToString(absl::optional<std::string>{"A"}));
|
||||
}
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
} // namespace gtest_printers_test
|
||||
} // namespace testing
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "test/gtest-typed-test_test.h"
|
||||
#include "gtest-typed-test_test.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST_P
|
||||
|
@ -29,7 +29,7 @@
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include "test/gtest-typed-test_test.h"
|
||||
#include "gtest-typed-test_test.h"
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
@ -33,15 +33,15 @@
|
||||
//
|
||||
// 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/gtest-filepath_test.cc"
|
||||
#include "test/gtest-linked_ptr_test.cc"
|
||||
#include "test/gtest-message_test.cc"
|
||||
#include "test/gtest-options_test.cc"
|
||||
#include "test/gtest-port_test.cc"
|
||||
#include "test/gtest_pred_impl_unittest.cc"
|
||||
#include "test/gtest_prod_test.cc"
|
||||
#include "test/gtest-test-part_test.cc"
|
||||
#include "test/gtest-typed-test_test.cc"
|
||||
#include "test/gtest-typed-test2_test.cc"
|
||||
#include "test/gtest_unittest.cc"
|
||||
#include "test/production.cc"
|
||||
#include "gtest-filepath_test.cc"
|
||||
#include "gtest-linked_ptr_test.cc"
|
||||
#include "gtest-message_test.cc"
|
||||
#include "gtest-options_test.cc"
|
||||
#include "gtest-port_test.cc"
|
||||
#include "gtest_pred_impl_unittest.cc"
|
||||
#include "gtest_prod_test.cc"
|
||||
#include "gtest-test-part_test.cc"
|
||||
#include "gtest-typed-test_test.cc"
|
||||
#include "gtest-typed-test2_test.cc"
|
||||
#include "gtest_unittest.cc"
|
||||
#include "production.cc"
|
||||
|
119
googletest/test/gtest_assert_by_exception_test.cc
Normal file
119
googletest/test/gtest_assert_by_exception_test.cc
Normal file
@ -0,0 +1,119 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Tests Google Test's assert-by-exception mode with exceptions enabled.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdexcept>
|
||||
|
||||
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") != NULL)
|
||||
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) {
|
||||
// FIXME(sokolov): how to force Test2 to be after Test?
|
||||
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;
|
||||
}
|
@ -40,10 +40,8 @@ Google Test) with different environments and command line flags.
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import gtest_test_utils
|
||||
import os
|
||||
import sys
|
||||
|
||||
import gtest_test_utils
|
||||
|
||||
# Constants.
|
||||
|
||||
|
@ -80,8 +80,7 @@ int main(int argc, char **argv) {
|
||||
SetUnhandledExceptionFilter(ExitWithExceptionCode);
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
|
@ -37,8 +37,6 @@ Google Test) and verifies their output.
|
||||
|
||||
__author__ = 'vladl@google.com (Vlad Losev)'
|
||||
|
||||
import os
|
||||
|
||||
import gtest_test_utils
|
||||
|
||||
# Constants.
|
||||
|
@ -36,8 +36,7 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
import os
|
||||
import gtest_test_utils
|
||||
|
||||
|
||||
IS_WINDOWS = os.name = 'nt'
|
||||
IS_WINDOWS = os.name == 'nt'
|
||||
|
||||
COLOR_ENV_VAR = 'GTEST_COLOR'
|
||||
COLOR_FLAG = 'gtest_color'
|
||||
|
@ -36,15 +36,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// their code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
using testing::internal::ShouldUseColor;
|
||||
|
||||
|
@ -47,8 +47,8 @@ environ = os.environ.copy()
|
||||
|
||||
def AssertEq(expected, actual):
|
||||
if expected != actual:
|
||||
print('Expected: %s' % (expected,))
|
||||
print(' Actual: %s' % (actual,))
|
||||
print 'Expected: %s' % (expected,)
|
||||
print ' Actual: %s' % (actual,)
|
||||
raise AssertionError
|
||||
|
||||
|
||||
|
@ -36,9 +36,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
using ::std::cout;
|
||||
|
||||
|
@ -34,10 +34,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define GTEST_IMPLEMENTATION_ 1 // Required for the next #include.
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
namespace testing {
|
||||
GTEST_DECLARE_string_(filter);
|
||||
|
@ -44,12 +44,8 @@ __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 sets
|
||||
import sys
|
||||
|
||||
import gtest_test_utils
|
||||
|
||||
# Constants.
|
||||
@ -59,10 +55,12 @@ import gtest_test_utils
|
||||
# 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'.
|
||||
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)
|
||||
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.
|
||||
@ -71,11 +69,14 @@ CAN_PASS_EMPTY_ENV = eval(child.output)
|
||||
# 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'.
|
||||
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)
|
||||
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
|
||||
@ -97,7 +98,7 @@ SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE'
|
||||
FILTER_FLAG = 'gtest_filter'
|
||||
|
||||
# The command line flag for including disabled tests.
|
||||
ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests'
|
||||
ALSO_RUN_DISABLED_TESTS_FLAG = 'gtest_also_run_disabled_tests'
|
||||
|
||||
# Command to run the gtest_filter_unittest_ program.
|
||||
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_')
|
||||
@ -246,14 +247,14 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
|
||||
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))
|
||||
self.assertEqual(sets.Set(set_var), sets.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))
|
||||
return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS))
|
||||
else:
|
||||
return tests_to_run
|
||||
|
||||
@ -294,6 +295,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
|
||||
Runs all shards of gtest_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.
|
||||
@ -339,7 +341,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
|
||||
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
|
||||
|
||||
# Construct the command line.
|
||||
args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG]
|
||||
args = ['--%s' % ALSO_RUN_DISABLED_TESTS_FLAG]
|
||||
if gtest_filter is not None:
|
||||
args.append('--%s=%s' % (FILTER_FLAG, gtest_filter))
|
||||
|
||||
|
163
googletest/test/gtest_json_outfiles_test.py
Normal file
163
googletest/test/gtest_json_outfiles_test.py
Normal file
@ -0,0 +1,163 @@
|
||||
#!/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_test_utils
|
||||
import gtest_json_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'testsuite': [{
|
||||
u'name': u'TestSomeProperties',
|
||||
u'status': u'RUN',
|
||||
u'time': 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'testsuite': [{
|
||||
u'name': u'TestSomeProperties',
|
||||
u'status': u'RUN',
|
||||
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)
|
||||
|
||||
# TODO(wan@google.com): libtool causes the built test binary to be
|
||||
# named lt-gtest_xml_outfiles_test_ instead of
|
||||
# gtest_xml_outfiles_test_. To account for this possibility, we
|
||||
# allow both names in the following code. We should remove this
|
||||
# hack when Chandler Carruth's libtool replacement tool is ready.
|
||||
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()
|
612
googletest/test/gtest_json_output_unittest.py
Normal file
612
googletest/test/gtest_json_output_unittest.py
Normal file
@ -0,0 +1,612 @@
|
||||
#!/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_test_utils
|
||||
import gtest_json_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_'
|
||||
|
||||
SUPPORTS_STACK_TRACES = False
|
||||
|
||||
if SUPPORTS_STACK_TRACES:
|
||||
STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
|
||||
else:
|
||||
STACK_TRACE_TEMPLATE = ''
|
||||
|
||||
EXPECTED_NON_EMPTY = {
|
||||
u'tests': 23,
|
||||
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'testsuite': [
|
||||
{
|
||||
u'name': u'Succeeds',
|
||||
u'status': u'RUN',
|
||||
u'time': 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'testsuite': [
|
||||
{
|
||||
u'name': u'Fails',
|
||||
u'status': u'RUN',
|
||||
u'time': 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'testsuite': [
|
||||
{
|
||||
u'name': u'DISABLED_test_not_run',
|
||||
u'status': u'NOTRUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'DisabledTest'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
u'name': u'MixedResultTest',
|
||||
u'tests': 3,
|
||||
u'failures': 1,
|
||||
u'disabled': 1,
|
||||
u'errors': 0,
|
||||
u'time': u'*',
|
||||
u'testsuite': [
|
||||
{
|
||||
u'name': u'Succeeds',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'MixedResultTest'
|
||||
},
|
||||
{
|
||||
u'name': u'Fails',
|
||||
u'status': u'RUN',
|
||||
u'time': 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'time': 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'testsuite': [
|
||||
{
|
||||
u'name': u'OutputsCData',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'XmlQuotingTest',
|
||||
u'failures': [
|
||||
{
|
||||
u'failure':
|
||||
u'gtest_xml_output_unittest_.cc:*\n'
|
||||
u'Failed\nXML output: <?xml encoding="utf-8">'
|
||||
u'<top><![CDATA[cdata text]]></top>' +
|
||||
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'testsuite': [
|
||||
{
|
||||
u'name': u'InvalidCharactersInMessage',
|
||||
u'status': u'RUN',
|
||||
u'time': 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'SetUpTestCase': u'yes',
|
||||
u'TearDownTestCase': u'aye',
|
||||
u'testsuite': [
|
||||
{
|
||||
u'name': u'OneProperty',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'PropertyRecordingTest',
|
||||
u'key_1': u'1'
|
||||
},
|
||||
{
|
||||
u'name': u'IntValuedProperty',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'PropertyRecordingTest',
|
||||
u'key_int': u'1'
|
||||
},
|
||||
{
|
||||
u'name': u'ThreeProperties',
|
||||
u'status': u'RUN',
|
||||
u'time': 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'time': 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'testsuite': [
|
||||
{
|
||||
u'name': u'RecordProperty',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'NoFixtureTest',
|
||||
u'key': u'1'
|
||||
},
|
||||
{
|
||||
u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'NoFixtureTest',
|
||||
u'key_for_utility_int': u'1'
|
||||
},
|
||||
{
|
||||
u'name':
|
||||
u'ExternalUtilityThatCallsRecordStringValuedProperty',
|
||||
u'status': u'RUN',
|
||||
u'time': 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'testsuite': [
|
||||
{
|
||||
u'name': u'HasTypeParamAttribute',
|
||||
u'type_param': u'int',
|
||||
u'status': u'RUN',
|
||||
u'time': 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'testsuite': [
|
||||
{
|
||||
u'name': u'HasTypeParamAttribute',
|
||||
u'type_param': u'long',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'TypedTest/1'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
u'name': u'Single/TypeParameterizedTestCase/0',
|
||||
u'tests': 1,
|
||||
u'failures': 0,
|
||||
u'disabled': 0,
|
||||
u'errors': 0,
|
||||
u'time': u'*',
|
||||
u'testsuite': [
|
||||
{
|
||||
u'name': u'HasTypeParamAttribute',
|
||||
u'type_param': u'int',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'Single/TypeParameterizedTestCase/0'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
u'name': u'Single/TypeParameterizedTestCase/1',
|
||||
u'tests': 1,
|
||||
u'failures': 0,
|
||||
u'disabled': 0,
|
||||
u'errors': 0,
|
||||
u'time': u'*',
|
||||
u'testsuite': [
|
||||
{
|
||||
u'name': u'HasTypeParamAttribute',
|
||||
u'type_param': u'long',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'Single/TypeParameterizedTestCase/1'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
u'name': u'Single/ValueParamTest',
|
||||
u'tests': 4,
|
||||
u'failures': 0,
|
||||
u'disabled': 0,
|
||||
u'errors': 0,
|
||||
u'time': u'*',
|
||||
u'testsuite': [
|
||||
{
|
||||
u'name': u'HasValueParamAttribute/0',
|
||||
u'value_param': u'33',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'Single/ValueParamTest'
|
||||
},
|
||||
{
|
||||
u'name': u'HasValueParamAttribute/1',
|
||||
u'value_param': u'42',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'Single/ValueParamTest'
|
||||
},
|
||||
{
|
||||
u'name': u'AnotherTestThatHasValueParamAttribute/0',
|
||||
u'value_param': u'33',
|
||||
u'status': u'RUN',
|
||||
u'time': u'*',
|
||||
u'classname': u'Single/ValueParamTest'
|
||||
},
|
||||
{
|
||||
u'name': u'AnotherTestThatHasValueParamAttribute/1',
|
||||
u'value_param': u'42',
|
||||
u'status': u'RUN',
|
||||
u'time': 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'testsuite': [{
|
||||
u'name': u'Succeeds',
|
||||
u'status': u'RUN',
|
||||
u'time': 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__':
|
||||
os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
|
||||
gtest_test_utils.Main()
|
60
googletest/test/gtest_json_test_utils.py
Normal file
60
googletest/test/gtest_json_test_utils.py
Normal file
@ -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$', u'*', 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
|
@ -39,9 +39,8 @@ Google Test) the command line flags.
|
||||
|
||||
__author__ = 'phanna@google.com (Patrick Hanna)'
|
||||
|
||||
import gtest_test_utils
|
||||
import re
|
||||
|
||||
import gtest_test_utils
|
||||
|
||||
# Constants.
|
||||
|
||||
@ -123,6 +122,7 @@ def Run(args):
|
||||
|
||||
# The unit test.
|
||||
|
||||
|
||||
class GTestListTestsUnitTest(gtest_test_utils.TestCase):
|
||||
"""Tests using the --gtest_list_tests flag to list all tests."""
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user