mirror of
https://github.com/google/googletest.git
synced 2025-01-22 07:31:04 +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/
|
Win32-Release/
|
||||||
x64-Debug/
|
x64-Debug/
|
||||||
x64-Release/
|
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:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
sudo: true
|
sudo : true
|
||||||
cache:
|
|
||||||
install: ./ci/install-linux.sh && ./ci/log-config.sh
|
install: ./ci/install-linux.sh && ./ci/log-config.sh
|
||||||
script: ./ci/build-linux-bazel.sh
|
script: ./ci/build-linux-bazel.sh
|
||||||
- os: linux
|
- os: linux
|
||||||
compiler: clang
|
compiler: clang
|
||||||
sudo: true
|
sudo : true
|
||||||
cache:
|
|
||||||
install: ./ci/install-linux.sh && ./ci/log-config.sh
|
install: ./ci/install-linux.sh && ./ci/log-config.sh
|
||||||
script: ./ci/build-linux-bazel.sh
|
script: ./ci/build-linux-bazel.sh
|
||||||
- os: linux
|
- os: linux
|
||||||
|
group: deprecated-2017Q4
|
||||||
compiler: gcc
|
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
|
- os: linux
|
||||||
|
group: deprecated-2017Q4
|
||||||
compiler: gcc
|
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
|
- os: linux
|
||||||
|
group: deprecated-2017Q4
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: BUILD_TYPE=Debug VERBOSE=1
|
env: BUILD_TYPE=Debug VERBOSE=1
|
||||||
- os: linux
|
- os: linux
|
||||||
|
group: deprecated-2017Q4
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
|
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
env: BUILD_TYPE=Debug VERBOSE=1
|
env: BUILD_TYPE=Debug VERBOSE=1
|
||||||
|
if: type != pull_request
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
|
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
|
||||||
|
if: type != pull_request
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: BUILD_TYPE=Debug VERBOSE=1
|
env: BUILD_TYPE=Debug VERBOSE=1
|
||||||
|
if: type != pull_request
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
|
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
|
# 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.
|
# 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"])
|
licenses(["notice"])
|
||||||
|
|
||||||
config_setting(
|
config_setting(
|
||||||
name = "win",
|
name = "windows",
|
||||||
|
values = { "cpu": "x64_windows" },
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "windows_msvc",
|
||||||
values = {"cpu": "x64_windows_msvc"},
|
values = {"cpu": "x64_windows_msvc"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "has_absl",
|
||||||
|
values = {"define": "absl=1"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Google Test including Google Mock
|
# Google Test including Google Mock
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "gtest",
|
name = "gtest",
|
||||||
@ -65,7 +76,8 @@ cc_library(
|
|||||||
]),
|
]),
|
||||||
copts = select(
|
copts = select(
|
||||||
{
|
{
|
||||||
":win": [],
|
":windows": [],
|
||||||
|
":windows_msvc": [],
|
||||||
"//conditions:default": ["-pthread"],
|
"//conditions:default": ["-pthread"],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -76,11 +88,27 @@ cc_library(
|
|||||||
"googletest/include",
|
"googletest/include",
|
||||||
],
|
],
|
||||||
linkopts = select({
|
linkopts = select({
|
||||||
":win": [],
|
":windows": [],
|
||||||
|
":windows_msvc": [],
|
||||||
"//conditions:default": [
|
"//conditions:default": [
|
||||||
"-pthread",
|
"-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(
|
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 ###
|
### Windows Requirements ###
|
||||||
|
|
||||||
* Microsoft Visual C++ 2010 or newer
|
* Microsoft Visual C++ 2015 or newer
|
||||||
|
|
||||||
### Cygwin Requirements ###
|
### Cygwin Requirements ###
|
||||||
|
|
||||||
|
@ -1 +1,8 @@
|
|||||||
workspace(name = "com_google_googletest")
|
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
|
- compiler: msvc-15-seh
|
||||||
generator: "Visual Studio 15 2017 Win64"
|
generator: "Visual Studio 15 2017 Win64"
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||||
|
enabled_on_pr: yes
|
||||||
|
|
||||||
- compiler: msvc-14-seh
|
- compiler: msvc-14-seh
|
||||||
generator: "Visual Studio 14 2015"
|
generator: "Visual Studio 14 2015"
|
||||||
|
enabled_on_pr: yes
|
||||||
|
|
||||||
- compiler: msvc-14-seh
|
- compiler: msvc-14-seh
|
||||||
generator: "Visual Studio 14 2015 Win64"
|
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
|
- compiler: gcc-5.3.0-posix
|
||||||
generator: "MinGW Makefiles"
|
generator: "MinGW Makefiles"
|
||||||
cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin'
|
cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin'
|
||||||
@ -43,7 +30,6 @@ environment:
|
|||||||
|
|
||||||
configuration:
|
configuration:
|
||||||
- Debug
|
- Debug
|
||||||
#- Release
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
verbosity: minimal
|
verbosity: minimal
|
||||||
@ -52,6 +38,14 @@ install:
|
|||||||
- ps: |
|
- ps: |
|
||||||
Write-Output "Compiler: $env:compiler"
|
Write-Output "Compiler: $env:compiler"
|
||||||
Write-Output "Generator: $env:generator"
|
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
|
# git bash conflicts with MinGW makefiles
|
||||||
if ($env:generator -eq "MinGW Makefiles") {
|
if ($env:generator -eq "MinGW Makefiles") {
|
||||||
@ -63,6 +57,10 @@ install:
|
|||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- ps: |
|
- 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
|
md _build -Force | Out-Null
|
||||||
cd _build
|
cd _build
|
||||||
|
|
||||||
@ -74,13 +72,18 @@ build_script:
|
|||||||
if ($LastExitCode -ne 0) {
|
if ($LastExitCode -ne 0) {
|
||||||
throw "Exec: $ErrorMessage"
|
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) {
|
if ($LastExitCode -ne 0) {
|
||||||
throw "Exec: $ErrorMessage"
|
throw "Exec: $ErrorMessage"
|
||||||
}
|
}
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- ps: |
|
- 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") {
|
if ($env:generator -eq "MinGW Makefiles") {
|
||||||
return # No test available for MinGW
|
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 build --curses=no //...:all
|
||||||
bazel test --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
|
#!/usr/bin/env sh
|
||||||
set -evx
|
set -evx
|
||||||
|
|
||||||
|
. ci/get-nprocessors.sh
|
||||||
|
|
||||||
# if possible, ask for the precise number of processors,
|
# if possible, ask for the precise number of processors,
|
||||||
# otherwise take 2 processors as reasonable default; see
|
# otherwise take 2 processors as reasonable default; see
|
||||||
# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization
|
# 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
|
# 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
|
# are used for other targets, to ensure that Google Mock can be compiled by
|
||||||
# a user aggressive about warnings.
|
# a user aggressive about warnings.
|
||||||
cxx_library(gmock
|
if (MSVC)
|
||||||
"${cxx_strict}"
|
cxx_library(gmock
|
||||||
"${gtest_dir}/src/gtest-all.cc"
|
"${cxx_strict}"
|
||||||
src/gmock-all.cc)
|
"${gtest_dir}/src/gtest-all.cc"
|
||||||
|
src/gmock-all.cc)
|
||||||
|
|
||||||
cxx_library(gmock_main
|
cxx_library(gmock_main
|
||||||
"${cxx_strict}"
|
"${cxx_strict}"
|
||||||
"${gtest_dir}/src/gtest-all.cc"
|
"${gtest_dir}/src/gtest-all.cc"
|
||||||
src/gmock-all.cc
|
src/gmock-all.cc
|
||||||
src/gmock_main.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
|
# 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
|
# 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.
|
# C++ tests built with non-standard compiler flags.
|
||||||
|
|
||||||
cxx_library(gmock_main_no_exception "${cxx_no_exception}"
|
if (MSVC)
|
||||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
cxx_library(gmock_main_no_exception "${cxx_no_exception}"
|
||||||
|
|
||||||
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}"
|
|
||||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
"${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}"
|
cxx_library(gmock_main_no_rtti "${cxx_no_rtti}"
|
||||||
gmock_main_use_own_tuple test/gmock-spec-builders_test.cc)
|
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||||
endif()
|
|
||||||
|
|
||||||
|
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}"
|
cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}"
|
||||||
gmock_main_no_exception test/gmock-more-actions_test.cc)
|
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_LDFLAGS=`${GTEST_CONFIG} --ldflags`
|
||||||
GTEST_LIBS=`${GTEST_CONFIG} --libs`
|
GTEST_LIBS=`${GTEST_CONFIG} --libs`
|
||||||
GTEST_VERSION=`${GTEST_CONFIG} --version`],
|
GTEST_VERSION=`${GTEST_CONFIG} --version`],
|
||||||
[AC_CONFIG_SUBDIRS([../googletest])
|
[
|
||||||
# GTEST_CONFIG needs to be executable both in a Makefile environment and
|
# 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.
|
# in a shell script environment, so resolve an absolute path for it here.
|
||||||
GTEST_CONFIG="`pwd -P`/../googletest/scripts/gtest-config"
|
GTEST_CONFIG="`pwd -P`/../googletest/scripts/gtest-config"
|
||||||
|
@ -178,6 +178,8 @@ divided into several categories:
|
|||||||
|`Ne(value)` |`argument != value`|
|
|`Ne(value)` |`argument != value`|
|
||||||
|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).|
|
|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).|
|
||||||
|`NotNull()` |`argument` is a non-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`.|
|
|`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.|
|
|`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.
|
object will be deleted.
|
||||||
|
|
||||||
Therefore, if you have some complex matcher that you want to use again
|
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,
|
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
|
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
|
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
|
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
|
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
|
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.
|
deleted.
|
||||||
|
|
||||||
If you have some complex action that you want to use again and again,
|
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
|
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
|
no matter how many times it has been called), you can assign it to an
|
||||||
action variable and use that variable repeatedly. For example:
|
action variable and use that variable repeatedly. For example:
|
||||||
|
@ -47,10 +47,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "gtest/gtest.h"
|
||||||
#include "gmock/internal/gmock-internal-utils.h"
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
#include "gtest/gtest.h"
|
|
||||||
|
|
||||||
#if GTEST_HAS_STD_INITIALIZER_LIST_
|
#if GTEST_HAS_STD_INITIALIZER_LIST_
|
||||||
# include <initializer_list> // NOLINT -- must be after gtest.h
|
# include <initializer_list> // NOLINT -- must be after gtest.h
|
||||||
@ -515,7 +514,7 @@ template <typename T, typename M>
|
|||||||
class MatcherCastImpl {
|
class MatcherCastImpl {
|
||||||
public:
|
public:
|
||||||
static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
|
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
|
// its conversion operator to create Matcher<T>. Or it can be a value
|
||||||
// that should be passed to the Matcher<T>'s constructor.
|
// 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
|
// MatcherList provides mechanisms for storing a variable number of matchers in
|
||||||
// a list structure (ListType) and creating a combining matcher from such a
|
// a list structure (ListType) and creating a combining matcher from such a
|
||||||
// list.
|
// 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.
|
// * kSize is the length of the MatcherList.
|
||||||
// * Head is the type of the first matcher of the list.
|
// * Head is the type of the first matcher of the list.
|
||||||
// * Tail denotes the types of the remaining matchers of the list.
|
// * Tail denotes the types of the remaining matchers of the list.
|
||||||
@ -2380,7 +2379,7 @@ class ResultOfMatcher {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Functors often define operator() as non-const method even though
|
// 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
|
// 'this' is a const pointer. It's the user's responsibility not to
|
||||||
// use stateful callables with ResultOf(), which does't guarantee
|
// use stateful callables with ResultOf(), which does't guarantee
|
||||||
// how many times the callable will be invoked.
|
// how many times the callable will be invoked.
|
||||||
@ -3304,14 +3303,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
|
|||||||
GTEST_API_ ElementMatcherPairs
|
GTEST_API_ ElementMatcherPairs
|
||||||
FindMaxBipartiteMatching(const MatchMatrix& g);
|
FindMaxBipartiteMatching(const MatchMatrix& g);
|
||||||
|
|
||||||
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
|
struct UnorderedMatcherRequire {
|
||||||
MatchResultListener* listener);
|
enum Flags {
|
||||||
|
Superset = 1 << 0,
|
||||||
|
Subset = 1 << 1,
|
||||||
|
ExactMatch = Superset | Subset,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// Untyped base class for implementing UnorderedElementsAre. By
|
// Untyped base class for implementing UnorderedElementsAre. By
|
||||||
// putting logic that's not specific to the element type here, we
|
// putting logic that's not specific to the element type here, we
|
||||||
// reduce binary bloat and increase compilation speed.
|
// reduce binary bloat and increase compilation speed.
|
||||||
class GTEST_API_ UnorderedElementsAreMatcherImplBase {
|
class GTEST_API_ UnorderedElementsAreMatcherImplBase {
|
||||||
protected:
|
protected:
|
||||||
|
explicit UnorderedElementsAreMatcherImplBase(
|
||||||
|
UnorderedMatcherRequire::Flags matcher_flags)
|
||||||
|
: match_flags_(matcher_flags) {}
|
||||||
|
|
||||||
// A vector of matcher describers, one for each element matcher.
|
// A vector of matcher describers, one for each element matcher.
|
||||||
// Does not own the describers (and thus can be used only when the
|
// Does not own the describers (and thus can be used only when the
|
||||||
// element matchers are alive).
|
// element matchers are alive).
|
||||||
@ -3323,9 +3331,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
|
|||||||
// Describes the negation of this UnorderedElementsAre matcher.
|
// Describes the negation of this UnorderedElementsAre matcher.
|
||||||
void DescribeNegationToImpl(::std::ostream* os) const;
|
void DescribeNegationToImpl(::std::ostream* os) const;
|
||||||
|
|
||||||
bool VerifyAllElementsAndMatchersAreMatched(
|
bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,
|
||||||
const ::std::vector<std::string>& element_printouts,
|
const MatchMatrix& matrix,
|
||||||
const MatchMatrix& matrix, MatchResultListener* listener) const;
|
MatchResultListener* listener) const;
|
||||||
|
|
||||||
|
bool FindPairing(const MatchMatrix& matrix,
|
||||||
|
MatchResultListener* listener) const;
|
||||||
|
|
||||||
MatcherDescriberVec& matcher_describers() {
|
MatcherDescriberVec& matcher_describers() {
|
||||||
return matcher_describers_;
|
return matcher_describers_;
|
||||||
@ -3335,13 +3346,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
|
|||||||
return Message() << n << " element" << (n == 1 ? "" : "s");
|
return Message() << n << " element" << (n == 1 ? "" : "s");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
UnorderedMatcherRequire::Flags match_flags_;
|
||||||
MatcherDescriberVec matcher_describers_;
|
MatcherDescriberVec matcher_describers_;
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
|
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implements unordered ElementsAre and unordered ElementsAreArray.
|
// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
|
||||||
|
// IsSupersetOf.
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
class UnorderedElementsAreMatcherImpl
|
class UnorderedElementsAreMatcherImpl
|
||||||
: public MatcherInterface<Container>,
|
: public MatcherInterface<Container>,
|
||||||
@ -3354,10 +3369,10 @@ class UnorderedElementsAreMatcherImpl
|
|||||||
typedef typename StlContainer::const_iterator StlContainerConstIterator;
|
typedef typename StlContainer::const_iterator StlContainerConstIterator;
|
||||||
typedef typename StlContainer::value_type Element;
|
typedef typename StlContainer::value_type Element;
|
||||||
|
|
||||||
// Constructs the matcher from a sequence of element values or
|
|
||||||
// element matchers.
|
|
||||||
template <typename InputIter>
|
template <typename InputIter>
|
||||||
UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) {
|
UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
|
||||||
|
InputIter first, InputIter last)
|
||||||
|
: UnorderedElementsAreMatcherImplBase(matcher_flags) {
|
||||||
for (; first != last; ++first) {
|
for (; first != last; ++first) {
|
||||||
matchers_.push_back(MatcherCast<const Element&>(*first));
|
matchers_.push_back(MatcherCast<const Element&>(*first));
|
||||||
matcher_describers().push_back(matchers_.back().GetDescriber());
|
matcher_describers().push_back(matchers_.back().GetDescriber());
|
||||||
@ -3378,34 +3393,32 @@ class UnorderedElementsAreMatcherImpl
|
|||||||
MatchResultListener* listener) const {
|
MatchResultListener* listener) const {
|
||||||
StlContainerReference stl_container = View::ConstReference(container);
|
StlContainerReference stl_container = View::ConstReference(container);
|
||||||
::std::vector<std::string> element_printouts;
|
::std::vector<std::string> element_printouts;
|
||||||
MatchMatrix matrix = AnalyzeElements(stl_container.begin(),
|
MatchMatrix matrix =
|
||||||
stl_container.end(),
|
AnalyzeElements(stl_container.begin(), stl_container.end(),
|
||||||
&element_printouts,
|
&element_printouts, listener);
|
||||||
listener);
|
|
||||||
|
|
||||||
const size_t actual_count = matrix.LhsSize();
|
if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
|
||||||
if (actual_count == 0 && matchers_.empty()) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (actual_count != matchers_.size()) {
|
|
||||||
// The element count doesn't match. If the container is empty,
|
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||||
// there's no need to explain anything as Google Mock already
|
if (matrix.LhsSize() != matrix.RhsSize()) {
|
||||||
// prints the empty container. Otherwise we just need to show
|
// The element count doesn't match. If the container is empty,
|
||||||
// how many elements there actually are.
|
// there's no need to explain anything as Google Mock already
|
||||||
if (actual_count != 0 && listener->IsInterested()) {
|
// prints the empty container. Otherwise we just need to show
|
||||||
*listener << "which has " << Elements(actual_count);
|
// 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,
|
return VerifyMatchMatrix(element_printouts, matrix, listener) &&
|
||||||
matrix, listener) &&
|
|
||||||
FindPairing(matrix, listener);
|
FindPairing(matrix, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef ::std::vector<Matcher<const Element&> > MatcherVec;
|
|
||||||
|
|
||||||
template <typename ElementIter>
|
template <typename ElementIter>
|
||||||
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
|
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
|
||||||
::std::vector<std::string>* element_printouts,
|
::std::vector<std::string>* element_printouts,
|
||||||
@ -3432,7 +3445,7 @@ class UnorderedElementsAreMatcherImpl
|
|||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatcherVec matchers_;
|
::std::vector<Matcher<const Element&> > matchers_;
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
|
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
|
||||||
};
|
};
|
||||||
@ -3465,7 +3478,7 @@ class UnorderedElementsAreMatcher {
|
|||||||
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
|
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
|
||||||
::std::back_inserter(matchers));
|
::std::back_inserter(matchers));
|
||||||
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
|
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
|
||||||
matchers.begin(), matchers.end()));
|
UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -3498,24 +3511,23 @@ class ElementsAreMatcher {
|
|||||||
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
|
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implements UnorderedElementsAreArray().
|
// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UnorderedElementsAreArrayMatcher {
|
class UnorderedElementsAreArrayMatcher {
|
||||||
public:
|
public:
|
||||||
UnorderedElementsAreArrayMatcher() {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
template <typename Iter>
|
||||||
UnorderedElementsAreArrayMatcher(Iter first, Iter last)
|
UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
|
||||||
: matchers_(first, last) {}
|
Iter first, Iter last)
|
||||||
|
: match_flags_(match_flags), matchers_(first, last) {}
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
operator Matcher<Container>() const {
|
operator Matcher<Container>() const {
|
||||||
return MakeMatcher(
|
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
|
||||||
new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(),
|
match_flags_, matchers_.begin(), matchers_.end()));
|
||||||
matchers_.end()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
UnorderedMatcherRequire::Flags match_flags_;
|
||||||
::std::vector<T> matchers_;
|
::std::vector<T> matchers_;
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
|
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
|
||||||
@ -3624,9 +3636,69 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
|
|||||||
const char* matcher_name,
|
const char* matcher_name,
|
||||||
const Strings& param_values);
|
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
|
} // namespace internal
|
||||||
|
|
||||||
// ElementsAreArray(first, last)
|
// ElementsAreArray(iterator_first, iterator_last)
|
||||||
// ElementsAreArray(pointer, count)
|
// ElementsAreArray(pointer, count)
|
||||||
// ElementsAreArray(array)
|
// ElementsAreArray(array)
|
||||||
// ElementsAreArray(container)
|
// ElementsAreArray(container)
|
||||||
@ -3675,20 +3747,26 @@ ElementsAreArray(::std::initializer_list<T> xs) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// UnorderedElementsAreArray(first, last)
|
// UnorderedElementsAreArray(iterator_first, iterator_last)
|
||||||
// UnorderedElementsAreArray(pointer, count)
|
// UnorderedElementsAreArray(pointer, count)
|
||||||
// UnorderedElementsAreArray(array)
|
// UnorderedElementsAreArray(array)
|
||||||
// UnorderedElementsAreArray(container)
|
// UnorderedElementsAreArray(container)
|
||||||
// UnorderedElementsAreArray({ e1, e2, ..., en })
|
// UnorderedElementsAreArray({ e1, e2, ..., en })
|
||||||
//
|
//
|
||||||
// The UnorderedElementsAreArray() functions are like
|
// UnorderedElementsAreArray() verifies that a bijective mapping onto a
|
||||||
// ElementsAreArray(...), but allow matching the elements in any order.
|
// 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>
|
template <typename Iter>
|
||||||
inline internal::UnorderedElementsAreArrayMatcher<
|
inline internal::UnorderedElementsAreArrayMatcher<
|
||||||
typename ::std::iterator_traits<Iter>::value_type>
|
typename ::std::iterator_traits<Iter>::value_type>
|
||||||
UnorderedElementsAreArray(Iter first, Iter last) {
|
UnorderedElementsAreArray(Iter first, Iter last) {
|
||||||
typedef typename ::std::iterator_traits<Iter>::value_type T;
|
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>
|
template <typename T>
|
||||||
@ -3730,7 +3808,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) {
|
|||||||
const internal::AnythingMatcher _ = {};
|
const internal::AnythingMatcher _ = {};
|
||||||
// Creates a matcher that matches any value of the given type T.
|
// Creates a matcher that matches any value of the given type T.
|
||||||
template <typename 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.
|
// Creates a matcher that matches any value of the given type T.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -4300,6 +4380,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
|
|||||||
return internal::ContainsMatcher<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
|
// Matches an STL-style container or a native array that contains only
|
||||||
// elements matching the given value or matcher.
|
// elements matching the given value or matcher.
|
||||||
//
|
//
|
||||||
@ -4398,6 +4600,17 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
|
|||||||
template <typename InnerMatcher>
|
template <typename InnerMatcher>
|
||||||
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
|
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
|
// These macros allow using matchers to check values in Google Test
|
||||||
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
|
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
|
||||||
// succeed iff the value matches the matcher. If the assertion fails,
|
// 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;
|
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
|
} // namespace testing
|
||||||
|
|
||||||
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_
|
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||||
|
@ -65,11 +65,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if GTEST_HAS_EXCEPTIONS
|
|
||||||
# include <stdexcept> // NOLINT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "gmock/gmock-actions.h"
|
#include "gmock/gmock-actions.h"
|
||||||
#include "gmock/gmock-cardinalities.h"
|
#include "gmock/gmock-cardinalities.h"
|
||||||
#include "gmock/gmock-matchers.h"
|
#include "gmock/gmock-matchers.h"
|
||||||
@ -77,6 +72,10 @@
|
|||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#if GTEST_HAS_EXCEPTIONS
|
||||||
|
# include <stdexcept> // NOLINT
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
// An abstract handle of an expectation.
|
// An abstract handle of an expectation.
|
||||||
|
@ -59,8 +59,8 @@
|
|||||||
#include "gmock/gmock-cardinalities.h"
|
#include "gmock/gmock-cardinalities.h"
|
||||||
#include "gmock/gmock-generated-actions.h"
|
#include "gmock/gmock-generated-actions.h"
|
||||||
#include "gmock/gmock-generated-function-mockers.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-matchers.h"
|
||||||
|
#include "gmock/gmock-generated-nice-strict.h"
|
||||||
#include "gmock/gmock-matchers.h"
|
#include "gmock/gmock-matchers.h"
|
||||||
#include "gmock/gmock-more-actions.h"
|
#include "gmock/gmock-more-actions.h"
|
||||||
#include "gmock/gmock-more-matchers.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>
|
template <typename A1, typename A2, typename A3, typename A4>
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4> > {
|
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4> > {
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
|
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4> >
|
||||||
Matcher<A4> > type;
|
type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5> > {
|
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5> > {
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
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,
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
typename A6>
|
typename A6>
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
|
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
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,
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
typename A6, typename A7>
|
typename A6, typename A7>
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
|
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
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,
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
typename A6, typename A7, typename A8>
|
typename A6, typename A7, typename A8>
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
|
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
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,
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
typename A6, typename A7, typename A8, typename A9>
|
typename A6, typename A7, typename A8, typename A9>
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, 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>,
|
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,
|
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,
|
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||||
A10> > {
|
A10> > {
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
|
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>,
|
||||||
Matcher<A10> > type;
|
Matcher<A9>, Matcher<A10> >
|
||||||
|
type;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Template struct Function<F>, where F must be a function type, contains
|
// Template struct Function<F>, where F must be a function type, contains
|
||||||
|
@ -41,7 +41,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "gmock/internal/gmock-generated-internal-utils.h"
|
#include "gmock/internal/gmock-generated-internal-utils.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
@ -49,11 +48,15 @@
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
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
|
// 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
|
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||||
// treated as one word. For example, both "FooBar123" and
|
// treated as one word. For example, both "FooBar123" and
|
||||||
// "foo_bar_123" are converted to "foo bar 123".
|
// "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
|
// 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
|
// 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>
|
template <bool kValue>
|
||||||
struct BooleanConstant {};
|
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 internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||||
|
|
||||||
|
@ -50,15 +50,11 @@
|
|||||||
// portability utilities to Google Test's gtest-port.h instead of
|
// portability utilities to Google Test's gtest-port.h instead of
|
||||||
// here, as Google Mock depends on Google Test. Only add a utility
|
// here, as Google Mock depends on Google Test. Only add a utility
|
||||||
// here if it's truly specific to Google Mock.
|
// here if it's truly specific to Google Mock.
|
||||||
|
|
||||||
#include "gtest/internal/gtest-linked_ptr.h"
|
#include "gtest/internal/gtest-linked_ptr.h"
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
#include "gmock/internal/custom/gmock-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
|
// For MS Visual C++, check the compiler version. At least VS 2003 is
|
||||||
// required to compile Google Mock.
|
// required to compile Google Mock.
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1310
|
#if defined(_MSC_VER) && _MSC_VER < 1310
|
||||||
@ -72,18 +68,18 @@
|
|||||||
#if !defined(GMOCK_DECLARE_bool_)
|
#if !defined(GMOCK_DECLARE_bool_)
|
||||||
|
|
||||||
// Macros for declaring flags.
|
// Macros for declaring flags.
|
||||||
#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
||||||
#define GMOCK_DECLARE_int32_(name) \
|
# define GMOCK_DECLARE_int32_(name) \
|
||||||
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(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)
|
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
||||||
|
|
||||||
// Macros for defining flags.
|
// 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)
|
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)
|
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)
|
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
||||||
|
|
||||||
#endif // !defined(GMOCK_DECLARE_bool_)
|
#endif // !defined(GMOCK_DECLARE_bool_)
|
||||||
|
@ -338,7 +338,7 @@ class Class(_GenericDeclaration):
|
|||||||
# TODO(nnorwitz): handle namespaces, etc.
|
# TODO(nnorwitz): handle namespaces, etc.
|
||||||
if self.bases:
|
if self.bases:
|
||||||
for token_list in 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:
|
for token in token_list:
|
||||||
if token.name == node.name:
|
if token.name == node.name:
|
||||||
return True
|
return True
|
||||||
@ -381,7 +381,7 @@ class Function(_GenericDeclaration):
|
|||||||
|
|
||||||
def Requires(self, node):
|
def Requires(self, node):
|
||||||
if self.parameters:
|
if self.parameters:
|
||||||
# TODO(nnorwitz): parameters are tokens, do name comparision.
|
# TODO(nnorwitz): parameters are tokens, do name comparison.
|
||||||
for p in self.parameters:
|
for p in self.parameters:
|
||||||
if p.name == node.name:
|
if p.name == node.name:
|
||||||
return True
|
return True
|
||||||
@ -858,7 +858,7 @@ class AstBuilder(object):
|
|||||||
last_token = self._GetNextToken()
|
last_token = self._GetNextToken()
|
||||||
return tokens, last_token
|
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):
|
def _IgnoreUpTo(self, token_type, token):
|
||||||
unused_tokens = self._GetTokensUpTo(token_type, token)
|
unused_tokens = self._GetTokensUpTo(token_type, token)
|
||||||
|
|
||||||
|
@ -47,6 +47,25 @@
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
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
|
// 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
|
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||||
// treated as one word. For example, both "FooBar123" and
|
// treated as one word. For example, both "FooBar123" and
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "gmock/gmock-generated-matchers.h"
|
#include "gmock/gmock-generated-matchers.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -100,25 +101,6 @@ Matcher<StringPiece>::Matcher(StringPiece s) {
|
|||||||
|
|
||||||
namespace internal {
|
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*()
|
// Returns the description for a matcher defined using the MATCHER*()
|
||||||
// macro where the user-supplied description string is "", if
|
// macro where the user-supplied description string is "", if
|
||||||
// 'negation' is false; otherwise returns the description of the
|
// 'negation' is false; otherwise returns the description of the
|
||||||
@ -200,8 +182,7 @@ class MaxBipartiteMatchState {
|
|||||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||||
: graph_(&graph),
|
: graph_(&graph),
|
||||||
left_(graph_->LhsSize(), kUnused),
|
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}.
|
// Returns the edges of a maximal match, each in the form {left, right}.
|
||||||
ElementMatcherPairs Compute() {
|
ElementMatcherPairs Compute() {
|
||||||
@ -258,10 +239,8 @@ class MaxBipartiteMatchState {
|
|||||||
//
|
//
|
||||||
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
|
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
|
||||||
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
|
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
|
||||||
if ((*seen)[irhs])
|
if ((*seen)[irhs]) continue;
|
||||||
continue;
|
if (!graph_->HasEdge(ilhs, irhs)) continue;
|
||||||
if (!graph_->HasEdge(ilhs, irhs))
|
|
||||||
continue;
|
|
||||||
// There's an available edge from ilhs to irhs.
|
// There's an available edge from ilhs to irhs.
|
||||||
(*seen)[irhs] = 1;
|
(*seen)[irhs] = 1;
|
||||||
// Next a search is performed to determine whether
|
// Next a search is performed to determine whether
|
||||||
@ -304,8 +283,7 @@ class MaxBipartiteMatchState {
|
|||||||
|
|
||||||
const size_t MaxBipartiteMatchState::kUnused;
|
const size_t MaxBipartiteMatchState::kUnused;
|
||||||
|
|
||||||
GTEST_API_ ElementMatcherPairs
|
GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {
|
||||||
FindMaxBipartiteMatching(const MatchMatrix& g) {
|
|
||||||
return MaxBipartiteMatchState(g).Compute();
|
return MaxBipartiteMatchState(g).Compute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +292,7 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
|||||||
typedef ElementMatcherPairs::const_iterator Iter;
|
typedef ElementMatcherPairs::const_iterator Iter;
|
||||||
::std::ostream& os = *stream;
|
::std::ostream& os = *stream;
|
||||||
os << "{";
|
os << "{";
|
||||||
const char *sep = "";
|
const char* sep = "";
|
||||||
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||||
os << sep << "\n ("
|
os << sep << "\n ("
|
||||||
<< "element #" << it->first << ", "
|
<< "element #" << it->first << ", "
|
||||||
@ -324,38 +302,6 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
|||||||
os << "\n}";
|
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() {
|
bool MatchMatrix::NextGraph() {
|
||||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||||
@ -381,7 +327,7 @@ void MatchMatrix::Randomize() {
|
|||||||
|
|
||||||
std::string MatchMatrix::DebugString() const {
|
std::string MatchMatrix::DebugString() const {
|
||||||
::std::stringstream ss;
|
::std::stringstream ss;
|
||||||
const char *sep = "";
|
const char* sep = "";
|
||||||
for (size_t i = 0; i < LhsSize(); ++i) {
|
for (size_t i = 0; i < LhsSize(); ++i) {
|
||||||
ss << sep;
|
ss << sep;
|
||||||
for (size_t j = 0; j < RhsSize(); ++j) {
|
for (size_t j = 0; j < RhsSize(); ++j) {
|
||||||
@ -394,44 +340,83 @@ std::string MatchMatrix::DebugString() const {
|
|||||||
|
|
||||||
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
|
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
|
||||||
::std::ostream* os) const {
|
::std::ostream* os) const {
|
||||||
if (matcher_describers_.empty()) {
|
switch (match_flags()) {
|
||||||
*os << "is empty";
|
case UnorderedMatcherRequire::ExactMatch:
|
||||||
return;
|
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 = "";
|
const char* sep = "";
|
||||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
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);
|
matcher_describers_[i]->DescribeTo(os);
|
||||||
sep = ", and\n";
|
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||||
|
sep = ", and\n";
|
||||||
|
} else {
|
||||||
|
sep = "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
||||||
::std::ostream* os) const {
|
::std::ostream* os) const {
|
||||||
if (matcher_describers_.empty()) {
|
switch (match_flags()) {
|
||||||
*os << "isn't empty";
|
case UnorderedMatcherRequire::ExactMatch:
|
||||||
return;
|
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 = "";
|
const char* sep = "";
|
||||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
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);
|
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.
|
// and better error reporting.
|
||||||
// Returns false, writing an explanation to 'listener', if and only
|
// Returns false, writing an explanation to 'listener', if and only
|
||||||
// if the success criteria are not met.
|
// if the success criteria are not met.
|
||||||
bool UnorderedElementsAreMatcherImplBase::
|
bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
|
||||||
VerifyAllElementsAndMatchersAreMatched(
|
const ::std::vector<std::string>& element_printouts,
|
||||||
const ::std::vector<std::string>& element_printouts,
|
const MatchMatrix& matrix, MatchResultListener* listener) const {
|
||||||
const MatchMatrix& matrix, MatchResultListener* listener) const {
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||||
@ -456,12 +440,11 @@ bool UnorderedElementsAreMatcherImplBase::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (match_flags() & UnorderedMatcherRequire::Superset) {
|
||||||
const char* sep =
|
const char* sep =
|
||||||
"where the following matchers don't match any elements:\n";
|
"where the following matchers don't match any elements:\n";
|
||||||
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
|
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
|
||||||
if (matcher_matched[mi])
|
if (matcher_matched[mi]) continue;
|
||||||
continue;
|
|
||||||
result = false;
|
result = false;
|
||||||
if (listener->IsInterested()) {
|
if (listener->IsInterested()) {
|
||||||
*listener << sep << "matcher #" << mi << ": ";
|
*listener << sep << "matcher #" << mi << ": ";
|
||||||
@ -471,7 +454,7 @@ bool UnorderedElementsAreMatcherImplBase::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (match_flags() & UnorderedMatcherRequire::Subset) {
|
||||||
const char* sep =
|
const char* sep =
|
||||||
"where the following elements don't match any matchers:\n";
|
"where the following elements don't match any matchers:\n";
|
||||||
const char* outer_sep = "";
|
const char* outer_sep = "";
|
||||||
@ -479,8 +462,7 @@ bool UnorderedElementsAreMatcherImplBase::
|
|||||||
outer_sep = "\nand ";
|
outer_sep = "\nand ";
|
||||||
}
|
}
|
||||||
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
|
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
|
||||||
if (element_matched[ei])
|
if (element_matched[ei]) continue;
|
||||||
continue;
|
|
||||||
result = false;
|
result = false;
|
||||||
if (listener->IsInterested()) {
|
if (listener->IsInterested()) {
|
||||||
*listener << outer_sep << sep << "element #" << ei << ": "
|
*listener << outer_sep << sep << "element #" << ei << ": "
|
||||||
@ -493,5 +475,46 @@ bool UnorderedElementsAreMatcherImplBase::
|
|||||||
return result;
|
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 internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
@ -508,7 +508,7 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
|||||||
return expectations_met;
|
return expectations_met;
|
||||||
}
|
}
|
||||||
|
|
||||||
CallReaction intToCallReaction(int mock_behavior) {
|
static CallReaction intToCallReaction(int mock_behavior) {
|
||||||
if (mock_behavior >= kAllow && mock_behavior <= kFail) {
|
if (mock_behavior >= kAllow && mock_behavior <= kFail) {
|
||||||
return static_cast<internal::CallReaction>(mock_behavior);
|
return static_cast<internal::CallReaction>(mock_behavior);
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,79 @@ cc_test(
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
linkopts = select({
|
linkopts = select({
|
||||||
"//:win": [],
|
"//:windows": [],
|
||||||
|
"//:windows_msvc": [],
|
||||||
"//conditions:default": [
|
"//conditions:default": [
|
||||||
"-pthread",
|
"-pthread",
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
deps = ["//:gtest"],
|
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
|
// 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) {
|
TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) {
|
||||||
DefaultValue<int>::Set(1);
|
DefaultValue<int>::Set(1);
|
||||||
MockClass mock;
|
MockClass mock;
|
||||||
|
@ -44,15 +44,7 @@
|
|||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "gtest/gtest-spi.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"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
#if GTEST_OS_CYGWIN
|
#if GTEST_OS_CYGWIN
|
||||||
# include <sys/types.h> // For ssize_t. NOLINT
|
# include <sys/types.h> // For ssize_t. NOLINT
|
||||||
|
@ -65,10 +65,6 @@
|
|||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
GTEST_API_ string JoinAsTuple(const Strings& fields);
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
namespace gmock_matchers_test {
|
namespace gmock_matchers_test {
|
||||||
|
|
||||||
using std::greater;
|
using std::greater;
|
||||||
@ -150,7 +146,6 @@ using testing::internal::ExplainMatchFailureTupleTo;
|
|||||||
using testing::internal::FloatingEqMatcher;
|
using testing::internal::FloatingEqMatcher;
|
||||||
using testing::internal::FormatMatcherDescription;
|
using testing::internal::FormatMatcherDescription;
|
||||||
using testing::internal::IsReadableTypeName;
|
using testing::internal::IsReadableTypeName;
|
||||||
using testing::internal::JoinAsTuple;
|
|
||||||
using testing::internal::linked_ptr;
|
using testing::internal::linked_ptr;
|
||||||
using testing::internal::MatchMatrix;
|
using testing::internal::MatchMatrix;
|
||||||
using testing::internal::RE;
|
using testing::internal::RE;
|
||||||
@ -919,7 +914,7 @@ TEST(TypedEqTest, CanDescribeSelf) {
|
|||||||
// Type<T>::IsTypeOf(v) compiles iff the type of value v is T, where T
|
// 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
|
// 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
|
// type is not T, the compiler will generate a message about
|
||||||
// "undefined referece".
|
// "undefined reference".
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Type {
|
struct Type {
|
||||||
static bool IsTypeOf(const T& /* v */) { return true; }
|
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(25, "foo"));
|
||||||
EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o")));
|
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(42, "foo")));
|
||||||
EXPECT_THAT(p, Not(Pair(Lt(25), "foo")));
|
EXPECT_THAT(p, Not(Pair(Lt(25), "foo")));
|
||||||
|
|
||||||
@ -4267,7 +4262,7 @@ TYPED_TEST(ContainerEqTest, DuplicateDifference) {
|
|||||||
#endif // GTEST_HAS_TYPED_TEST
|
#endif // GTEST_HAS_TYPED_TEST
|
||||||
|
|
||||||
// Tests that mutliple missing values are reported.
|
// 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) {
|
TEST(ContainerEqExtraTest, MultipleValuesMissing) {
|
||||||
static const int vals[] = {1, 1, 2, 3, 5, 8};
|
static const int vals[] = {1, 1, 2, 3, 5, 8};
|
||||||
static const int test_vals[] = {2, 1, 5};
|
static const int test_vals[] = {2, 1, 5};
|
||||||
@ -4280,7 +4275,7 @@ TEST(ContainerEqExtraTest, MultipleValuesMissing) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tests that added values are reported.
|
// 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) {
|
TEST(ContainerEqExtraTest, MultipleValuesAdded) {
|
||||||
static const int vals[] = {1, 1, 2, 3, 5, 8};
|
static const int vals[] = {1, 1, 2, 3, 5, 8};
|
||||||
static const int test_vals[] = {1, 2, 92, 3, 5, 8, 46};
|
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)"));
|
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().
|
// Tests FormatMatcherDescription().
|
||||||
|
|
||||||
TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) {
|
TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) {
|
||||||
@ -5682,5 +5655,69 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) {
|
|||||||
EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs));
|
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 gmock_matchers_test
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
@ -120,13 +120,15 @@
|
|||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gmock/internal/gmock-port.h"
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
using testing::_;
|
using testing::_;
|
||||||
using testing::A;
|
using testing::A;
|
||||||
|
using testing::Action;
|
||||||
using testing::AllOf;
|
using testing::AllOf;
|
||||||
using testing::AnyOf;
|
using testing::AnyOf;
|
||||||
using testing::Assign;
|
using testing::Assign;
|
||||||
@ -148,6 +150,8 @@ using testing::Invoke;
|
|||||||
using testing::InvokeArgument;
|
using testing::InvokeArgument;
|
||||||
using testing::InvokeWithoutArgs;
|
using testing::InvokeWithoutArgs;
|
||||||
using testing::IsNull;
|
using testing::IsNull;
|
||||||
|
using testing::IsSubsetOf;
|
||||||
|
using testing::IsSupersetOf;
|
||||||
using testing::Le;
|
using testing::Le;
|
||||||
using testing::Lt;
|
using testing::Lt;
|
||||||
using testing::Matcher;
|
using testing::Matcher;
|
||||||
@ -592,6 +596,22 @@ TEST(LinkTest, TestMatcherElementsAreArray) {
|
|||||||
ON_CALL(mock, VoidFromVector(ElementsAreArray(arr))).WillByDefault(Return());
|
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.
|
// Tests the linkage of the ContainerEq matcher.
|
||||||
TEST(LinkTest, TestMatcherContainerEq) {
|
TEST(LinkTest, TestMatcherContainerEq) {
|
||||||
Mock mock;
|
Mock mock;
|
||||||
|
@ -31,11 +31,11 @@
|
|||||||
|
|
||||||
"""Tests the text output of Google C++ Mocking Framework.
|
"""Tests the text output of Google C++ Mocking Framework.
|
||||||
|
|
||||||
SYNOPSIS
|
To update the golden file:
|
||||||
gmock_output_test.py --build_dir=BUILD/DIR --gengolden
|
gmock_output_test.py --build_dir=BUILD/DIR --gengolden
|
||||||
# where BUILD/DIR contains the built gmock_output_test_ file.
|
# where BUILD/DIR contains the built gmock_output_test_ file.
|
||||||
gmock_output_test.py --gengolden
|
gmock_output_test.py --gengolden
|
||||||
gmock_output_test.py
|
gmock_output_test.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||||
@ -176,5 +176,8 @@ if __name__ == '__main__':
|
|||||||
golden_file = open(GOLDEN_PATH, 'wb')
|
golden_file = open(GOLDEN_PATH, 'wb')
|
||||||
golden_file.write(output)
|
golden_file.write(output)
|
||||||
golden_file.close()
|
golden_file.close()
|
||||||
|
# Suppress the error "googletest was imported but a call to its main()
|
||||||
|
# was never detected."
|
||||||
|
os._exit(0)
|
||||||
else:
|
else:
|
||||||
gmock_test_utils.Main()
|
gmock_test_utils.Main()
|
||||||
|
@ -33,12 +33,13 @@
|
|||||||
// threads concurrently.
|
// threads concurrently.
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// From <gtest/internal/gtest-port.h>.
|
// From "gtest/internal/gtest-port.h".
|
||||||
using ::testing::internal::ThreadWithParam;
|
using ::testing::internal::ThreadWithParam;
|
||||||
|
|
||||||
// The maximum number of test threads (not including helper threads)
|
// The maximum number of test threads (not including helper threads)
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "gtest/internal/custom/gtest.h"
|
||||||
|
|
||||||
#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
#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& expected_gmock_verbose) {
|
||||||
const ::std::string old_verbose = GMOCK_FLAG(verbose);
|
const ::std::string old_verbose = GMOCK_FLAG(verbose);
|
||||||
|
|
||||||
int argc = M;
|
int argc = M - 1;
|
||||||
InitGoogleMock(&argc, const_cast<Char**>(argv));
|
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++) {
|
for (int i = 0; i < N; i++) {
|
||||||
EXPECT_STREQ(new_argv[i], argv[i]);
|
EXPECT_STREQ(new_argv[i], argv[i]);
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2006, Google Inc.
|
# Copyright 2006, Google Inc.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
@ -36,19 +34,19 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
# Determines path to gtest_test_utils and imports it.
|
# Determines path to gtest_test_utils and imports it.
|
||||||
SCRIPT_DIR = os.path.dirname(__file__) or '.'
|
SCRIPT_DIR = os.path.dirname(__file__) or '.'
|
||||||
|
|
||||||
# isdir resolves symbolic links.
|
# 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):
|
if os.path.isdir(gtest_tests_util_dir):
|
||||||
GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir
|
GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir
|
||||||
else:
|
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)
|
sys.path.append(GTEST_TESTS_UTIL_DIR)
|
||||||
import gtest_test_utils # pylint: disable-msg=C6204
|
|
||||||
|
# pylint: disable=C6204
|
||||||
|
import gtest_test_utils
|
||||||
|
|
||||||
|
|
||||||
def GetSourceDir():
|
def GetSourceDir():
|
||||||
|
@ -27,8 +27,6 @@ option(
|
|||||||
"Build gtest with internal symbols hidden in shared libraries."
|
"Build gtest with internal symbols hidden in shared libraries."
|
||||||
OFF)
|
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().
|
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
||||||
include(cmake/hermetic_build.cmake OPTIONAL)
|
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_outfile1_test_ test gtest_main)
|
||||||
cxx_executable(gtest_xml_outfile2_test_ test gtest_main)
|
cxx_executable(gtest_xml_outfile2_test_ test gtest_main)
|
||||||
py_test(gtest_xml_outfiles_test)
|
py_test(gtest_xml_outfiles_test)
|
||||||
|
py_test(gtest_json_outfiles_test)
|
||||||
|
|
||||||
cxx_executable(gtest_xml_output_unittest_ test gtest)
|
cxx_executable(gtest_xml_output_unittest_ test gtest)
|
||||||
py_test(gtest_xml_output_unittest)
|
py_test(gtest_xml_output_unittest)
|
||||||
|
py_test(gtest_json_output_unittest)
|
||||||
endif()
|
endif()
|
||||||
|
@ -34,6 +34,7 @@ EXTRA_DIST += $(GTEST_SRC)
|
|||||||
# Sample files that we don't compile.
|
# Sample files that we don't compile.
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
samples/prime_tables.h \
|
samples/prime_tables.h \
|
||||||
|
samples/sample1_unittest.cc \
|
||||||
samples/sample2_unittest.cc \
|
samples/sample2_unittest.cc \
|
||||||
samples/sample3_unittest.cc \
|
samples/sample3_unittest.cc \
|
||||||
samples/sample4_unittest.cc \
|
samples/sample4_unittest.cc \
|
||||||
@ -120,16 +121,16 @@ EXTRA_DIST += \
|
|||||||
|
|
||||||
# MSVC project files
|
# MSVC project files
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
msvc/gtest-md.sln \
|
msvc/2010/gtest-md.sln \
|
||||||
msvc/gtest-md.vcproj \
|
msvc/2010/gtest-md.vcxproj \
|
||||||
msvc/gtest.sln \
|
msvc/2010/gtest.sln \
|
||||||
msvc/gtest.vcproj \
|
msvc/2010/gtest.vcxproj \
|
||||||
msvc/gtest_main-md.vcproj \
|
msvc/2010/gtest_main-md.vcxproj \
|
||||||
msvc/gtest_main.vcproj \
|
msvc/2010/gtest_main.vcxproj \
|
||||||
msvc/gtest_prod_test-md.vcproj \
|
msvc/2010/gtest_prod_test-md.vcxproj \
|
||||||
msvc/gtest_prod_test.vcproj \
|
msvc/2010/gtest_prod_test.vcxproj \
|
||||||
msvc/gtest_unittest-md.vcproj \
|
msvc/2010/gtest_unittest-md.vcxproj \
|
||||||
msvc/gtest_unittest.vcproj
|
msvc/2010/gtest_unittest.vcxproj
|
||||||
|
|
||||||
# xcode project files
|
# xcode project files
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
@ -223,33 +224,61 @@ lib_libgtest_main_la_LIBADD = lib/libgtest.la
|
|||||||
# TESTS -- Programs run automatically by "make check"
|
# TESTS -- Programs run automatically by "make check"
|
||||||
# check_PROGRAMS -- Programs built by "make check" but not necessarily run
|
# 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=
|
||||||
TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \
|
TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \
|
||||||
GTEST_BUILD_DIR="$(top_builddir)/test"
|
GTEST_BUILD_DIR="$(top_builddir)/test"
|
||||||
check_PROGRAMS=
|
check_PROGRAMS=
|
||||||
|
|
||||||
# A simple sample on using gtest.
|
# A simple sample on using gtest.
|
||||||
TESTS += samples/sample1_unittest
|
TESTS += samples/sample1_unittest \
|
||||||
check_PROGRAMS += samples/sample1_unittest
|
samples/sample2_unittest \
|
||||||
samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc
|
samples/sample3_unittest \
|
||||||
samples_sample1_unittest_LDADD = lib/libgtest_main.la \
|
samples/sample4_unittest \
|
||||||
lib/libgtest.la \
|
samples/sample5_unittest \
|
||||||
samples/libsamples.la
|
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.
|
samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc samples/sample1.cc
|
||||||
TESTS += samples/sample10_unittest
|
samples_sample1_unittest_LDADD = lib/libgtest_main.la \
|
||||||
check_PROGRAMS += samples/sample10_unittest
|
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_SOURCES = samples/sample10_unittest.cc
|
||||||
samples_sample10_unittest_LDADD = lib/libgtest.la
|
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} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
|
||||||
set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
|
set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
|
||||||
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
|
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-")
|
set(cxx_no_rtti_flags "-GR-")
|
||||||
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
||||||
set(cxx_base_flags "-Wall -Wshadow -Werror")
|
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_exception_flags "-fexceptions")
|
||||||
set(cxx_no_exception_flags "-fno-exceptions")
|
set(cxx_no_exception_flags "-fno-exceptions")
|
||||||
# Until version 4.3.2, GCC doesn't define a macro to indicate
|
# 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}
|
set_target_properties(${name}
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
COMPILE_FLAGS "${cxx_flags}")
|
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")
|
if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED")
|
||||||
set_target_properties(${name}
|
set_target_properties(${name}
|
||||||
PROPERTIES
|
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
|
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
|
sub-routine the failure is from. You can alleviate this problem using
|
||||||
extra logging or custom failure messages, but that usually clutters up
|
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
|
where `message` can be anything streamable to `std::ostream`. `SCOPED_TRACE`
|
||||||
macro will cause the current file name, line number, and the given
|
macro will cause the current file name, line number, and the given message to be
|
||||||
message to be added in every failure message. The effect will be
|
added in every failure message. `ScopedTrace` accepts explicit file name and
|
||||||
undone when the control leaves the current lexical scope.
|
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,
|
For example,
|
||||||
|
|
||||||
@ -870,13 +872,33 @@ TEST(FooTest, Bar) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Since we don't use exceptions, it is technically impossible to
|
To alleviate this, gUnit provides three different solutions. You could use
|
||||||
implement the intended behavior here. To alleviate this, Google Test
|
either exceptions, the `(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the
|
||||||
provides two solutions. You could use either the
|
`HasFatalFailure()` function. They are described in the following two
|
||||||
`(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the
|
|
||||||
`HasFatalFailure()` function. They are described in the following two
|
|
||||||
subsections.
|
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 ###
|
### Asserting on Subroutines ###
|
||||||
|
|
||||||
As shown above, if your test calls a subroutine that has an `ASSERT_*`
|
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,
|
_Availability:_ Linux, Windows, Mac. (In Google Test 1.3.0 and lower,
|
||||||
the default behavior is that the elapsed time is **not** printed.)
|
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 ###
|
### Generating an XML Report ###
|
||||||
|
|
||||||
Google Test can emit a detailed XML report to a file in addition to its normal
|
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.
|
_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 ##
|
## Controlling How Failures Are Reported ##
|
||||||
|
|
||||||
### Turning Assertion Failures into Break-Points ###
|
### Turning Assertion Failures into Break-Points ###
|
||||||
|
@ -12,5 +12,5 @@ the respective git branch/tag).**
|
|||||||
|
|
||||||
To contribute code to Google Test, read:
|
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.
|
* [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:
|
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.
|
* 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.
|
* 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? ##
|
## 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.
|
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 ...
|
... test body ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -102,7 +102,7 @@ GTEST_API_ bool InDeathTestChild();
|
|||||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||||
// which uses the POSIX extended regex syntax.
|
// 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
|
// syntax implemented as part of Google Test. This limited
|
||||||
// implementation should be enough most of the time when writing
|
// implementation should be enough most of the time when writing
|
||||||
// death tests; though it lacks many features you can find in PCRE
|
// 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 // NDEBUG for EXPECT_DEBUG_DEATH
|
||||||
#endif // GTEST_HAS_DEATH_TEST
|
#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
|
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
|
||||||
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
||||||
// death tests are supported; otherwise they just issue a warning. This is
|
// death tests are supported; otherwise they just issue a warning. This is
|
||||||
@ -284,9 +332,9 @@ class GTEST_API_ KilledBySignal {
|
|||||||
ASSERT_DEATH(statement, regex)
|
ASSERT_DEATH(statement, regex)
|
||||||
#else
|
#else
|
||||||
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
# 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) \
|
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
|
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
@ -196,7 +196,6 @@ class GTEST_API_ Message {
|
|||||||
std::string GetString() const;
|
std::string GetString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#if GTEST_OS_SYMBIAN
|
#if GTEST_OS_SYMBIAN
|
||||||
// These are needed as the Nokia Symbian Compiler cannot decide between
|
// These are needed as the Nokia Symbian Compiler cannot decide between
|
||||||
// const T& and const T* in a function template. The Nokia compiler _can_
|
// 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!
|
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||||
#define 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
|
// 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
|
// case with any set of parameters you want. Google Test defines a number
|
||||||
// of functions for generating test parameters. They return what we call
|
// 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:
|
// 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":
|
// each with C-string values of "foo", "bar", and "baz":
|
||||||
//
|
//
|
||||||
// const char* strings[] = {"foo", "bar", "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
|
// This instantiates tests from test case StlStringTest
|
||||||
// each with STL strings with values "a" and "b":
|
// 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.
|
// type testing::TestParamInfo<class ParamType>, and return std::string.
|
||||||
//
|
//
|
||||||
// testing::PrintToStringParamName is a builtin test suffix generator that
|
// testing::PrintToStringParamName is a builtin test suffix generator that
|
||||||
// returns the value of testing::PrintToString(GetParam()). It does not work
|
// returns the value of testing::PrintToString(GetParam()).
|
||||||
// for std::string or C strings.
|
|
||||||
//
|
//
|
||||||
// Note: test names must be non-empty, unique, and may only contain ASCII
|
// 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, ...) \
|
#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; } \
|
gtest_##prefix##test_case_name##_EvalGenerator_() { \
|
||||||
::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
return generator; \
|
||||||
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
} \
|
||||||
return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
|
static ::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
||||||
(__VA_ARGS__)(info); \
|
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
||||||
} \
|
return ::testing::internal::GetParamNameGen<test_case_name::ParamType>( \
|
||||||
int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
__VA_ARGS__)(info); \
|
||||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
} \
|
||||||
GetTestCasePatternHolder<test_case_name>(\
|
static int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
#test_case_name, \
|
::testing::UnitTest::GetInstance() \
|
||||||
::testing::internal::CodeLocation(\
|
->parameterized_test_registry() \
|
||||||
__FILE__, __LINE__))->AddTestCaseInstantiation(\
|
.GetTestCasePatternHolder<test_case_name>( \
|
||||||
#prefix, \
|
#test_case_name, \
|
||||||
>est_##prefix##test_case_name##_EvalGenerator_, \
|
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||||
>est_##prefix##test_case_name##_EvalGenerateName_, \
|
->AddTestCaseInstantiation( \
|
||||||
__FILE__, __LINE__)
|
#prefix, >est_##prefix##test_case_name##_EvalGenerator_, \
|
||||||
|
>est_##prefix##test_case_name##_EvalGenerateName_, __FILE__, \
|
||||||
|
__LINE__)
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ TEST_P(FooTest, HasBlahBlah) {
|
|||||||
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
|
// 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
|
// case with any set of parameters you want. Google Test defines a number
|
||||||
// of functions for generating test parameters. They return what we call
|
// 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:
|
// 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":
|
// each with C-string values of "foo", "bar", and "baz":
|
||||||
//
|
//
|
||||||
// const char* strings[] = {"foo", "bar", "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
|
// This instantiates tests from test case StlStringTest
|
||||||
// each with STL strings with values "a" and "b":
|
// 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.
|
// to std::string and C strings, it won't work for these types.
|
||||||
|
|
||||||
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
|
# 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; } \
|
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) { \
|
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
||||||
return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
|
return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
|
||||||
(__VA_ARGS__)(info); \
|
(__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(). \
|
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||||
GetTestCasePatternHolder<test_case_name>(\
|
GetTestCasePatternHolder<test_case_name>(\
|
||||||
#test_case_name, \
|
#test_case_name, \
|
||||||
|
@ -46,6 +46,10 @@
|
|||||||
// 2. operator<<(ostream&, const T&) defined in either foo or the
|
// 2. operator<<(ostream&, const T&) defined in either foo or the
|
||||||
// global namespace.
|
// 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
|
// 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
|
// the value if it is a protocol buffer, or print the raw bytes in the
|
||||||
// value otherwise.
|
// value otherwise.
|
||||||
@ -107,6 +111,11 @@
|
|||||||
# include <tuple>
|
# include <tuple>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GTEST_HAS_ABSL
|
||||||
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "absl/types/optional.h"
|
||||||
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
// Definitions in the 'internal' and 'internal2' name spaces are
|
// Definitions in the 'internal' and 'internal2' name spaces are
|
||||||
@ -125,7 +134,11 @@ enum TypeKind {
|
|||||||
kProtobuf, // a protobuf type
|
kProtobuf, // a protobuf type
|
||||||
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
|
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
|
||||||
// (e.g. a named or unnamed enum type)
|
// (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
|
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
|
||||||
@ -138,7 +151,7 @@ class TypeWithoutFormatter {
|
|||||||
// This default version is called when kTypeKind is kOtherType.
|
// This default version is called when kTypeKind is kOtherType.
|
||||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||||
PrintBytesInObjectTo(static_cast<const unsigned char*>(
|
PrintBytesInObjectTo(static_cast<const unsigned char*>(
|
||||||
reinterpret_cast<const void *>(&value)),
|
reinterpret_cast<const void*>(&value)),
|
||||||
sizeof(value), os);
|
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
|
// 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
|
// 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
|
// 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>
|
template <typename Char, typename CharTraits, typename T>
|
||||||
::std::basic_ostream<Char, CharTraits>& operator<<(
|
::std::basic_ostream<Char, CharTraits>& operator<<(
|
||||||
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
|
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
|
||||||
TypeWithoutFormatter<T,
|
TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
|
||||||
(internal::IsAProtocolMessage<T>::value ? kProtobuf :
|
? kProtobuf
|
||||||
internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?
|
: internal::ImplicitlyConvertible<
|
||||||
kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);
|
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;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,12 +463,8 @@ void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
|
|||||||
} else {
|
} else {
|
||||||
// T is a function type, so '*os << p' doesn't do what we want
|
// 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
|
// (it just prints p as bool). We want to print p as a const
|
||||||
// void*. However, we cannot cast it to const void* directly,
|
// void*.
|
||||||
// even using reinterpret_cast, as earlier versions of gcc
|
*os << reinterpret_cast<const void*>(p);
|
||||||
// (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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,17 +492,15 @@ void PrintTo(const T& value, ::std::ostream* os) {
|
|||||||
// DefaultPrintTo() is overloaded. The type of its first argument
|
// DefaultPrintTo() is overloaded. The type of its first argument
|
||||||
// determines which version will be picked.
|
// determines which version will be picked.
|
||||||
//
|
//
|
||||||
// Note that we check for recursive and other container types here, prior
|
// Note that we check for container types here, prior to we check
|
||||||
// to we check for protocol message types in our operator<<. The rationale is:
|
// for protocol message types in our operator<<. The rationale is:
|
||||||
//
|
//
|
||||||
// For protocol messages, we want to give people a chance to
|
// For protocol messages, we want to give people a chance to
|
||||||
// override Google Mock's format by defining a PrintTo() or
|
// override Google Mock's format by defining a PrintTo() or
|
||||||
// operator<<. For STL containers, other formats can be
|
// operator<<. For STL containers, other formats can be
|
||||||
// incompatible with Google Mock's format for the container
|
// incompatible with Google Mock's format for the container
|
||||||
// elements; therefore we check for container types here to ensure
|
// elements; therefore we check for container types here to ensure
|
||||||
// that our format is used. To prevent an infinite runtime recursion
|
// that our format is used.
|
||||||
// during the output of recursive container types, we check first for
|
|
||||||
// those.
|
|
||||||
//
|
//
|
||||||
// Note that MSVC and clang-cl do allow an implicit conversion from
|
// 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.
|
// 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
|
#else
|
||||||
: !internal::ImplicitlyConvertible<T, const void*>::value
|
: !internal::ImplicitlyConvertible<T, const void*>::value
|
||||||
#endif
|
#endif
|
||||||
? kPrintFunctionPointer
|
? kPrintFunctionPointer
|
||||||
: kPrintPointer>(),
|
: kPrintPointer>(),
|
||||||
value, os);
|
value, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,6 +627,13 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
|||||||
}
|
}
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#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_
|
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
||||||
// Helper function for printing a tuple. T must be instantiated with
|
// Helper function for printing a tuple. T must be instantiated with
|
||||||
// a tuple type.
|
// a tuple type.
|
||||||
@ -727,6 +763,26 @@ class UniversalPrinter {
|
|||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
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'
|
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||||
// elements, starting at address 'begin'.
|
// elements, starting at address 'begin'.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -873,7 +929,7 @@ void UniversalPrint(const T& value, ::std::ostream* os) {
|
|||||||
UniversalPrinter<T1>::Print(value, os);
|
UniversalPrinter<T1>::Print(value, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ::std::vector<string> Strings;
|
typedef ::std::vector< ::std::string> Strings;
|
||||||
|
|
||||||
// TuplePolicy<TupleT> must provide:
|
// TuplePolicy<TupleT> must provide:
|
||||||
// - tuple_size
|
// - tuple_size
|
||||||
@ -993,6 +1049,16 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
|||||||
|
|
||||||
} // namespace internal
|
} // 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>
|
template <typename T>
|
||||||
::std::string PrintToString(const T& value) {
|
::std::string PrintToString(const T& value) {
|
||||||
::std::stringstream ss;
|
::std::stringstream ss;
|
||||||
|
@ -243,7 +243,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
|||||||
} \
|
} \
|
||||||
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) \
|
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) \
|
||||||
GTEST_ATTRIBUTE_UNUSED_ = \
|
GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
|
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames( \
|
||||||
__FILE__, __LINE__, #__VA_ARGS__)
|
__FILE__, __LINE__, #__VA_ARGS__)
|
||||||
|
|
||||||
// The 'Types' template argument below must have spaces around it
|
// The 'Types' template argument below must have spaces around it
|
||||||
|
@ -115,6 +115,9 @@ GTEST_DECLARE_string_(output);
|
|||||||
// test.
|
// test.
|
||||||
GTEST_DECLARE_bool_(print_time);
|
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.
|
// This flag specifies the random number seed.
|
||||||
GTEST_DECLARE_int32_(random_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
|
// When this flag is specified, a failed assertion will throw an
|
||||||
// exception if exceptions are enabled, or exit the program with a
|
// 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);
|
GTEST_DECLARE_bool_(throw_on_failure);
|
||||||
|
|
||||||
// When this flag is set with a "host:port" string, on supported
|
// 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).
|
// Used in EXPECT_TRUE/FALSE(assertion_result).
|
||||||
AssertionResult(const AssertionResult& other);
|
AssertionResult(const AssertionResult& other);
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1910
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Used in the EXPECT_TRUE/FALSE(bool_expression).
|
// Used in the EXPECT_TRUE/FALSE(bool_expression).
|
||||||
//
|
//
|
||||||
@ -276,7 +281,9 @@ class GTEST_API_ AssertionResult {
|
|||||||
/*enabler*/ = NULL)
|
/*enabler*/ = NULL)
|
||||||
: success_(success) {}
|
: success_(success) {}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1910
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||||
|
#endif
|
||||||
|
|
||||||
// Assignment operator.
|
// Assignment operator.
|
||||||
AssertionResult& operator=(AssertionResult other) {
|
AssertionResult& operator=(AssertionResult other) {
|
||||||
@ -345,6 +352,15 @@ GTEST_API_ AssertionResult AssertionFailure();
|
|||||||
// Deprecated; use AssertionFailure() << msg.
|
// Deprecated; use AssertionFailure() << msg.
|
||||||
GTEST_API_ AssertionResult AssertionFailure(const Message& 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.
|
// The abstract class that all tests inherit from.
|
||||||
//
|
//
|
||||||
// In Google Test, a unit test program contains one or many TestCases, and
|
// 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.
|
// this for you.
|
||||||
//
|
//
|
||||||
// The only time you derive from Test is when defining a test fixture
|
// 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 {
|
// class FooTest : public testing::Test {
|
||||||
// protected:
|
// protected:
|
||||||
@ -550,9 +566,8 @@ class GTEST_API_ TestResult {
|
|||||||
// Returns the elapsed time, in milliseconds.
|
// Returns the elapsed time, in milliseconds.
|
||||||
TimeInMillis elapsed_time() const { return elapsed_time_; }
|
TimeInMillis elapsed_time() const { return elapsed_time_; }
|
||||||
|
|
||||||
// Returns the i-th test part result among all the results. i can range
|
// Returns the i-th test part result among all the results. i can range from 0
|
||||||
// from 0 to test_property_count() - 1. If i is not in that range, aborts
|
// to total_part_count() - 1. If i is not in that range, aborts the program.
|
||||||
// the program.
|
|
||||||
const TestPartResult& GetTestPartResult(int i) const;
|
const TestPartResult& GetTestPartResult(int i) const;
|
||||||
|
|
||||||
// Returns the i-th test property. i can range from 0 to
|
// 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.
|
// Returns the line where this test is defined.
|
||||||
int line() const { return location_.line; }
|
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
|
// 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
|
// disabled (or it is disabled but the also_run_disabled_tests flag has
|
||||||
// been specified) and its full name matches the user-specified filter.
|
// 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.
|
// Returns true iff this test will appear in the XML report.
|
||||||
bool is_reportable() const {
|
bool is_reportable() const {
|
||||||
// For now, the XML report includes all tests matching the filter.
|
// The XML report includes tests matching the filter, excluding those
|
||||||
// In the future, we may trim tests that are excluded because of
|
// run in other shards.
|
||||||
// sharding.
|
return matches_filter_ && !is_in_another_shard_;
|
||||||
return matches_filter_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the result of the test.
|
// Returns the result of the test.
|
||||||
@ -762,6 +779,7 @@ class GTEST_API_ TestInfo {
|
|||||||
bool is_disabled_; // True iff this test is disabled
|
bool is_disabled_; // True iff this test is disabled
|
||||||
bool matches_filter_; // True if this test matches the
|
bool matches_filter_; // True if this test matches the
|
||||||
// user-specified filter.
|
// user-specified filter.
|
||||||
|
bool is_in_another_shard_; // Will be run in another shard.
|
||||||
internal::TestFactoryBase* const factory_; // The factory that creates
|
internal::TestFactoryBase* const factory_; // The factory that creates
|
||||||
// the test object
|
// the test object
|
||||||
|
|
||||||
@ -986,6 +1004,18 @@ class Environment {
|
|||||||
virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
|
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 interface for tracing execution of tests. The methods are organized in
|
||||||
// the order the corresponding events are fired.
|
// the order the corresponding events are fired.
|
||||||
class TestEventListener {
|
class TestEventListener {
|
||||||
@ -1014,6 +1044,8 @@ class TestEventListener {
|
|||||||
virtual void OnTestStart(const TestInfo& test_info) = 0;
|
virtual void OnTestStart(const TestInfo& test_info) = 0;
|
||||||
|
|
||||||
// Fired after a failed assertion or a SUCCEED() invocation.
|
// 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;
|
virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
|
||||||
|
|
||||||
// Fired after the test ends.
|
// 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
|
// These classes and functions are friends as they need to access private
|
||||||
// members of UnitTest.
|
// members of UnitTest.
|
||||||
|
friend class ScopedTrace;
|
||||||
friend class Test;
|
friend class Test;
|
||||||
friend class internal::AssertHelper;
|
friend class internal::AssertHelper;
|
||||||
friend class internal::ScopedTrace;
|
|
||||||
friend class internal::StreamingListenerTest;
|
friend class internal::StreamingListenerTest;
|
||||||
friend class internal::UnitTestRecordPropertyTestHelper;
|
friend class internal::UnitTestRecordPropertyTestHelper;
|
||||||
friend Environment* AddGlobalTestEnvironment(Environment* env);
|
friend Environment* AddGlobalTestEnvironment(Environment* env);
|
||||||
@ -1778,7 +1810,6 @@ template <typename T>
|
|||||||
class TestWithParam : public Test, public WithParamInterface<T> {
|
class TestWithParam : public Test, public WithParamInterface<T> {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Macros for indicating success/failure in test code.
|
// Macros for indicating success/failure in test code.
|
||||||
|
|
||||||
// ADD_FAILURE unconditionally adds a failure to the current test.
|
// 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
|
// AssertionResult. For more information on how to use AssertionResult with
|
||||||
// these macros see comments on that class.
|
// these macros see comments on that class.
|
||||||
#define EXPECT_TRUE(condition) \
|
#define EXPECT_TRUE(condition) \
|
||||||
GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
|
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
|
||||||
GTEST_NONFATAL_FAILURE_)
|
GTEST_NONFATAL_FAILURE_)
|
||||||
#define EXPECT_FALSE(condition) \
|
#define EXPECT_FALSE(condition) \
|
||||||
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
|
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
|
||||||
GTEST_NONFATAL_FAILURE_)
|
GTEST_NONFATAL_FAILURE_)
|
||||||
#define ASSERT_TRUE(condition) \
|
#define ASSERT_TRUE(condition) \
|
||||||
GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
|
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
|
||||||
GTEST_FATAL_FAILURE_)
|
GTEST_FATAL_FAILURE_)
|
||||||
#define ASSERT_FALSE(condition) \
|
#define ASSERT_FALSE(condition) \
|
||||||
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
|
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
|
||||||
GTEST_FATAL_FAILURE_)
|
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.
|
// Macros for testing equalities and inequalities.
|
||||||
//
|
//
|
||||||
// * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2
|
// * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2
|
||||||
@ -1908,8 +1935,8 @@ class TestWithParam : public Test, public WithParamInterface<T> {
|
|||||||
//
|
//
|
||||||
// Examples:
|
// Examples:
|
||||||
//
|
//
|
||||||
// EXPECT_NE(5, Foo());
|
// EXPECT_NE(Foo(), 5);
|
||||||
// EXPECT_EQ(NULL, a_pointer);
|
// EXPECT_EQ(a_pointer, NULL);
|
||||||
// ASSERT_LT(i, array_size);
|
// ASSERT_LT(i, array_size);
|
||||||
// ASSERT_GT(records.size(), 0) << "There is no record left.";
|
// 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) \
|
#define EXPECT_NO_FATAL_FAILURE(statement) \
|
||||||
GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
|
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
|
// Causes a trace (including the source file path, the current line
|
||||||
// number, and the given message) to be included in every test failure
|
// number, and the given message) to be included in every test failure
|
||||||
// message generated by code in the current scope. The effect is
|
// 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
|
// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s
|
||||||
// to appear in the same block - as long as they are on different
|
// to appear in the same block - as long as they are on different
|
||||||
// lines.
|
// 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) \
|
#define SCOPED_TRACE(message) \
|
||||||
::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
|
::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
|
||||||
__FILE__, __LINE__, ::testing::Message() << (message))
|
__FILE__, __LINE__, (message))
|
||||||
|
|
||||||
|
|
||||||
// Compile-time assertion for type equality.
|
// Compile-time assertion for type equality.
|
||||||
// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
|
// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
|
||||||
@ -2203,8 +2286,8 @@ bool StaticAssertTypeEq() {
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// TEST_F(FooTest, ReturnsElementCountCorrectly) {
|
// TEST_F(FooTest, ReturnsElementCountCorrectly) {
|
||||||
// EXPECT_EQ(0, a_.size());
|
// EXPECT_EQ(a_.size(), 0);
|
||||||
// EXPECT_EQ(1, b_.size());
|
// EXPECT_EQ(b_.size(), 1);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#define TEST_F(test_fixture, test_name)\
|
#define TEST_F(test_fixture, test_name)\
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// 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!
|
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||||
//
|
//
|
||||||
// Implements a family of generic predicate assertion macros.
|
// Implements a family of generic predicate assertion macros.
|
||||||
@ -35,10 +35,9 @@
|
|||||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||||
#define 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.
|
#include "gtest/gtest.h"
|
||||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
|
|
||||||
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
|
namespace testing {
|
||||||
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
|
|
||||||
|
|
||||||
// This header implements a family of generic predicate assertion
|
// This header implements a family of generic predicate assertion
|
||||||
// macros:
|
// macros:
|
||||||
@ -66,8 +65,6 @@
|
|||||||
// We also define the EXPECT_* variations.
|
// We also define the EXPECT_* variations.
|
||||||
//
|
//
|
||||||
// For now we only support predicates whose arity is at most 5.
|
// 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
|
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
||||||
// in this file reduce. Don't use this in your code.
|
// 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_
|
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||||
|
@ -40,17 +40,20 @@
|
|||||||
//
|
//
|
||||||
// class MyClass {
|
// class MyClass {
|
||||||
// private:
|
// private:
|
||||||
// void MyMethod();
|
// void PrivateMethod();
|
||||||
// FRIEND_TEST(MyClassTest, MyMethod);
|
// FRIEND_TEST(MyClassTest, PrivateMethodWorks);
|
||||||
// };
|
// };
|
||||||
//
|
//
|
||||||
// class MyClassTest : public testing::Test {
|
// class MyClassTest : public testing::Test {
|
||||||
// // ...
|
// // ...
|
||||||
// };
|
// };
|
||||||
//
|
//
|
||||||
// TEST_F(MyClassTest, MyMethod) {
|
// TEST_F(MyClassTest, PrivateMethodWorks) {
|
||||||
// // Can call MyClass::MyMethod() here.
|
// // 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)\
|
#define FRIEND_TEST(test_case_name, test_name)\
|
||||||
friend class test_case_name##_##test_name##_Test
|
friend class test_case_name##_##test_name##_Test
|
||||||
|
@ -61,6 +61,9 @@
|
|||||||
// GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
|
// GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
|
||||||
// GTEST_LOCK_EXCLUDED_(locks)
|
// GTEST_LOCK_EXCLUDED_(locks)
|
||||||
//
|
//
|
||||||
|
// Underlying library support features:
|
||||||
|
// GTEST_HAS_CXXABI_H_
|
||||||
|
//
|
||||||
// Exporting API symbols:
|
// Exporting API symbols:
|
||||||
// GTEST_API_ - Specifier for exported symbols.
|
// GTEST_API_ - Specifier for exported symbols.
|
||||||
//
|
//
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// 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)
|
// The Google C++ Testing Framework (Google Test)
|
||||||
//
|
//
|
||||||
@ -264,53 +263,6 @@ class InternalRunDeathTestFlag {
|
|||||||
// the flag is specified; otherwise returns NULL.
|
// the flag is specified; otherwise returns NULL.
|
||||||
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
|
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
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -27,14 +27,13 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
// Author: keith.ray@gmail.com (Keith Ray)
|
|
||||||
//
|
//
|
||||||
// Google Test filepath utilities
|
// Google Test filepath utilities
|
||||||
//
|
//
|
||||||
// This header file declares classes and functions used internally by
|
// This header file declares classes and functions used internally by
|
||||||
// Google Test. They are subject to change without notice.
|
// 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!
|
// Do not include this header file separately!
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// 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)
|
// The Google C++ Testing Framework (Google Test)
|
||||||
//
|
//
|
||||||
@ -61,8 +60,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/gtest-message.h"
|
#include "gtest/gtest-message.h"
|
||||||
#include "gtest/internal/gtest-string.h"
|
|
||||||
#include "gtest/internal/gtest-filepath.h"
|
#include "gtest/internal/gtest-filepath.h"
|
||||||
|
#include "gtest/internal/gtest-string.h"
|
||||||
#include "gtest/internal/gtest-type-util.h"
|
#include "gtest/internal/gtest-type-util.h"
|
||||||
|
|
||||||
// Due to C++ preprocessor weirdness, we need double indirection to
|
// Due to C++ preprocessor weirdness, we need double indirection to
|
||||||
@ -96,7 +95,6 @@ template <typename T>
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
struct TraceInfo; // Information about a trace point.
|
struct TraceInfo; // Information about a trace point.
|
||||||
class ScopedTrace; // Implements scoped trace.
|
|
||||||
class TestInfoImpl; // Opaque implementation of TestInfo
|
class TestInfoImpl; // Opaque implementation of TestInfo
|
||||||
class UnitTestImpl; // Opaque implementation of UnitTest
|
class UnitTestImpl; // Opaque implementation of UnitTest
|
||||||
|
|
||||||
@ -152,30 +150,11 @@ class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {
|
|||||||
|
|
||||||
#endif // GTEST_HAS_EXCEPTIONS
|
#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 {
|
namespace edit_distance {
|
||||||
// Returns the optimal edits to go from 'left' to 'right'.
|
// Returns the optimal edits to go from 'left' to 'right'.
|
||||||
// All edits cost the same, with replace having lower priority than
|
// All edits cost the same, with replace having lower priority than
|
||||||
// add/remove.
|
// 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
|
// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
|
||||||
enum EditType { kMatch, kAdd, kRemove, kReplace };
|
enum EditType { kMatch, kAdd, kRemove, kReplace };
|
||||||
GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
|
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
|
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
||||||
// length of Types.
|
// length of Types.
|
||||||
static bool Register(const char* prefix,
|
static bool Register(const char* prefix,
|
||||||
CodeLocation code_location,
|
const CodeLocation& code_location,
|
||||||
const char* case_name, const char* test_names,
|
const char* case_name, const char* test_names,
|
||||||
int index) {
|
int index) {
|
||||||
typedef typename Types::Head Type;
|
typedef typename Types::Head Type;
|
||||||
@ -659,7 +638,7 @@ class TypeParameterizedTest {
|
|||||||
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
||||||
class TypeParameterizedTest<Fixture, TestSel, Types0> {
|
class TypeParameterizedTest<Fixture, TestSel, Types0> {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* /*prefix*/, CodeLocation,
|
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
||||||
const char* /*case_name*/, const char* /*test_names*/,
|
const char* /*case_name*/, const char* /*test_names*/,
|
||||||
int /*index*/) {
|
int /*index*/) {
|
||||||
return true;
|
return true;
|
||||||
@ -705,7 +684,7 @@ class TypeParameterizedTestCase {
|
|||||||
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
||||||
class TypeParameterizedTestCase<Fixture, Templates0, Types> {
|
class TypeParameterizedTestCase<Fixture, Templates0, Types> {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* /*prefix*/, CodeLocation,
|
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
||||||
const TypedTestCasePState* /*state*/,
|
const TypedTestCasePState* /*state*/,
|
||||||
const char* /*case_name*/, const char* /*test_names*/) {
|
const char* /*case_name*/, const char* /*test_names*/) {
|
||||||
return true;
|
return true;
|
||||||
@ -824,31 +803,6 @@ struct RemoveConst<T[N]> {
|
|||||||
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
|
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
|
||||||
GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(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
|
// ImplicitlyConvertible<From, To>::value is a compile-time bool
|
||||||
// constant that's true iff type From can be implicitly converted to
|
// constant that's true iff type From can be implicitly converted to
|
||||||
// type To.
|
// type To.
|
||||||
@ -1096,7 +1050,7 @@ class NativeArray {
|
|||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper<
|
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.
|
// Initializes this object with a copy of the input.
|
||||||
|
@ -3203,7 +3203,7 @@ class CartesianProductGenerator2
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -3235,7 +3235,7 @@ class CartesianProductGenerator2
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType(*current1_, *current2_);
|
current_value_.reset(new ParamType(*current1_, *current2_));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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 begin2_;
|
||||||
const typename ParamGenerator<T2>::iterator end2_;
|
const typename ParamGenerator<T2>::iterator end2_;
|
||||||
typename ParamGenerator<T2>::iterator current2_;
|
typename ParamGenerator<T2>::iterator current2_;
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator2::Iterator
|
}; // class CartesianProductGenerator2::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
@ -3326,7 +3326,7 @@ class CartesianProductGenerator3
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -3362,7 +3362,7 @@ class CartesianProductGenerator3
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType(*current1_, *current2_, *current3_);
|
current_value_.reset(new ParamType(*current1_, *current2_, *current3_));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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 begin3_;
|
||||||
const typename ParamGenerator<T3>::iterator end3_;
|
const typename ParamGenerator<T3>::iterator end3_;
|
||||||
typename ParamGenerator<T3>::iterator current3_;
|
typename ParamGenerator<T3>::iterator current3_;
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator3::Iterator
|
}; // class CartesianProductGenerator3::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
@ -3467,7 +3467,7 @@ class CartesianProductGenerator4
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -3507,8 +3507,8 @@ class CartesianProductGenerator4
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||||
*current4_);
|
*current4_));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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 begin4_;
|
||||||
const typename ParamGenerator<T4>::iterator end4_;
|
const typename ParamGenerator<T4>::iterator end4_;
|
||||||
typename ParamGenerator<T4>::iterator current4_;
|
typename ParamGenerator<T4>::iterator current4_;
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator4::Iterator
|
}; // class CartesianProductGenerator4::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
@ -3625,7 +3625,7 @@ class CartesianProductGenerator5
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -3669,8 +3669,8 @@ class CartesianProductGenerator5
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||||
*current4_, *current5_);
|
*current4_, *current5_));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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 begin5_;
|
||||||
const typename ParamGenerator<T5>::iterator end5_;
|
const typename ParamGenerator<T5>::iterator end5_;
|
||||||
typename ParamGenerator<T5>::iterator current5_;
|
typename ParamGenerator<T5>::iterator current5_;
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator5::Iterator
|
}; // class CartesianProductGenerator5::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
@ -3802,7 +3802,7 @@ class CartesianProductGenerator6
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -3850,8 +3850,8 @@ class CartesianProductGenerator6
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||||
*current4_, *current5_, *current6_);
|
*current4_, *current5_, *current6_));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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 begin6_;
|
||||||
const typename ParamGenerator<T6>::iterator end6_;
|
const typename ParamGenerator<T6>::iterator end6_;
|
||||||
typename ParamGenerator<T6>::iterator current6_;
|
typename ParamGenerator<T6>::iterator current6_;
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator6::Iterator
|
}; // class CartesianProductGenerator6::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
@ -3996,7 +3996,7 @@ class CartesianProductGenerator7
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -4048,8 +4048,8 @@ class CartesianProductGenerator7
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||||
*current4_, *current5_, *current6_, *current7_);
|
*current4_, *current5_, *current6_, *current7_));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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 begin7_;
|
||||||
const typename ParamGenerator<T7>::iterator end7_;
|
const typename ParamGenerator<T7>::iterator end7_;
|
||||||
typename ParamGenerator<T7>::iterator current7_;
|
typename ParamGenerator<T7>::iterator current7_;
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator7::Iterator
|
}; // class CartesianProductGenerator7::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
@ -4209,7 +4209,7 @@ class CartesianProductGenerator8
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -4265,8 +4265,8 @@ class CartesianProductGenerator8
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||||
*current4_, *current5_, *current6_, *current7_, *current8_);
|
*current4_, *current5_, *current6_, *current7_, *current8_));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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 begin8_;
|
||||||
const typename ParamGenerator<T8>::iterator end8_;
|
const typename ParamGenerator<T8>::iterator end8_;
|
||||||
typename ParamGenerator<T8>::iterator current8_;
|
typename ParamGenerator<T8>::iterator current8_;
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator8::Iterator
|
}; // class CartesianProductGenerator8::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
@ -4438,7 +4438,7 @@ class CartesianProductGenerator9
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -4498,9 +4498,9 @@ class CartesianProductGenerator9
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||||
*current4_, *current5_, *current6_, *current7_, *current8_,
|
*current4_, *current5_, *current6_, *current7_, *current8_,
|
||||||
*current9_);
|
*current9_));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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 begin9_;
|
||||||
const typename ParamGenerator<T9>::iterator end9_;
|
const typename ParamGenerator<T9>::iterator end9_;
|
||||||
typename ParamGenerator<T9>::iterator current9_;
|
typename ParamGenerator<T9>::iterator current9_;
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator9::Iterator
|
}; // class CartesianProductGenerator9::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
@ -4685,7 +4685,7 @@ class CartesianProductGenerator10
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -4749,9 +4749,9 @@ class CartesianProductGenerator10
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType(*current1_, *current2_, *current3_,
|
current_value_.reset(new ParamType(*current1_, *current2_, *current3_,
|
||||||
*current4_, *current5_, *current6_, *current7_, *current8_,
|
*current4_, *current5_, *current6_, *current7_, *current8_,
|
||||||
*current9_, *current10_);
|
*current9_, *current10_));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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 begin10_;
|
||||||
const typename ParamGenerator<T10>::iterator end10_;
|
const typename ParamGenerator<T10>::iterator end10_;
|
||||||
typename ParamGenerator<T10>::iterator current10_;
|
typename ParamGenerator<T10>::iterator current10_;
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator10::Iterator
|
}; // class CartesianProductGenerator10::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
|
@ -160,7 +160,7 @@ $for k [[
|
|||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||||
return new Iterator(*this);
|
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 {
|
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
@ -192,7 +192,7 @@ $for k [[
|
|||||||
|
|
||||||
void ComputeCurrentValue() {
|
void ComputeCurrentValue() {
|
||||||
if (!AtEnd())
|
if (!AtEnd())
|
||||||
current_value_ = ParamType($for j, [[*current$(j)_]]);
|
current_value_.reset(new ParamType($for j, [[*current$(j)_]]));
|
||||||
}
|
}
|
||||||
bool AtEnd() const {
|
bool AtEnd() const {
|
||||||
// We must report iterator past the end of the range when either of the
|
// 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)_;
|
typename ParamGenerator<T$j>::iterator current$(j)_;
|
||||||
]]
|
]]
|
||||||
|
|
||||||
ParamType current_value_;
|
linked_ptr<ParamType> current_value_;
|
||||||
}; // class CartesianProductGenerator$i::Iterator
|
}; // class CartesianProductGenerator$i::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
|
@ -54,6 +54,9 @@
|
|||||||
# define GTEST_OS_WINDOWS_PHONE 1
|
# define GTEST_OS_WINDOWS_PHONE 1
|
||||||
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
# define GTEST_OS_WINDOWS_RT 1
|
# 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
|
# else
|
||||||
// WINAPI_FAMILY defined but no known partition matched.
|
// WINAPI_FAMILY defined but no known partition matched.
|
||||||
// Default to desktop.
|
// Default to desktop.
|
||||||
|
@ -73,11 +73,9 @@
|
|||||||
// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions
|
// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions
|
||||||
// are enabled.
|
// are enabled.
|
||||||
// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string
|
// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string
|
||||||
// is/isn't available (some systems define
|
// is/isn't available
|
||||||
// ::string, which is different to std::string).
|
// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::wstring
|
||||||
// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
|
// is/isn't available
|
||||||
// is/isn't available (some systems define
|
|
||||||
// ::wstring, which is different to std::wstring).
|
|
||||||
// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular
|
// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular
|
||||||
// expressions are/aren't available.
|
// expressions are/aren't available.
|
||||||
// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h>
|
// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h>
|
||||||
@ -109,6 +107,12 @@
|
|||||||
// GTEST_CREATE_SHARED_LIBRARY
|
// GTEST_CREATE_SHARED_LIBRARY
|
||||||
// - Define to 1 when compiling Google Test itself
|
// - Define to 1 when compiling Google Test itself
|
||||||
// as a shared library.
|
// 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
|
// Platform-indicating macros
|
||||||
// --------------------------
|
// --------------------------
|
||||||
@ -178,7 +182,7 @@
|
|||||||
// GTEST_HAS_POSIX_RE (see above) which users can
|
// GTEST_HAS_POSIX_RE (see above) which users can
|
||||||
// define themselves.
|
// define themselves.
|
||||||
// GTEST_USES_SIMPLE_RE - our own simple regex is used;
|
// 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().
|
// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
|
||||||
|
|
||||||
// Misc public macros
|
// Misc public macros
|
||||||
@ -207,6 +211,7 @@
|
|||||||
//
|
//
|
||||||
// C++11 feature wrappers:
|
// C++11 feature wrappers:
|
||||||
//
|
//
|
||||||
|
// testing::internal::forward - portability wrapper for std::forward.
|
||||||
// testing::internal::move - portability wrapper for std::move.
|
// testing::internal::move - portability wrapper for std::move.
|
||||||
//
|
//
|
||||||
// Synchronization:
|
// Synchronization:
|
||||||
@ -272,10 +277,12 @@
|
|||||||
# include <TargetConditionals.h>
|
# include <TargetConditionals.h>
|
||||||
#endif
|
#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 <algorithm> // NOLINT
|
||||||
#include <iostream> // NOLINT
|
#include <iostream> // NOLINT
|
||||||
#include <sstream> // NOLINT
|
#include <sstream> // NOLINT
|
||||||
#include <string> // NOLINT
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector> // NOLINT
|
#include <vector> // NOLINT
|
||||||
|
|
||||||
@ -464,8 +471,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
#ifndef GTEST_HAS_EXCEPTIONS
|
#ifndef GTEST_HAS_EXCEPTIONS
|
||||||
// The user didn't tell us whether exceptions are enabled, so we need
|
// The user didn't tell us whether exceptions are enabled, so we need
|
||||||
// to figure it out.
|
// to figure it out.
|
||||||
# if defined(_MSC_VER) || defined(__BORLANDC__)
|
# if defined(_MSC_VER) && defined(_CPPUNWIND)
|
||||||
// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
|
// 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.
|
// macro to enable exceptions, so we'll do the same.
|
||||||
// Assumes that exceptions are enabled by default.
|
// Assumes that exceptions are enabled by default.
|
||||||
# ifndef _HAS_EXCEPTIONS
|
# 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 disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
|
||||||
// to your compiler flags.
|
// to your compiler flags.
|
||||||
#define GTEST_HAS_PTHREAD \
|
#define GTEST_HAS_PTHREAD \
|
||||||
(GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
|
(GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
|
||||||
GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA)
|
GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA)
|
||||||
#endif // GTEST_HAS_PTHREAD
|
#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
|
// 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
|
// abort() in a VC 7.1 application compiled as GUI in debug config
|
||||||
// pops up a dialog window that cannot be suppressed programmatically.
|
// pops up a dialog window that cannot be suppressed programmatically.
|
||||||
#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
|
#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
|
||||||
(GTEST_OS_MAC && !GTEST_OS_IOS) || \
|
(GTEST_OS_MAC && !GTEST_OS_IOS) || \
|
||||||
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
|
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
|
||||||
GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
|
GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
|
||||||
GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NETBSD)
|
GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NETBSD)
|
||||||
# define GTEST_HAS_DEATH_TEST 1
|
# define GTEST_HAS_DEATH_TEST 1
|
||||||
@ -824,10 +834,11 @@ using ::std::tuple_size;
|
|||||||
# define GTEST_HAS_TYPED_TEST_P 1
|
# define GTEST_HAS_TYPED_TEST_P 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Determines whether to support Combine().
|
// Determines whether to support Combine(). This only makes sense when
|
||||||
// The implementation doesn't work on Sun Studio since it doesn't
|
// value-parameterized tests are enabled. The implementation doesn't
|
||||||
// understand templated conversion operators.
|
// work on Sun Studio since it doesn't understand templated conversion
|
||||||
#if GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
|
// operators.
|
||||||
|
#if (GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_) && !defined(__SUNPRO_CC)
|
||||||
# define GTEST_HAS_COMBINE 1
|
# define GTEST_HAS_COMBINE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -879,7 +890,7 @@ using ::std::tuple_size;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Use this annotation before a function that takes a printf format string.
|
// 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)
|
# if defined(__MINGW_PRINTF_FORMAT)
|
||||||
// MinGW has two different printf implementations. Ensure the format macro
|
// MinGW has two different printf implementations. Ensure the format macro
|
||||||
// matches the selected implementation. See
|
// matches the selected implementation. See
|
||||||
@ -972,6 +983,10 @@ using ::std::tuple_size;
|
|||||||
# define GTEST_API_
|
# define GTEST_API_
|
||||||
#endif // 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__
|
#ifdef __GNUC__
|
||||||
// Ask the compiler to never inline a given function.
|
// Ask the compiler to never inline a given function.
|
||||||
# define GTEST_NO_INLINE_ __attribute__((noinline))
|
# define GTEST_NO_INLINE_ __attribute__((noinline))
|
||||||
@ -980,7 +995,7 @@ using ::std::tuple_size;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.
|
// _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
|
# define GTEST_HAS_CXXABI_H_ 1
|
||||||
#else
|
#else
|
||||||
# define GTEST_HAS_CXXABI_H_ 0
|
# define GTEST_HAS_CXXABI_H_ 0
|
||||||
@ -1126,6 +1141,16 @@ struct StaticAssertTypeEqHelper<T, T> {
|
|||||||
enum { value = true };
|
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'.
|
// Evaluates to the number of elements in 'array'.
|
||||||
#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
|
#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
|
||||||
|
|
||||||
@ -1189,6 +1214,10 @@ class scoped_ptr {
|
|||||||
|
|
||||||
// Defines RE.
|
// 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
|
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
|
||||||
// Regular Expression syntax.
|
// Regular Expression syntax.
|
||||||
class GTEST_API_ RE {
|
class GTEST_API_ RE {
|
||||||
@ -1200,11 +1229,11 @@ class GTEST_API_ RE {
|
|||||||
// Constructs an RE from a string.
|
// Constructs an RE from a string.
|
||||||
RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT
|
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
|
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(const char* regex) { Init(regex); } // NOLINT
|
||||||
~RE();
|
~RE();
|
||||||
@ -1226,7 +1255,7 @@ class GTEST_API_ RE {
|
|||||||
return PartialMatch(str.c_str(), 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) {
|
static bool FullMatch(const ::string& str, const RE& re) {
|
||||||
return FullMatch(str.c_str(), re);
|
return FullMatch(str.c_str(), re);
|
||||||
@ -1235,7 +1264,7 @@ class GTEST_API_ RE {
|
|||||||
return PartialMatch(str.c_str(), 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 FullMatch(const char* str, const RE& re);
|
||||||
static bool PartialMatch(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_;
|
const char* pattern_;
|
||||||
bool is_valid_;
|
bool is_valid_;
|
||||||
|
|
||||||
#if GTEST_USES_POSIX_RE
|
# if GTEST_USES_POSIX_RE
|
||||||
|
|
||||||
regex_t full_regex_; // For FullMatch().
|
regex_t full_regex_; // For FullMatch().
|
||||||
regex_t partial_regex_; // For PartialMatch().
|
regex_t partial_regex_; // For PartialMatch().
|
||||||
|
|
||||||
#else // GTEST_USES_SIMPLE_RE
|
# else // GTEST_USES_SIMPLE_RE
|
||||||
|
|
||||||
const char* full_pattern_; // For FullMatch();
|
const char* full_pattern_; // For FullMatch();
|
||||||
|
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(RE);
|
GTEST_DISALLOW_ASSIGN_(RE);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // GTEST_USES_PCRE
|
||||||
|
|
||||||
// Formats a source file path and a line number as they would appear
|
// 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.
|
// in an error message from the compiler used to compile this code.
|
||||||
GTEST_API_ ::std::string FormatFileLocation(const char* file, int line);
|
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_LOG_(FATAL) << #posix_call << "failed with error " \
|
||||||
<< gtest_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_
|
#if GTEST_HAS_STD_MOVE_
|
||||||
|
using std::forward;
|
||||||
using std::move;
|
using std::move;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct RvalueRef {
|
||||||
|
typedef T&& type;
|
||||||
|
};
|
||||||
#else // GTEST_HAS_STD_MOVE_
|
#else // GTEST_HAS_STD_MOVE_
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const T& move(const T& t) {
|
const T& move(const T& t) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct RvalueRef {
|
||||||
|
typedef const T& type;
|
||||||
|
};
|
||||||
#endif // GTEST_HAS_STD_MOVE_
|
#endif // GTEST_HAS_STD_MOVE_
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
@ -1455,7 +1530,6 @@ GTEST_API_ void CaptureStderr();
|
|||||||
GTEST_API_ std::string GetCapturedStderr();
|
GTEST_API_ std::string GetCapturedStderr();
|
||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
|
|
||||||
// Returns the size (in bytes) of a file.
|
// Returns the size (in bytes) of a file.
|
||||||
GTEST_API_ size_t GetFileSize(FILE* file);
|
GTEST_API_ size_t GetFileSize(FILE* file);
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// 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)
|
// The Google C++ Testing Framework (Google Test)
|
||||||
//
|
//
|
||||||
@ -35,7 +34,8 @@
|
|||||||
// Google Test. They are subject to change without notice. They should not used
|
// Google Test. They are subject to change without notice. They should not used
|
||||||
// by code external to Google Test.
|
// 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.
|
// It should not be #included by other files.
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
#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);
|
::std::fill(is_prime_, is_prime_ + is_prime_size_, true);
|
||||||
is_prime_[0] = is_prime_[1] = false;
|
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;
|
if (!is_prime_[i]) continue;
|
||||||
|
|
||||||
// Marks all multiples of i (except i itself) as non-prime.
|
// 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;
|
is_prime_[j] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,12 @@
|
|||||||
//
|
//
|
||||||
// Author: wan@google.com (Zhanyong Wan)
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include "sample4.h"
|
#include "sample4.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Tests the Increment() method.
|
// Tests the Increment() method.
|
||||||
|
|
||||||
TEST(Counter, Increment) {
|
TEST(Counter, Increment) {
|
||||||
Counter c;
|
Counter c;
|
||||||
|
|
||||||
@ -43,4 +45,5 @@ TEST(Counter, Increment) {
|
|||||||
EXPECT_EQ(1, c.Increment());
|
EXPECT_EQ(1, c.Increment());
|
||||||
EXPECT_EQ(2, c.Increment());
|
EXPECT_EQ(2, c.Increment());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -46,9 +46,9 @@
|
|||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "sample3-inl.h"
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "sample1.h"
|
#include "sample1.h"
|
||||||
|
#include "sample3-inl.h"
|
||||||
namespace {
|
namespace {
|
||||||
// In this sample, we want to ensure that every test finishes within
|
// 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
|
// ~5 seconds. If a test takes longer to run, we consider it a
|
||||||
|
@ -66,22 +66,18 @@
|
|||||||
|
|
||||||
#include "gtest/gtest-message.h"
|
#include "gtest/gtest-message.h"
|
||||||
#include "gtest/internal/gtest-string.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"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
// Constants.
|
// Constants.
|
||||||
|
|
||||||
// The default death test style.
|
// 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_(
|
GTEST_DEFINE_string_(
|
||||||
death_test_style,
|
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 propagated back to the parent process. Otherwise, the
|
||||||
// message is simply printed to stderr. In either case, the program
|
// message is simply printed to stderr. In either case, the program
|
||||||
// then exits with status 1.
|
// 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
|
// 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
|
// death test child process, which operates on a very small stack. Use
|
||||||
// the heap for any additional non-minuscule memory requirements.
|
// the heap for any additional non-minuscule memory requirements.
|
||||||
@ -563,7 +559,13 @@ bool DeathTestImpl::Passed(bool status_ok) {
|
|||||||
break;
|
break;
|
||||||
case DIED:
|
case DIED:
|
||||||
if (status_ok) {
|
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());
|
const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
|
||||||
|
# endif // GTEST_USES_PCRE
|
||||||
if (matched) {
|
if (matched) {
|
||||||
success = true;
|
success = true;
|
||||||
} else {
|
} else {
|
||||||
@ -985,6 +987,7 @@ static int ExecDeathTestChildMain(void* child_arg) {
|
|||||||
}
|
}
|
||||||
# endif // !GTEST_OS_QNX
|
# endif // !GTEST_OS_QNX
|
||||||
|
|
||||||
|
# if GTEST_HAS_CLONE
|
||||||
// Two utility routines that together determine the direction the stack
|
// Two utility routines that together determine the direction the stack
|
||||||
// grows.
|
// grows.
|
||||||
// This could be accomplished more elegantly by a single recursive
|
// 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
|
// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
|
||||||
// StackLowerThanAddress into StackGrowsDown, which then doesn't give
|
// StackLowerThanAddress into StackGrowsDown, which then doesn't give
|
||||||
// correct answer.
|
// correct answer.
|
||||||
void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_;
|
static void StackLowerThanAddress(const void* ptr,
|
||||||
void StackLowerThanAddress(const void* ptr, bool* result) {
|
bool* result) GTEST_NO_INLINE_;
|
||||||
|
static void StackLowerThanAddress(const void* ptr, bool* result) {
|
||||||
int dummy;
|
int dummy;
|
||||||
*result = (&dummy < ptr);
|
*result = (&dummy < ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure AddressSanitizer does not tamper with the stack here.
|
// Make sure AddressSanitizer does not tamper with the stack here.
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||||
bool StackGrowsDown() {
|
static bool StackGrowsDown() {
|
||||||
int dummy;
|
int dummy;
|
||||||
bool result;
|
bool result;
|
||||||
StackLowerThanAddress(&dummy, &result);
|
StackLowerThanAddress(&dummy, &result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
# endif // GTEST_HAS_CLONE
|
||||||
|
|
||||||
// Spawns a child process with the same executable as the current process in
|
// 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
|
// 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,
|
// Recreates the pipe and event handles from the provided parameters,
|
||||||
// signals the event, and returns a file descriptor wrapped around the pipe
|
// signals the event, and returns a file descriptor wrapped around the pipe
|
||||||
// handle. This function is called in the child process only.
|
// 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 write_handle_as_size_t,
|
||||||
size_t event_handle_as_size_t) {
|
size_t event_handle_as_size_t) {
|
||||||
AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
|
AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
|
||||||
|
@ -26,14 +26,12 @@
|
|||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// 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-filepath.h"
|
||||||
#include "gtest/internal/gtest-port.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
#include "gtest/gtest-message.h"
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS_MOBILE
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
@ -48,6 +46,8 @@
|
|||||||
# include <climits> // Some Linux distributions define PATH_MAX here.
|
# include <climits> // Some Linux distributions define PATH_MAX here.
|
||||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-string.h"
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS
|
#if GTEST_OS_WINDOWS
|
||||||
# define GTEST_PATH_MAX_ _MAX_PATH
|
# define GTEST_PATH_MAX_ _MAX_PATH
|
||||||
#elif defined(PATH_MAX)
|
#elif defined(PATH_MAX)
|
||||||
@ -58,8 +58,6 @@
|
|||||||
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
|
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
#include "gtest/internal/gtest-string.h"
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@ -130,7 +128,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const {
|
|||||||
return *this;
|
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
|
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||||
// separators. Returns NULL if no path separator was found.
|
// separators. Returns NULL if no path separator was found.
|
||||||
const char* FilePath::FindLastPathSeparator() const {
|
const char* FilePath::FindLastPathSeparator() const {
|
||||||
|
@ -37,14 +37,6 @@
|
|||||||
#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
|
#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
|
||||||
#define 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
|
#ifndef _WIN32_WCE
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
#endif // !_WIN32_WCE
|
#endif // !_WIN32_WCE
|
||||||
@ -67,7 +59,7 @@
|
|||||||
# include <windows.h> // NOLINT
|
# include <windows.h> // NOLINT
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
#include "gtest/gtest.h" // NOLINT
|
#include "gtest/gtest.h"
|
||||||
#include "gtest/gtest-spi.h"
|
#include "gtest/gtest-spi.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@ -94,6 +86,7 @@ const char kFilterFlag[] = "filter";
|
|||||||
const char kListTestsFlag[] = "list_tests";
|
const char kListTestsFlag[] = "list_tests";
|
||||||
const char kOutputFlag[] = "output";
|
const char kOutputFlag[] = "output";
|
||||||
const char kPrintTimeFlag[] = "print_time";
|
const char kPrintTimeFlag[] = "print_time";
|
||||||
|
const char kPrintUTF8Flag[] = "print_utf8";
|
||||||
const char kRandomSeedFlag[] = "random_seed";
|
const char kRandomSeedFlag[] = "random_seed";
|
||||||
const char kRepeatFlag[] = "repeat";
|
const char kRepeatFlag[] = "repeat";
|
||||||
const char kShuffleFlag[] = "shuffle";
|
const char kShuffleFlag[] = "shuffle";
|
||||||
@ -174,6 +167,7 @@ class GTestFlagSaver {
|
|||||||
list_tests_ = GTEST_FLAG(list_tests);
|
list_tests_ = GTEST_FLAG(list_tests);
|
||||||
output_ = GTEST_FLAG(output);
|
output_ = GTEST_FLAG(output);
|
||||||
print_time_ = GTEST_FLAG(print_time);
|
print_time_ = GTEST_FLAG(print_time);
|
||||||
|
print_utf8_ = GTEST_FLAG(print_utf8);
|
||||||
random_seed_ = GTEST_FLAG(random_seed);
|
random_seed_ = GTEST_FLAG(random_seed);
|
||||||
repeat_ = GTEST_FLAG(repeat);
|
repeat_ = GTEST_FLAG(repeat);
|
||||||
shuffle_ = GTEST_FLAG(shuffle);
|
shuffle_ = GTEST_FLAG(shuffle);
|
||||||
@ -195,6 +189,7 @@ class GTestFlagSaver {
|
|||||||
GTEST_FLAG(list_tests) = list_tests_;
|
GTEST_FLAG(list_tests) = list_tests_;
|
||||||
GTEST_FLAG(output) = output_;
|
GTEST_FLAG(output) = output_;
|
||||||
GTEST_FLAG(print_time) = print_time_;
|
GTEST_FLAG(print_time) = print_time_;
|
||||||
|
GTEST_FLAG(print_utf8) = print_utf8_;
|
||||||
GTEST_FLAG(random_seed) = random_seed_;
|
GTEST_FLAG(random_seed) = random_seed_;
|
||||||
GTEST_FLAG(repeat) = repeat_;
|
GTEST_FLAG(repeat) = repeat_;
|
||||||
GTEST_FLAG(shuffle) = shuffle_;
|
GTEST_FLAG(shuffle) = shuffle_;
|
||||||
@ -216,6 +211,7 @@ class GTestFlagSaver {
|
|||||||
bool list_tests_;
|
bool list_tests_;
|
||||||
std::string output_;
|
std::string output_;
|
||||||
bool print_time_;
|
bool print_time_;
|
||||||
|
bool print_utf8_;
|
||||||
internal::Int32 random_seed_;
|
internal::Int32 random_seed_;
|
||||||
internal::Int32 repeat_;
|
internal::Int32 repeat_;
|
||||||
bool shuffle_;
|
bool shuffle_;
|
||||||
@ -1028,7 +1024,7 @@ class TestResultAccessor {
|
|||||||
#if GTEST_CAN_STREAM_RESULTS_
|
#if GTEST_CAN_STREAM_RESULTS_
|
||||||
|
|
||||||
// Streams test results to the given port on the given host machine.
|
// Streams test results to the given port on the given host machine.
|
||||||
class GTEST_API_ StreamingListener : public EmptyTestEventListener {
|
class StreamingListener : public EmptyTestEventListener {
|
||||||
public:
|
public:
|
||||||
// Abstract base class for writing strings to a socket.
|
// Abstract base class for writing strings to a socket.
|
||||||
class AbstractSocketWriter {
|
class AbstractSocketWriter {
|
||||||
|
@ -67,15 +67,7 @@
|
|||||||
#include "gtest/gtest-message.h"
|
#include "gtest/gtest-message.h"
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
#include "gtest/internal/gtest-string.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"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -671,7 +663,7 @@ bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function used by ValidateRegex() to format error messages.
|
// 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
|
return (Message() << "Syntax error at index " << index
|
||||||
<< " in simple regular expression \"" << regex << "\": ").GetString();
|
<< " in simple regular expression \"" << regex << "\": ").GetString();
|
||||||
}
|
}
|
||||||
@ -923,6 +915,7 @@ GTestLog::~GTestLog() {
|
|||||||
posix::Abort();
|
posix::Abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable Microsoft deprecation warnings for POSIX functions called from
|
// Disable Microsoft deprecation warnings for POSIX functions called from
|
||||||
// this class (creat, dup, dup2, and close)
|
// this class (creat, dup, dup2, and close)
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
|
||||||
@ -1015,7 +1008,8 @@ static CapturedStream* g_captured_stderr = NULL;
|
|||||||
static CapturedStream* g_captured_stdout = NULL;
|
static CapturedStream* g_captured_stdout = NULL;
|
||||||
|
|
||||||
// Starts capturing an output stream (stdout/stderr).
|
// 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) {
|
if (*stream != NULL) {
|
||||||
GTEST_LOG_(FATAL) << "Only one " << stream_name
|
GTEST_LOG_(FATAL) << "Only one " << stream_name
|
||||||
<< " capturer can exist at a time.";
|
<< " 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.
|
// 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();
|
const std::string content = (*captured_stream)->GetCapturedString();
|
||||||
|
|
||||||
delete *captured_stream;
|
delete *captured_stream;
|
||||||
@ -1055,6 +1049,10 @@ std::string GetCapturedStderr() {
|
|||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
size_t GetFileSize(FILE* file) {
|
size_t GetFileSize(FILE* file) {
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
return static_cast<size_t>(ftell(file));
|
return static_cast<size_t>(ftell(file));
|
||||||
|
@ -43,12 +43,13 @@
|
|||||||
// defines Foo.
|
// defines Foo.
|
||||||
|
|
||||||
#include "gtest/gtest-printers.h"
|
#include "gtest/gtest-printers.h"
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <cctype>
|
||||||
#include <cwchar>
|
#include <cwchar>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
#include "src/gtest-internal-inl.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
@ -123,7 +124,7 @@ namespace internal {
|
|||||||
// Depending on the value of a char (or wchar_t), we print it in one
|
// Depending on the value of a char (or wchar_t), we print it in one
|
||||||
// of three formats:
|
// of three formats:
|
||||||
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
|
// - 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').
|
// - as a special escape sequence (e.g. '\r', '\n').
|
||||||
enum CharFormat {
|
enum CharFormat {
|
||||||
kAsIs,
|
kAsIs,
|
||||||
@ -230,7 +231,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
|
|||||||
return;
|
return;
|
||||||
*os << " (" << static_cast<int>(c);
|
*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
|
// unless c was already printed in the form '\x##' or the code is in
|
||||||
// [1, 9].
|
// [1, 9].
|
||||||
if (format == kHexEscape || (1 <= c && c <= 9)) {
|
if (format == kHexEscape || (1 <= c && c <= 9)) {
|
||||||
@ -262,11 +263,12 @@ template <typename CharType>
|
|||||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
||||||
static void PrintCharsAsStringTo(
|
static CharFormat PrintCharsAsStringTo(
|
||||||
const CharType* begin, size_t len, ostream* os) {
|
const CharType* begin, size_t len, ostream* os) {
|
||||||
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
|
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
|
||||||
*os << kQuoteBegin;
|
*os << kQuoteBegin;
|
||||||
bool is_previous_hex = false;
|
bool is_previous_hex = false;
|
||||||
|
CharFormat print_format = kAsIs;
|
||||||
for (size_t index = 0; index < len; ++index) {
|
for (size_t index = 0; index < len; ++index) {
|
||||||
const CharType cur = begin[index];
|
const CharType cur = begin[index];
|
||||||
if (is_previous_hex && IsXDigit(cur)) {
|
if (is_previous_hex && IsXDigit(cur)) {
|
||||||
@ -276,8 +278,13 @@ static void PrintCharsAsStringTo(
|
|||||||
*os << "\" " << kQuoteBegin;
|
*os << "\" " << kQuoteBegin;
|
||||||
}
|
}
|
||||||
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
|
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
|
||||||
|
// Remember if any characters required hex escaping.
|
||||||
|
if (is_previous_hex) {
|
||||||
|
print_format = kHexEscape;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*os << "\"";
|
*os << "\"";
|
||||||
|
return print_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
// 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
|
#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.
|
// Prints a ::string object.
|
||||||
#if GTEST_HAS_GLOBAL_STRING
|
#if GTEST_HAS_GLOBAL_STRING
|
||||||
void PrintStringTo(const ::string& s, ostream* os) {
|
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
|
#endif // GTEST_HAS_GLOBAL_STRING
|
||||||
|
|
||||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
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.
|
// Prints a ::wstring object.
|
||||||
|
@ -32,15 +32,7 @@
|
|||||||
// The Google C++ Testing Framework (Google Test)
|
// The Google C++ Testing Framework (Google Test)
|
||||||
|
|
||||||
#include "gtest/gtest-test-part.h"
|
#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"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
// Author: wan@google.com (Zhanyong Wan)
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
#include "gtest/gtest-typed-test.h"
|
#include "gtest/gtest-typed-test.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
@ -133,14 +133,7 @@
|
|||||||
# include <sys/types.h> // NOLINT
|
# include <sys/types.h> // NOLINT
|
||||||
#endif
|
#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"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS
|
#if GTEST_OS_WINDOWS
|
||||||
# define vsnprintf _vsnprintf
|
# define vsnprintf _vsnprintf
|
||||||
@ -167,8 +160,10 @@ static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
|
|||||||
// A test filter that matches everything.
|
// A test filter that matches everything.
|
||||||
static const char kUniversalFilter[] = "*";
|
static const char kUniversalFilter[] = "*";
|
||||||
|
|
||||||
// The default output file for XML output.
|
// The default output format.
|
||||||
static const char kDefaultOutputFile[] = "test_detail.xml";
|
static const char kDefaultOutputFormat[] = "xml";
|
||||||
|
// The default output file.
|
||||||
|
static const char kDefaultOutputFile[] = "test_detail";
|
||||||
|
|
||||||
// The environment variable name for the test shard index.
|
// The environment variable name for the test shard index.
|
||||||
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
|
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
|
||||||
@ -238,9 +233,9 @@ GTEST_DEFINE_bool_(list_tests, false,
|
|||||||
GTEST_DEFINE_string_(
|
GTEST_DEFINE_string_(
|
||||||
output,
|
output,
|
||||||
internal::StringFromGTestEnv("output", ""),
|
internal::StringFromGTestEnv("output", ""),
|
||||||
"A format (currently must be \"xml\"), optionally followed "
|
"A format (defaults to \"xml\" but can be specified to be \"json\"), "
|
||||||
"by a colon and an output file name or directory. A directory "
|
"optionally followed by a colon and an output file name or directory. "
|
||||||
"is indicated by a trailing pathname separator. "
|
"A directory is indicated by a trailing pathname separator. "
|
||||||
"Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
|
"Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
|
||||||
"If a directory is specified, output files will be created "
|
"If a directory is specified, output files will be created "
|
||||||
"within that directory, with file-names based on the test "
|
"within that directory, with file-names based on the test "
|
||||||
@ -253,6 +248,12 @@ GTEST_DEFINE_bool_(
|
|||||||
"True iff " GTEST_NAME_
|
"True iff " GTEST_NAME_
|
||||||
" should display elapsed time in text output.");
|
" 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_(
|
GTEST_DEFINE_int32_(
|
||||||
random_seed,
|
random_seed,
|
||||||
internal::Int32FromGTestEnv("random_seed", 0),
|
internal::Int32FromGTestEnv("random_seed", 0),
|
||||||
@ -294,7 +295,7 @@ GTEST_DEFINE_bool_(
|
|||||||
internal::BoolFromGTestEnv("throw_on_failure", false),
|
internal::BoolFromGTestEnv("throw_on_failure", false),
|
||||||
"When this flag is specified, a failed assertion will throw an exception "
|
"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 "
|
"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_
|
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
GTEST_DEFINE_string_(
|
GTEST_DEFINE_string_(
|
||||||
@ -429,12 +430,17 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
|||||||
if (gtest_output_flag == NULL)
|
if (gtest_output_flag == NULL)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
std::string format = GetOutputFormat();
|
||||||
|
if (format.empty())
|
||||||
|
format = std::string(kDefaultOutputFormat);
|
||||||
|
|
||||||
const char* const colon = strchr(gtest_output_flag, ':');
|
const char* const colon = strchr(gtest_output_flag, ':');
|
||||||
if (colon == NULL)
|
if (colon == NULL)
|
||||||
return internal::FilePath::ConcatPaths(
|
return internal::FilePath::MakeFileName(
|
||||||
internal::FilePath(
|
internal::FilePath(
|
||||||
UnitTest::GetInstance()->original_working_dir()),
|
UnitTest::GetInstance()->original_working_dir()),
|
||||||
internal::FilePath(kDefaultOutputFile)).string();
|
internal::FilePath(kDefaultOutputFile), 0,
|
||||||
|
format.c_str()).string();
|
||||||
|
|
||||||
internal::FilePath output_name(colon + 1);
|
internal::FilePath output_name(colon + 1);
|
||||||
if (!output_name.IsAbsolutePath())
|
if (!output_name.IsAbsolutePath())
|
||||||
@ -629,12 +635,12 @@ extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();
|
|||||||
// This predicate-formatter checks that 'results' contains a test part
|
// This predicate-formatter checks that 'results' contains a test part
|
||||||
// failure of the given type and that the failure message contains the
|
// failure of the given type and that the failure message contains the
|
||||||
// given substring.
|
// given substring.
|
||||||
AssertionResult HasOneFailure(const char* /* results_expr */,
|
static AssertionResult HasOneFailure(const char* /* results_expr */,
|
||||||
const char* /* type_expr */,
|
const char* /* type_expr */,
|
||||||
const char* /* substr_expr */,
|
const char* /* substr_expr */,
|
||||||
const TestPartResultArray& results,
|
const TestPartResultArray& results,
|
||||||
TestPartResult::Type type,
|
TestPartResult::Type type,
|
||||||
const std::string& substr) {
|
const std::string& substr) {
|
||||||
const std::string expected(type == TestPartResult::kFatalFailure ?
|
const std::string expected(type == TestPartResult::kFatalFailure ?
|
||||||
"1 fatal failure" :
|
"1 fatal failure" :
|
||||||
"1 non-fatal failure");
|
"1 non-fatal failure");
|
||||||
@ -1662,7 +1668,7 @@ namespace {
|
|||||||
AssertionResult HRESULTFailureHelper(const char* expr,
|
AssertionResult HRESULTFailureHelper(const char* expr,
|
||||||
const char* expected,
|
const char* expected,
|
||||||
long hr) { // NOLINT
|
long hr) { // NOLINT
|
||||||
# if GTEST_OS_WINDOWS_MOBILE
|
# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE
|
||||||
|
|
||||||
// Windows CE doesn't support FormatMessage.
|
// Windows CE doesn't support FormatMessage.
|
||||||
const char error_text[] = "";
|
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
|
// Utility functions for encoding Unicode text (wide strings) in
|
||||||
// UTF-8.
|
// 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:
|
// like this:
|
||||||
//
|
//
|
||||||
// Code-point length Encoding
|
// Code-point length Encoding
|
||||||
@ -2137,8 +2143,9 @@ static std::string FormatWordList(const std::vector<std::string>& words) {
|
|||||||
return word_list.GetString();
|
return word_list.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValidateTestPropertyName(const std::string& property_name,
|
static bool ValidateTestPropertyName(
|
||||||
const std::vector<std::string>& reserved_names) {
|
const std::string& property_name,
|
||||||
|
const std::vector<std::string>& reserved_names) {
|
||||||
if (std::find(reserved_names.begin(), reserved_names.end(), property_name) !=
|
if (std::find(reserved_names.begin(), reserved_names.end(), property_name) !=
|
||||||
reserved_names.end()) {
|
reserved_names.end()) {
|
||||||
ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name
|
ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name
|
||||||
@ -2435,6 +2442,8 @@ Result HandleExceptionsInMethodIfSupported(
|
|||||||
#if GTEST_HAS_EXCEPTIONS
|
#if GTEST_HAS_EXCEPTIONS
|
||||||
try {
|
try {
|
||||||
return HandleSehExceptionsInMethodIfSupported(object, method, location);
|
return HandleSehExceptionsInMethodIfSupported(object, method, location);
|
||||||
|
} catch (const AssertionException&) { // NOLINT
|
||||||
|
// This failure was reported already.
|
||||||
} catch (const internal::GoogleTestFailureException&) { // NOLINT
|
} catch (const internal::GoogleTestFailureException&) { // NOLINT
|
||||||
// This exception type can only be thrown by a failed Google
|
// This exception type can only be thrown by a failed Google
|
||||||
// Test assertion with the intention of letting another testing
|
// 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"
|
<< "probably rename one of the classes to put the tests into different\n"
|
||||||
<< "test cases.";
|
<< "test cases.";
|
||||||
|
|
||||||
GTEST_LOG_(ERROR)
|
GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(),
|
||||||
<< FormatFileLocation(code_location.file.c_str(),
|
code_location.line)
|
||||||
code_location.line)
|
<< " " << errors.GetString();
|
||||||
<< " " << errors.GetString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -2883,7 +2890,7 @@ enum GTestColor {
|
|||||||
!GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW
|
!GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW
|
||||||
|
|
||||||
// Returns the character attribute for the given color.
|
// Returns the character attribute for the given color.
|
||||||
WORD GetColorAttribute(GTestColor color) {
|
static WORD GetColorAttribute(GTestColor color) {
|
||||||
switch (color) {
|
switch (color) {
|
||||||
case COLOR_RED: return FOREGROUND_RED;
|
case COLOR_RED: return FOREGROUND_RED;
|
||||||
case COLOR_GREEN: return FOREGROUND_GREEN;
|
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;
|
if (color_mask == 0) return 0;
|
||||||
|
|
||||||
int bitOffset = 0;
|
int bitOffset = 0;
|
||||||
while((color_mask & 1) == 0) {
|
while ((color_mask & 1) == 0) {
|
||||||
color_mask >>= 1;
|
color_mask >>= 1;
|
||||||
++bitOffset;
|
++bitOffset;
|
||||||
}
|
}
|
||||||
return 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
|
// Let's reuse the BG
|
||||||
static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
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;
|
static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||||
@ -2923,7 +2930,7 @@ WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
|
|||||||
|
|
||||||
// Returns the ANSI color code for the given color. COLOR_DEFAULT is
|
// Returns the ANSI color code for the given color. COLOR_DEFAULT is
|
||||||
// an invalid input.
|
// an invalid input.
|
||||||
const char* GetAnsiColorCode(GTestColor color) {
|
static const char* GetAnsiColorCode(GTestColor color) {
|
||||||
switch (color) {
|
switch (color) {
|
||||||
case COLOR_RED: return "1";
|
case COLOR_RED: return "1";
|
||||||
case COLOR_GREEN: return "2";
|
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
|
// This routine must actually emit the characters rather than return a string
|
||||||
// that would be colored when printed, as can be done on Linux.
|
// that would be colored when printed, as can be done on Linux.
|
||||||
GTEST_ATTRIBUTE_PRINTF_(2, 3)
|
GTEST_ATTRIBUTE_PRINTF_(2, 3)
|
||||||
void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
||||||
@ -3030,7 +3037,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
|||||||
static const char kTypeParamLabel[] = "TypeParam";
|
static const char kTypeParamLabel[] = "TypeParam";
|
||||||
static const char kValueParamLabel[] = "GetParam()";
|
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 type_param = test_info.type_param();
|
||||||
const char* const value_param = test_info.value_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",
|
"Note: Randomizing tests' orders with a seed of %d .\n",
|
||||||
unit_test.random_seed());
|
unit_test.random_seed());
|
||||||
}
|
}
|
||||||
|
|
||||||
ColoredPrintf(COLOR_GREEN, "[==========] ");
|
ColoredPrintf(COLOR_GREEN, "[==========] ");
|
||||||
printf("Running %s from %s.\n",
|
printf("Running %s from %s.\n",
|
||||||
FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
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,
|
// 3. To interpret the meaning of errno in a thread-safe way,
|
||||||
// we need the strerror_r() function, which is not available on
|
// we need the strerror_r() function, which is not available on
|
||||||
// Windows.
|
// Windows.
|
||||||
GTEST_LOG_(FATAL) << "Unable to open file \""
|
|
||||||
<< output_file_ << "\"";
|
GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file_ << "\"";
|
||||||
}
|
}
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
PrintXmlUnitTest(&stream, unit_test);
|
PrintXmlUnitTest(&stream, unit_test);
|
||||||
@ -3771,6 +3777,352 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
|
|||||||
|
|
||||||
// End XmlUnitTestResultPrinter
|
// 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_
|
#if GTEST_CAN_STREAM_RESULTS_
|
||||||
|
|
||||||
// Checks if str contains '=', '&', '%' or '\n' characters. If yes,
|
// Checks if str contains '=', '&', '%' or '\n' characters. If yes,
|
||||||
@ -3841,27 +4193,6 @@ void StreamingListener::SocketWriter::MakeConnection() {
|
|||||||
// End of class Streaming Listener
|
// End of class Streaming Listener
|
||||||
#endif // GTEST_CAN_STREAM_RESULTS__
|
#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
|
// class OsStackTraceGetter
|
||||||
|
|
||||||
const char* const OsStackTraceGetterInterface::kElidedFramesMarker =
|
const char* const OsStackTraceGetterInterface::kElidedFramesMarker =
|
||||||
@ -4418,10 +4749,12 @@ void UnitTestImpl::ConfigureXmlOutput() {
|
|||||||
if (output_format == "xml") {
|
if (output_format == "xml") {
|
||||||
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
|
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
|
||||||
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
|
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
|
||||||
|
} else if (output_format == "json") {
|
||||||
|
listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter(
|
||||||
|
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
|
||||||
} else if (output_format != "") {
|
} else if (output_format != "") {
|
||||||
GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
|
GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
|
||||||
<< output_format
|
<< output_format << "\" ignored.";
|
||||||
<< "\" ignored.";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4436,8 +4769,7 @@ void UnitTestImpl::ConfigureStreamingOutput() {
|
|||||||
listeners()->Append(new StreamingListener(target.substr(0, pos),
|
listeners()->Append(new StreamingListener(target.substr(0, pos),
|
||||||
target.substr(pos+1)));
|
target.substr(pos+1)));
|
||||||
} else {
|
} else {
|
||||||
GTEST_LOG_(WARNING) << "unrecognized streaming target \""
|
GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target
|
||||||
<< target
|
|
||||||
<< "\" ignored.";
|
<< "\" ignored.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4840,10 +5172,11 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
|||||||
(GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
|
(GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
|
||||||
matches_filter;
|
matches_filter;
|
||||||
|
|
||||||
const bool is_selected = is_runnable &&
|
const bool is_in_another_shard =
|
||||||
(shard_tests == IGNORE_SHARDING_PROTOCOL ||
|
shard_tests != IGNORE_SHARDING_PROTOCOL &&
|
||||||
ShouldRunTestOnShard(total_shards, shard_index,
|
!ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests);
|
||||||
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_runnable_tests += is_runnable;
|
||||||
num_selected_tests += is_selected;
|
num_selected_tests += is_selected;
|
||||||
@ -5028,9 +5361,9 @@ bool SkipPrefix(const char* prefix, const char** pstr) {
|
|||||||
// part can be omitted.
|
// part can be omitted.
|
||||||
//
|
//
|
||||||
// Returns the value of the flag, or NULL if the parsing failed.
|
// Returns the value of the flag, or NULL if the parsing failed.
|
||||||
const char* ParseFlagValue(const char* str,
|
static const char* ParseFlagValue(const char* str,
|
||||||
const char* flag,
|
const char* flag,
|
||||||
bool def_optional) {
|
bool def_optional) {
|
||||||
// str and flag must not be NULL.
|
// str and flag must not be NULL.
|
||||||
if (str == NULL || flag == NULL) return 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
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// 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.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseFlagValue(str, flag, true);
|
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
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// 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.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseFlagValue(str, flag, false);
|
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"
|
" Enable/disable colored output. The default is @Gauto@D.\n"
|
||||||
" @G--" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
|
" @G--" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
|
||||||
" Don't print the elapsed time of each test.\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"
|
GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
|
||||||
" Generate an XML report in the given directory or with the given file\n"
|
" Generate a JSON or XML report in the given directory or with the given\n"
|
||||||
" name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\n"
|
" file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
|
||||||
#if GTEST_CAN_STREAM_RESULTS_
|
#if GTEST_CAN_STREAM_RESULTS_
|
||||||
" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n"
|
" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n"
|
||||||
" Stream test results to the given server.\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"
|
" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
|
||||||
" Turn assertion failures into debugger break-points.\n"
|
" Turn assertion failures into debugger break-points.\n"
|
||||||
" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\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"
|
" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n"
|
||||||
" Do not report exceptions as test failures. Instead, allow them\n"
|
" Do not report exceptions as test failures. Instead, allow them\n"
|
||||||
" to crash the program or throw a pop-up (on Windows).\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"
|
"(not one in your own code or tests), please report it to\n"
|
||||||
"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
|
"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
|
||||||
|
|
||||||
bool ParseGoogleTestFlag(const char* const arg) {
|
static bool ParseGoogleTestFlag(const char* const arg) {
|
||||||
return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
|
return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
|
||||||
>EST_FLAG(also_run_disabled_tests)) ||
|
>EST_FLAG(also_run_disabled_tests)) ||
|
||||||
ParseBoolFlag(arg, kBreakOnFailureFlag,
|
ParseBoolFlag(arg, kBreakOnFailureFlag,
|
||||||
@ -5254,6 +5590,7 @@ bool ParseGoogleTestFlag(const char* const arg) {
|
|||||||
ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) ||
|
ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) ||
|
||||||
ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) ||
|
ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) ||
|
||||||
ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) ||
|
ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) ||
|
||||||
|
ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) ||
|
||||||
ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) ||
|
ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) ||
|
||||||
ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) ||
|
ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) ||
|
||||||
ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) ||
|
ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) ||
|
||||||
@ -5266,11 +5603,10 @@ bool ParseGoogleTestFlag(const char* const arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
#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");
|
FILE* flagfile = posix::FOpen(path.c_str(), "r");
|
||||||
if (!flagfile) {
|
if (!flagfile) {
|
||||||
GTEST_LOG_(FATAL) << "Unable to open file \""
|
GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile)
|
||||||
<< GTEST_FLAG(flagfile)
|
|
||||||
<< "\"";
|
<< "\"";
|
||||||
}
|
}
|
||||||
std::string contents(ReadEntireFile(flagfile));
|
std::string contents(ReadEntireFile(flagfile));
|
||||||
@ -5401,8 +5737,9 @@ void InitGoogleTest(int* argc, wchar_t** argv) {
|
|||||||
|
|
||||||
std::string TempDir() {
|
std::string TempDir() {
|
||||||
#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
|
#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
|
||||||
return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
|
return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS_MOBILE
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
return "\\temp\\";
|
return "\\temp\\";
|
||||||
#elif GTEST_OS_WINDOWS
|
#elif GTEST_OS_WINDOWS
|
||||||
@ -5420,4 +5757,23 @@ std::string TempDir() {
|
|||||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
#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
|
} // namespace testing
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
GTEST_API_ int main(int argc, char **argv) {
|
GTEST_API_ int main(int argc, char **argv) {
|
||||||
|
@ -57,13 +57,15 @@ cc_test(
|
|||||||
"gtest-param-test_test.cc",
|
"gtest-param-test_test.cc",
|
||||||
],
|
],
|
||||||
) + select({
|
) + select({
|
||||||
"//:win": [],
|
"//:windows": [],
|
||||||
|
"//:windows_msvc": [],
|
||||||
"//conditions:default": [
|
"//conditions:default": [
|
||||||
"gtest-tuple_test.cc",
|
"gtest-tuple_test.cc",
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
copts = select({
|
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"],
|
"//conditions:default": ["-DGTEST_USE_OWN_TR1_TUPLE=1"],
|
||||||
}),
|
}),
|
||||||
includes = [
|
includes = [
|
||||||
@ -73,7 +75,8 @@ cc_test(
|
|||||||
"googletest/test",
|
"googletest/test",
|
||||||
],
|
],
|
||||||
linkopts = select({
|
linkopts = select({
|
||||||
"//:win": [],
|
"//:windows": [],
|
||||||
|
"//:windows_msvc": [],
|
||||||
"//conditions:default": [
|
"//conditions:default": [
|
||||||
"-pthread",
|
"-pthread",
|
||||||
],
|
],
|
||||||
@ -116,3 +119,262 @@ cc_test(
|
|||||||
"//:gtest",
|
"//: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
|
# endif // GTEST_OS_LINUX
|
||||||
|
|
||||||
# include "gtest/gtest-spi.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"
|
# include "src/gtest-internal-inl.h"
|
||||||
# undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
namespace posix = ::testing::internal::posix;
|
namespace posix = ::testing::internal::posix;
|
||||||
|
|
||||||
@ -313,14 +305,14 @@ void DieWithEmbeddedNul() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# if GTEST_USES_PCRE
|
# if GTEST_USES_PCRE
|
||||||
|
|
||||||
// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error
|
// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error
|
||||||
// message has a NUL character in it.
|
// message has a NUL character in it.
|
||||||
TEST_F(TestForDeathTest, EmbeddedNulInMessage) {
|
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");
|
EXPECT_DEATH(DieWithEmbeddedNul(), "my null world");
|
||||||
ASSERT_DEATH(DieWithEmbeddedNul(), "my null world");
|
ASSERT_DEATH(DieWithEmbeddedNul(), "my null world");
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif // GTEST_USES_PCRE
|
# endif // GTEST_USES_PCRE
|
||||||
|
|
||||||
// Tests that death test macros expand to code which interacts well with switch
|
// 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) {
|
TEST_F(TestForDeathTest, TestExpectDebugDeath) {
|
||||||
int sideeffect = 0;
|
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";
|
<< "Must accept a streamed message";
|
||||||
|
|
||||||
# ifdef NDEBUG
|
# ifdef NDEBUG
|
||||||
|
@ -27,28 +27,18 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
// Authors: keith.ray@gmail.com (Keith Ray)
|
|
||||||
//
|
//
|
||||||
// Google Test filepath utilities
|
// Google Test filepath utilities
|
||||||
//
|
//
|
||||||
// This file tests classes and functions used internally by
|
// This file tests classes and functions used internally by
|
||||||
// Google Test. They are subject to change without notice.
|
// Google Test. They are subject to change without notice.
|
||||||
//
|
//
|
||||||
// This file is #included from gtest_unittest.cc, to avoid changing
|
// This file is #included from gtest-internal.h.
|
||||||
// build or make-files for some existing Google Test clients. Do not
|
// Do not #include this file anywhere else!
|
||||||
// #include this file anywhere else!
|
|
||||||
|
|
||||||
#include "gtest/internal/gtest-filepath.h"
|
#include "gtest/internal/gtest-filepath.h"
|
||||||
#include "gtest/gtest.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"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS_MOBILE
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
# include <windows.h> // NOLINT
|
# include <windows.h> // NOLINT
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
// Authors: keith.ray@gmail.com (Keith Ray)
|
|
||||||
//
|
//
|
||||||
// Google Test UnitTestOptions tests
|
// Google Test UnitTestOptions tests
|
||||||
//
|
//
|
||||||
@ -46,14 +45,7 @@
|
|||||||
# include <direct.h>
|
# include <direct.h>
|
||||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
#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"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -33,8 +33,7 @@
|
|||||||
// Google Test work.
|
// Google Test work.
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "gtest-param-test_test.h"
|
||||||
#include "test/gtest-param-test_test.h"
|
|
||||||
|
|
||||||
using ::testing::Values;
|
using ::testing::Values;
|
||||||
using ::testing::internal::ParamGenerator;
|
using ::testing::internal::ParamGenerator;
|
||||||
@ -59,3 +58,4 @@ INSTANTIATE_TEST_CASE_P(MultiplesOf33,
|
|||||||
INSTANTIATE_TEST_CASE_P(Sequence2,
|
INSTANTIATE_TEST_CASE_P(Sequence2,
|
||||||
InstantiationInMultipleTranslaionUnitsTest,
|
InstantiationInMultipleTranslaionUnitsTest,
|
||||||
Values(42*3, 42*4, 42*5));
|
Values(42*3, 42*4, 42*5));
|
||||||
|
|
||||||
|
@ -42,11 +42,7 @@
|
|||||||
# include <string>
|
# include <string>
|
||||||
# include <vector>
|
# include <vector>
|
||||||
|
|
||||||
// To include gtest-internal-inl.h.
|
|
||||||
# define GTEST_IMPLEMENTATION_ 1
|
|
||||||
# include "src/gtest-internal-inl.h" // for UnitTestOptions
|
# include "src/gtest-internal-inl.h" // for UnitTestOptions
|
||||||
# undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
# include "test/gtest-param-test_test.h"
|
# include "test/gtest-param-test_test.h"
|
||||||
|
|
||||||
using ::std::vector;
|
using ::std::vector;
|
||||||
@ -540,6 +536,51 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) {
|
|||||||
VerifyGenerator(gen, expected_values);
|
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
|
# endif // GTEST_HAS_COMBINE
|
||||||
|
|
||||||
// Tests that an generator produces correct sequence after being
|
// Tests that an generator produces correct sequence after being
|
||||||
@ -815,8 +856,8 @@ class CustomFunctorNamingTest : public TestWithParam<std::string> {};
|
|||||||
TEST_P(CustomFunctorNamingTest, CustomTestNames) {}
|
TEST_P(CustomFunctorNamingTest, CustomTestNames) {}
|
||||||
|
|
||||||
struct CustomParamNameFunctor {
|
struct CustomParamNameFunctor {
|
||||||
std::string operator()(const ::testing::TestParamInfo<std::string>& info) {
|
std::string operator()(const ::testing::TestParamInfo<std::string>& inf) {
|
||||||
return info.param;
|
return inf.param;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -833,8 +874,8 @@ INSTANTIATE_TEST_CASE_P(AllAllowedCharacters,
|
|||||||
CustomParamNameFunctor());
|
CustomParamNameFunctor());
|
||||||
|
|
||||||
inline std::string CustomParamNameFunction(
|
inline std::string CustomParamNameFunction(
|
||||||
const ::testing::TestParamInfo<std::string>& info) {
|
const ::testing::TestParamInfo<std::string>& inf) {
|
||||||
return info.param;
|
return inf.param;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomFunctionNamingTest : public TestWithParam<std::string> {};
|
class CustomFunctionNamingTest : public TestWithParam<std::string> {};
|
||||||
@ -852,11 +893,10 @@ INSTANTIATE_TEST_CASE_P(CustomParamNameFunction,
|
|||||||
class CustomLambdaNamingTest : public TestWithParam<std::string> {};
|
class CustomLambdaNamingTest : public TestWithParam<std::string> {};
|
||||||
TEST_P(CustomLambdaNamingTest, CustomTestNames) {}
|
TEST_P(CustomLambdaNamingTest, CustomTestNames) {}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(CustomParamNameLambda,
|
INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest,
|
||||||
CustomLambdaNamingTest,
|
|
||||||
Values(std::string("LambdaName")),
|
Values(std::string("LambdaName")),
|
||||||
[](const ::testing::TestParamInfo<std::string>& tpinfo) {
|
[](const ::testing::TestParamInfo<std::string>& inf) {
|
||||||
return tpinfo.param;
|
return inf.param;
|
||||||
});
|
});
|
||||||
|
|
||||||
#endif // GTEST_LANG_CXX11
|
#endif // GTEST_LANG_CXX11
|
||||||
@ -1023,6 +1063,7 @@ TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
|
|||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5));
|
INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5));
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
// Used in TestGenerationTest test case.
|
// Used in TestGenerationTest test case.
|
||||||
AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
|
AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
|
||||||
|
@ -45,15 +45,7 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "gtest/gtest-spi.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"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
using std::make_pair;
|
using std::make_pair;
|
||||||
using std::pair;
|
using std::pair;
|
||||||
@ -75,8 +67,8 @@ TEST(IsXDigitTest, WorksForNarrowAscii) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) {
|
TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) {
|
||||||
EXPECT_FALSE(IsXDigit('\x80'));
|
EXPECT_FALSE(IsXDigit(static_cast<char>(0x80)));
|
||||||
EXPECT_FALSE(IsXDigit(static_cast<char>('0' | '\x80')));
|
EXPECT_FALSE(IsXDigit(static_cast<char>('0' | 0x80)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(IsXDigitTest, WorksForWideAscii) {
|
TEST(IsXDigitTest, WorksForWideAscii) {
|
||||||
|
@ -52,13 +52,13 @@
|
|||||||
|
|
||||||
// hash_map and hash_set are available under Visual C++, or on Linux.
|
// hash_map and hash_set are available under Visual C++, or on Linux.
|
||||||
#if GTEST_HAS_UNORDERED_MAP_
|
#if GTEST_HAS_UNORDERED_MAP_
|
||||||
# include <unordered_map> // NOLINT
|
# include <unordered_map> // NOLINT
|
||||||
#elif GTEST_HAS_HASH_MAP_
|
#elif GTEST_HAS_HASH_MAP_
|
||||||
# include <hash_map> // NOLINT
|
# include <hash_map> // NOLINT
|
||||||
#endif // GTEST_HAS_HASH_MAP_
|
#endif // GTEST_HAS_HASH_MAP_
|
||||||
|
|
||||||
#if GTEST_HAS_UNORDERED_SET_
|
#if GTEST_HAS_UNORDERED_SET_
|
||||||
# include <unordered_set> // NOLINT
|
# include <unordered_set> // NOLINT
|
||||||
#elif GTEST_HAS_HASH_SET_
|
#elif GTEST_HAS_HASH_SET_
|
||||||
# include <hash_set> // NOLINT
|
# include <hash_set> // NOLINT
|
||||||
#endif // GTEST_HAS_HASH_SET_
|
#endif // GTEST_HAS_HASH_SET_
|
||||||
@ -197,8 +197,7 @@ inline ::std::ostream& operator<<(::std::ostream& os,
|
|||||||
// boost::filesystem::path.
|
// boost::filesystem::path.
|
||||||
class PathLike {
|
class PathLike {
|
||||||
public:
|
public:
|
||||||
struct iterator
|
struct iterator {
|
||||||
{
|
|
||||||
typedef PathLike value_type;
|
typedef PathLike value_type;
|
||||||
};
|
};
|
||||||
typedef iterator const_iterator;
|
typedef iterator const_iterator;
|
||||||
@ -208,9 +207,7 @@ class PathLike {
|
|||||||
iterator begin() const { return iterator(); }
|
iterator begin() const { return iterator(); }
|
||||||
iterator end() const { return iterator(); }
|
iterator end() const { return iterator(); }
|
||||||
|
|
||||||
friend
|
friend ::std::ostream& operator<<(::std::ostream& os, const PathLike&) {
|
||||||
::std::ostream& operator<<(::std::ostream& os, const PathLike&)
|
|
||||||
{
|
|
||||||
return os << "Streamable-PathLike";
|
return os << "Streamable-PathLike";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -250,9 +247,9 @@ using ::testing::internal::string;
|
|||||||
#if GTEST_HAS_UNORDERED_MAP_
|
#if GTEST_HAS_UNORDERED_MAP_
|
||||||
|
|
||||||
#define GTEST_HAS_HASH_MAP_ 1
|
#define GTEST_HAS_HASH_MAP_ 1
|
||||||
template<class Key, class T>
|
template <class Key, class T>
|
||||||
using hash_map = ::std::unordered_map<Key, 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>;
|
using hash_multimap = ::std::unordered_multimap<Key, T>;
|
||||||
|
|
||||||
#elif GTEST_HAS_HASH_MAP_
|
#elif GTEST_HAS_HASH_MAP_
|
||||||
@ -270,19 +267,19 @@ using ::stdext::hash_multimap;
|
|||||||
#if GTEST_HAS_UNORDERED_SET_
|
#if GTEST_HAS_UNORDERED_SET_
|
||||||
|
|
||||||
#define GTEST_HAS_HASH_SET_ 1
|
#define GTEST_HAS_HASH_SET_ 1
|
||||||
template<class Key>
|
template <class Key>
|
||||||
using hash_set = ::std::unordered_set<Key>;
|
using hash_set = ::std::unordered_set<Key>;
|
||||||
template<class Key>
|
template <class Key>
|
||||||
using hash_multiset = ::std::unordered_multiset<Key>;
|
using hash_multiset = ::std::unordered_multiset<Key>;
|
||||||
|
|
||||||
#elif GTEST_HAS_HASH_SET_
|
#elif GTEST_HAS_HASH_SET_
|
||||||
|
|
||||||
#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
|
#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
|
||||||
using ::std::hash_set;
|
using ::std::hash_map;
|
||||||
using ::std::hash_multiset;
|
using ::std::hash_multimap;
|
||||||
#elif _MSC_VER
|
#elif _MSC_VER
|
||||||
using ::stdext::hash_set;
|
using ::stdext::hash_map;
|
||||||
using ::stdext::hash_multiset;
|
using ::stdext::hash_multimap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -840,22 +837,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) {
|
|||||||
EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a));
|
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) {
|
TEST(PrintStringViewTest, SimpleStringView) {
|
||||||
const StringPiece sp = "Hello";
|
const ::absl::string_view sp = "Hello";
|
||||||
EXPECT_EQ("\"Hello\"", Print(sp));
|
EXPECT_EQ("\"Hello\"", Print(sp));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PrintStringPieceTest, UnprintableCharacters) {
|
TEST(PrintStringViewTest, UnprintableCharacters) {
|
||||||
const char str[] = "NUL (\0) and \r\t";
|
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));
|
EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_HAS_STRING_PIECE_
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
// Tests printing STL containers.
|
// Tests printing STL containers.
|
||||||
|
|
||||||
@ -1092,7 +1089,7 @@ TEST(PrintTr1TupleTest, VariousSizes) {
|
|||||||
::std::tr1::tuple<bool, char, short, testing::internal::Int32, // NOLINT
|
::std::tr1::tuple<bool, char, short, testing::internal::Int32, // NOLINT
|
||||||
testing::internal::Int64, float, double, const char*, void*,
|
testing::internal::Int64, float, double, const char*, void*,
|
||||||
std::string>
|
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");
|
ImplicitCast_<void*>(NULL), "10");
|
||||||
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
|
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
|
||||||
" pointing to \"8\", NULL, \"10\")",
|
" pointing to \"8\", NULL, \"10\")",
|
||||||
@ -1152,7 +1149,7 @@ TEST(PrintStdTupleTest, VariousSizes) {
|
|||||||
::std::tuple<bool, char, short, testing::internal::Int32, // NOLINT
|
::std::tuple<bool, char, short, testing::internal::Int32, // NOLINT
|
||||||
testing::internal::Int64, float, double, const char*, void*,
|
testing::internal::Int64, float, double, const char*, void*,
|
||||||
std::string>
|
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");
|
ImplicitCast_<void*>(NULL), "10");
|
||||||
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
|
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
|
||||||
" pointing to \"8\", NULL, \"10\")",
|
" pointing to \"8\", NULL, \"10\")",
|
||||||
@ -1330,7 +1327,7 @@ TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tests formatting a char pointer when it's compared with another pointer.
|
// 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.
|
// pointer.
|
||||||
|
|
||||||
// char pointer vs pointer
|
// char pointer vs pointer
|
||||||
@ -1555,6 +1552,78 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) {
|
|||||||
EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\"");
|
EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintToStringTest, ContainsNonLatin) {
|
||||||
|
// Sanity test with valid UTF-8. Prints both in hex and as text.
|
||||||
|
std::string non_ascii_str = ::std::string("오전 4:30");
|
||||||
|
EXPECT_PRINT_TO_STRING_(non_ascii_str,
|
||||||
|
"\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n"
|
||||||
|
" As Text: \"오전 4:30\"");
|
||||||
|
non_ascii_str = ::std::string("From ä — ẑ");
|
||||||
|
EXPECT_PRINT_TO_STRING_(non_ascii_str,
|
||||||
|
"\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\""
|
||||||
|
"\n As Text: \"From ä — ẑ\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IsValidUTF8Test, IllFormedUTF8) {
|
||||||
|
// The following test strings are ill-formed UTF-8 and are printed
|
||||||
|
// as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is
|
||||||
|
// expected to fail, thus output does not contain "As Text:".
|
||||||
|
|
||||||
|
static const char *const kTestdata[][2] = {
|
||||||
|
// 2-byte lead byte followed by a single-byte character.
|
||||||
|
{"\xC3\x74", "\"\\xC3t\""},
|
||||||
|
// Valid 2-byte character followed by an orphan trail byte.
|
||||||
|
{"\xC3\x84\xA4", "\"\\xC3\\x84\\xA4\""},
|
||||||
|
// Lead byte without trail byte.
|
||||||
|
{"abc\xC3", "\"abc\\xC3\""},
|
||||||
|
// 3-byte lead byte, single-byte character, orphan trail byte.
|
||||||
|
{"x\xE2\x70\x94", "\"x\\xE2p\\x94\""},
|
||||||
|
// Truncated 3-byte character.
|
||||||
|
{"\xE2\x80", "\"\\xE2\\x80\""},
|
||||||
|
// Truncated 3-byte character followed by valid 2-byte char.
|
||||||
|
{"\xE2\x80\xC3\x84", "\"\\xE2\\x80\\xC3\\x84\""},
|
||||||
|
// Truncated 3-byte character followed by a single-byte character.
|
||||||
|
{"\xE2\x80\x7A", "\"\\xE2\\x80z\""},
|
||||||
|
// 3-byte lead byte followed by valid 3-byte character.
|
||||||
|
{"\xE2\xE2\x80\x94", "\"\\xE2\\xE2\\x80\\x94\""},
|
||||||
|
// 4-byte lead byte followed by valid 3-byte character.
|
||||||
|
{"\xF0\xE2\x80\x94", "\"\\xF0\\xE2\\x80\\x94\""},
|
||||||
|
// Truncated 4-byte character.
|
||||||
|
{"\xF0\xE2\x80", "\"\\xF0\\xE2\\x80\""},
|
||||||
|
// Invalid UTF-8 byte sequences embedded in other chars.
|
||||||
|
{"abc\xE2\x80\x94\xC3\x74xyc", "\"abc\\xE2\\x80\\x94\\xC3txyc\""},
|
||||||
|
{"abc\xC3\x84\xE2\x80\xC3\x84xyz",
|
||||||
|
"\"abc\\xC3\\x84\\xE2\\x80\\xC3\\x84xyz\""},
|
||||||
|
// Non-shortest UTF-8 byte sequences are also ill-formed.
|
||||||
|
// The classics: xC0, xC1 lead byte.
|
||||||
|
{"\xC0\x80", "\"\\xC0\\x80\""},
|
||||||
|
{"\xC1\x81", "\"\\xC1\\x81\""},
|
||||||
|
// Non-shortest sequences.
|
||||||
|
{"\xE0\x80\x80", "\"\\xE0\\x80\\x80\""},
|
||||||
|
{"\xf0\x80\x80\x80", "\"\\xF0\\x80\\x80\\x80\""},
|
||||||
|
// Last valid code point before surrogate range, should be printed as text,
|
||||||
|
// too.
|
||||||
|
{"\xED\x9F\xBF", "\"\\xED\\x9F\\xBF\"\n As Text: \"\""},
|
||||||
|
// Start of surrogate lead. Surrogates are not printed as text.
|
||||||
|
{"\xED\xA0\x80", "\"\\xED\\xA0\\x80\""},
|
||||||
|
// Last non-private surrogate lead.
|
||||||
|
{"\xED\xAD\xBF", "\"\\xED\\xAD\\xBF\""},
|
||||||
|
// First private-use surrogate lead.
|
||||||
|
{"\xED\xAE\x80", "\"\\xED\\xAE\\x80\""},
|
||||||
|
// Last private-use surrogate lead.
|
||||||
|
{"\xED\xAF\xBF", "\"\\xED\\xAF\\xBF\""},
|
||||||
|
// Mid-point of surrogate trail.
|
||||||
|
{"\xED\xB3\xBF", "\"\\xED\\xB3\\xBF\""},
|
||||||
|
// First valid code point after surrogate range, should be printed as text,
|
||||||
|
// too.
|
||||||
|
{"\xEE\x80\x80", "\"\\xEE\\x80\\x80\"\n As Text: \"\""}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < int(sizeof(kTestdata)/sizeof(kTestdata[0])); ++i) {
|
||||||
|
EXPECT_PRINT_TO_STRING_(kTestdata[i][0], kTestdata[i][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#undef EXPECT_PRINT_TO_STRING_
|
#undef EXPECT_PRINT_TO_STRING_
|
||||||
|
|
||||||
TEST(UniversalTersePrintTest, WorksForNonReference) {
|
TEST(UniversalTersePrintTest, WorksForNonReference) {
|
||||||
@ -1696,5 +1765,17 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
|
|||||||
|
|
||||||
#endif // GTEST_HAS_STD_TUPLE_
|
#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 gtest_printers_test
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "test/gtest-typed-test_test.h"
|
#include "gtest-typed-test_test.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#if GTEST_HAS_TYPED_TEST_P
|
#if GTEST_HAS_TYPED_TEST_P
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
//
|
//
|
||||||
// Author: wan@google.com (Zhanyong Wan)
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
#include "test/gtest-typed-test_test.h"
|
#include "gtest-typed-test_test.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -33,15 +33,15 @@
|
|||||||
//
|
//
|
||||||
// Sometimes it's desirable to build most of Google Test's own tests
|
// Sometimes it's desirable to build most of Google Test's own tests
|
||||||
// by compiling a single file. This file serves this purpose.
|
// by compiling a single file. This file serves this purpose.
|
||||||
#include "test/gtest-filepath_test.cc"
|
#include "gtest-filepath_test.cc"
|
||||||
#include "test/gtest-linked_ptr_test.cc"
|
#include "gtest-linked_ptr_test.cc"
|
||||||
#include "test/gtest-message_test.cc"
|
#include "gtest-message_test.cc"
|
||||||
#include "test/gtest-options_test.cc"
|
#include "gtest-options_test.cc"
|
||||||
#include "test/gtest-port_test.cc"
|
#include "gtest-port_test.cc"
|
||||||
#include "test/gtest_pred_impl_unittest.cc"
|
#include "gtest_pred_impl_unittest.cc"
|
||||||
#include "test/gtest_prod_test.cc"
|
#include "gtest_prod_test.cc"
|
||||||
#include "test/gtest-test-part_test.cc"
|
#include "gtest-test-part_test.cc"
|
||||||
#include "test/gtest-typed-test_test.cc"
|
#include "gtest-typed-test_test.cc"
|
||||||
#include "test/gtest-typed-test2_test.cc"
|
#include "gtest-typed-test2_test.cc"
|
||||||
#include "test/gtest_unittest.cc"
|
#include "gtest_unittest.cc"
|
||||||
#include "test/production.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)'
|
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||||
|
|
||||||
import gtest_test_utils
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import gtest_test_utils
|
||||||
|
|
||||||
|
|
||||||
# Constants.
|
# Constants.
|
||||||
|
|
||||||
|
@ -80,8 +80,7 @@ int main(int argc, char **argv) {
|
|||||||
SetUnhandledExceptionFilter(ExitWithExceptionCode);
|
SetUnhandledExceptionFilter(ExitWithExceptionCode);
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
|
@ -37,8 +37,6 @@ Google Test) and verifies their output.
|
|||||||
|
|
||||||
__author__ = 'vladl@google.com (Vlad Losev)'
|
__author__ = 'vladl@google.com (Vlad Losev)'
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
import gtest_test_utils
|
import gtest_test_utils
|
||||||
|
|
||||||
# Constants.
|
# Constants.
|
||||||
|
@ -36,8 +36,7 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
|
|||||||
import os
|
import os
|
||||||
import gtest_test_utils
|
import gtest_test_utils
|
||||||
|
|
||||||
|
IS_WINDOWS = os.name == 'nt'
|
||||||
IS_WINDOWS = os.name = 'nt'
|
|
||||||
|
|
||||||
COLOR_ENV_VAR = 'GTEST_COLOR'
|
COLOR_ENV_VAR = 'GTEST_COLOR'
|
||||||
COLOR_FLAG = 'gtest_color'
|
COLOR_FLAG = 'gtest_color'
|
||||||
|
@ -36,15 +36,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "gtest/gtest.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"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
using testing::internal::ShouldUseColor;
|
using testing::internal::ShouldUseColor;
|
||||||
|
|
||||||
|
@ -47,8 +47,8 @@ environ = os.environ.copy()
|
|||||||
|
|
||||||
def AssertEq(expected, actual):
|
def AssertEq(expected, actual):
|
||||||
if expected != actual:
|
if expected != actual:
|
||||||
print('Expected: %s' % (expected,))
|
print 'Expected: %s' % (expected,)
|
||||||
print(' Actual: %s' % (actual,))
|
print ' Actual: %s' % (actual,)
|
||||||
raise AssertionError
|
raise AssertionError
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,9 +36,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define GTEST_IMPLEMENTATION_ 1
|
|
||||||
#include "src/gtest-internal-inl.h"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
using ::std::cout;
|
using ::std::cout;
|
||||||
|
|
||||||
|
@ -34,10 +34,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#define GTEST_IMPLEMENTATION_ 1 // Required for the next #include.
|
|
||||||
#include "src/gtest-internal-inl.h"
|
#include "src/gtest-internal-inl.h"
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
GTEST_DECLARE_string_(filter);
|
GTEST_DECLARE_string_(filter);
|
||||||
|
@ -44,12 +44,8 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
try:
|
import sets
|
||||||
from sets import Set as set # For Python 2.3 compatibility
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import gtest_test_utils
|
import gtest_test_utils
|
||||||
|
|
||||||
# Constants.
|
# Constants.
|
||||||
@ -59,10 +55,12 @@ import gtest_test_utils
|
|||||||
# script in a subprocess to print whether the variable is STILL in
|
# 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
|
# 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'.
|
# exception is thrown if the input is anything other than 'True' nor 'False'.
|
||||||
os.environ['EMPTY_VAR'] = ''
|
CAN_PASS_EMPTY_ENV = False
|
||||||
child = gtest_test_utils.Subprocess(
|
if sys.executable:
|
||||||
[sys.executable, '-c', 'import os; print(\'EMPTY_VAR\' in os.environ)'])
|
os.environ['EMPTY_VAR'] = ''
|
||||||
CAN_PASS_EMPTY_ENV = eval(child.output)
|
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.
|
# 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.
|
# is NO LONGER in os.environ.
|
||||||
# We use 'eval' to parse the child's output so that an exception
|
# We use 'eval' to parse the child's output so that an exception
|
||||||
# is thrown if the input is neither 'True' nor 'False'.
|
# is thrown if the input is neither 'True' nor 'False'.
|
||||||
os.environ['UNSET_VAR'] = 'X'
|
CAN_UNSET_ENV = False
|
||||||
del os.environ['UNSET_VAR']
|
if sys.executable:
|
||||||
child = gtest_test_utils.Subprocess(
|
os.environ['UNSET_VAR'] = 'X'
|
||||||
[sys.executable, '-c', 'import os; print(\'UNSET_VAR\' not in os.environ)'])
|
del os.environ['UNSET_VAR']
|
||||||
CAN_UNSET_ENV = eval(child.output)
|
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
|
# 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'
|
FILTER_FLAG = 'gtest_filter'
|
||||||
|
|
||||||
# The command line flag for including disabled tests.
|
# 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 to run the gtest_filter_unittest_ program.
|
||||||
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_')
|
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:
|
for slice_var in list_of_sets:
|
||||||
full_partition.extend(slice_var)
|
full_partition.extend(slice_var)
|
||||||
self.assertEqual(len(set_var), len(full_partition))
|
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):
|
def AdjustForParameterizedTests(self, tests_to_run):
|
||||||
"""Adjust tests_to_run in case value parameterized tests are disabled."""
|
"""Adjust tests_to_run in case value parameterized tests are disabled."""
|
||||||
|
|
||||||
global param_tests_present
|
global param_tests_present
|
||||||
if not 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:
|
else:
|
||||||
return tests_to_run
|
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
|
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
|
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.
|
on each shard should be identical to tests_to_run, without duplicates.
|
||||||
|
If check_exit_0, .
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
gtest_filter: A filter to apply to the tests.
|
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)
|
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
|
||||||
|
|
||||||
# Construct the command line.
|
# Construct the command line.
|
||||||
args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG]
|
args = ['--%s' % ALSO_RUN_DISABLED_TESTS_FLAG]
|
||||||
if gtest_filter is not None:
|
if gtest_filter is not None:
|
||||||
args.append('--%s=%s' % (FILTER_FLAG, gtest_filter))
|
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)'
|
__author__ = 'phanna@google.com (Patrick Hanna)'
|
||||||
|
|
||||||
import gtest_test_utils
|
|
||||||
import re
|
import re
|
||||||
|
import gtest_test_utils
|
||||||
|
|
||||||
# Constants.
|
# Constants.
|
||||||
|
|
||||||
@ -123,6 +122,7 @@ def Run(args):
|
|||||||
|
|
||||||
# The unit test.
|
# The unit test.
|
||||||
|
|
||||||
|
|
||||||
class GTestListTestsUnitTest(gtest_test_utils.TestCase):
|
class GTestListTestsUnitTest(gtest_test_utils.TestCase):
|
||||||
"""Tests using the --gtest_list_tests flag to list all tests."""
|
"""Tests using the --gtest_list_tests flag to list all tests."""
|
||||||
|
|
||||||
|
@ -41,5 +41,5 @@ TEST(GTestMainTest, ShouldSucceed) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// We are using the main() function defined in src/gtest_main.cc, so
|
// We are using the main() function defined in gtest_main.cc, so we
|
||||||
// we don't define it here.
|
// don't define it here.
|
||||||
|
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