dep: Add googletest
This commit is contained in:
parent
a4486cf6fa
commit
6ce97e0e13
|
@ -0,0 +1,25 @@
|
||||||
|
set(SRCS
|
||||||
|
src/gtest.cc
|
||||||
|
src/gtest-death-test.cc
|
||||||
|
src/gtest-filepath.cc
|
||||||
|
src/gtest-matchers.cc
|
||||||
|
src/gtest-port.cc
|
||||||
|
src/gtest-printers.cc
|
||||||
|
src/gtest-test-part.cc
|
||||||
|
src/gtest-typed-test.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MAIN_SRCS
|
||||||
|
src/gtest_main.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(gtest ${SRCS})
|
||||||
|
target_include_directories(gtest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||||
|
target_include_directories(gtest INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||||
|
target_link_libraries(gtest Threads::Threads)
|
||||||
|
|
||||||
|
add_library(gtest_main "${MAIN_SRCS}")
|
||||||
|
target_include_directories(gtest_main PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||||
|
target_include_directories(gtest_main INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||||
|
target_link_libraries(gtest_main Threads::Threads)
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# This file contains a list of people who've made non-trivial
|
||||||
|
# contribution to the Google C++ Testing Framework project. People
|
||||||
|
# who commit code to the project are encouraged to add their names
|
||||||
|
# here. Please keep the list sorted by first names.
|
||||||
|
|
||||||
|
Ajay Joshi <jaj@google.com>
|
||||||
|
Balázs Dán <balazs.dan@gmail.com>
|
||||||
|
Bharat Mediratta <bharat@menalto.com>
|
||||||
|
Chandler Carruth <chandlerc@google.com>
|
||||||
|
Chris Prince <cprince@google.com>
|
||||||
|
Chris Taylor <taylorc@google.com>
|
||||||
|
Dan Egnor <egnor@google.com>
|
||||||
|
Eric Roman <eroman@chromium.org>
|
||||||
|
Hady Zalek <hady.zalek@gmail.com>
|
||||||
|
Jeffrey Yasskin <jyasskin@google.com>
|
||||||
|
Jói Sigurðsson <joi@google.com>
|
||||||
|
Keir Mierle <mierle@gmail.com>
|
||||||
|
Keith Ray <keith.ray@gmail.com>
|
||||||
|
Kenton Varda <kenton@google.com>
|
||||||
|
Krystian Kuzniarek <krystian.kuzniarek@gmail.com>
|
||||||
|
Manuel Klimek <klimek@google.com>
|
||||||
|
Markus Heule <markus.heule@gmail.com>
|
||||||
|
Mika Raento <mikie@iki.fi>
|
||||||
|
Miklós Fazekas <mfazekas@szemafor.com>
|
||||||
|
Pasi Valminen <pasi.valminen@gmail.com>
|
||||||
|
Patrick Hanna <phanna@google.com>
|
||||||
|
Patrick Riley <pfr@google.com>
|
||||||
|
Peter Kaminski <piotrk@google.com>
|
||||||
|
Preston Jackson <preston.a.jackson@gmail.com>
|
||||||
|
Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.com>
|
||||||
|
Russ Cox <rsc@google.com>
|
||||||
|
Russ Rufer <russ@pentad.com>
|
||||||
|
Sean Mcafee <eefacm@gmail.com>
|
||||||
|
Sigurður Ásgeirsson <siggi@google.com>
|
||||||
|
Tracy Bialik <tracy@pentad.com>
|
||||||
|
Vadim Berman <vadimb@google.com>
|
||||||
|
Vlad Losev <vladl@google.com>
|
||||||
|
Zhanyong Wan <wan@google.com>
|
|
@ -0,0 +1,28 @@
|
||||||
|
Copyright 2008, Google Inc.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,371 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="DebugFast|Win32">
|
||||||
|
<Configuration>DebugFast</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="DebugFast|x64">
|
||||||
|
<Configuration>DebugFast</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="ReleaseLTCG|Win32">
|
||||||
|
<Configuration>ReleaseLTCG</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="ReleaseLTCG|x64">
|
||||||
|
<Configuration>ReleaseLTCG</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="include\gtest\gtest-death-test.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-matchers.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-message.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-param-test.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-printers.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-spi.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-test-part.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-typed-test.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest_pred_impl.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest_prod.h" />
|
||||||
|
<ClInclude Include="src\gtest-internal-inl.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\gtest-death-test.cc" />
|
||||||
|
<ClCompile Include="src\gtest-filepath.cc" />
|
||||||
|
<ClCompile Include="src\gtest-matchers.cc" />
|
||||||
|
<ClCompile Include="src\gtest-port.cc" />
|
||||||
|
<ClCompile Include="src\gtest-printers.cc" />
|
||||||
|
<ClCompile Include="src\gtest-test-part.cc" />
|
||||||
|
<ClCompile Include="src\gtest-typed-test.cc" />
|
||||||
|
<ClCompile Include="src\gtest.cc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{49953E1B-2EF7-46A4-B88B-1BF9E099093B}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>googletest</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|x64'">
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level2</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_7ZIP_ST;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level2</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_7ZIP_ST;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level2</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_7ZIP_ST;_ITERATOR_DEBUG_LEVEL=1;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level2</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_7ZIP_ST;_ITERATOR_DEBUG_LEVEL=1;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level2</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>_7ZIP_ST;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level2</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>_7ZIP_ST;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level2</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>_7ZIP_ST;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level2</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>_7ZIP_ST;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="include\gtest\gtest.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest_pred_impl.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest_prod.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-death-test.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-matchers.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-message.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-param-test.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-printers.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-spi.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-test-part.h" />
|
||||||
|
<ClInclude Include="include\gtest\gtest-typed-test.h" />
|
||||||
|
<ClInclude Include="src\gtest-internal-inl.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\gtest.cc" />
|
||||||
|
<ClCompile Include="src\gtest-death-test.cc" />
|
||||||
|
<ClCompile Include="src\gtest-filepath.cc" />
|
||||||
|
<ClCompile Include="src\gtest-matchers.cc" />
|
||||||
|
<ClCompile Include="src\gtest-port.cc" />
|
||||||
|
<ClCompile Include="src\gtest-printers.cc" />
|
||||||
|
<ClCompile Include="src\gtest-test-part.cc" />
|
||||||
|
<ClCompile Include="src\gtest-typed-test.cc" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,343 @@
|
||||||
|
// Copyright 2005, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// This header file defines the public API for death tests. It is
|
||||||
|
// #included by gtest.h so a user doesn't need to include this
|
||||||
|
// directly.
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-death-test-internal.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// This flag controls the style of death tests. Valid values are "threadsafe",
|
||||||
|
// meaning that the death test child process will re-execute the test binary
|
||||||
|
// from the start, running only a single death test, or "fast",
|
||||||
|
// meaning that the child process will execute the test logic immediately
|
||||||
|
// after forking.
|
||||||
|
GTEST_DECLARE_string_(death_test_style);
|
||||||
|
|
||||||
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Returns a Boolean value indicating whether the caller is currently
|
||||||
|
// executing in the context of the death test child process. Tools such as
|
||||||
|
// Valgrind heap checkers may need this to modify their behavior in death
|
||||||
|
// tests. IMPORTANT: This is an internal utility. Using it may break the
|
||||||
|
// implementation of death tests. User code MUST NOT use it.
|
||||||
|
GTEST_API_ bool InDeathTestChild();
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// The following macros are useful for writing death tests.
|
||||||
|
|
||||||
|
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
|
||||||
|
// executed:
|
||||||
|
//
|
||||||
|
// 1. It generates a warning if there is more than one active
|
||||||
|
// thread. This is because it's safe to fork() or clone() only
|
||||||
|
// when there is a single thread.
|
||||||
|
//
|
||||||
|
// 2. The parent process clone()s a sub-process and runs the death
|
||||||
|
// test in it; the sub-process exits with code 0 at the end of the
|
||||||
|
// death test, if it hasn't exited already.
|
||||||
|
//
|
||||||
|
// 3. The parent process waits for the sub-process to terminate.
|
||||||
|
//
|
||||||
|
// 4. The parent process checks the exit code and error message of
|
||||||
|
// the sub-process.
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
|
||||||
|
// for (int i = 0; i < 5; i++) {
|
||||||
|
// EXPECT_DEATH(server.ProcessRequest(i),
|
||||||
|
// "Invalid request .* in ProcessRequest()")
|
||||||
|
// << "Failed to die on request " << i;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
|
||||||
|
//
|
||||||
|
// bool KilledBySIGHUP(int exit_code) {
|
||||||
|
// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
|
||||||
|
//
|
||||||
|
// On the regular expressions used in death tests:
|
||||||
|
//
|
||||||
|
// GOOGLETEST_CM0005 DO NOT DELETE
|
||||||
|
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||||
|
// which uses the POSIX extended regex syntax.
|
||||||
|
//
|
||||||
|
// On other platforms (e.g. Windows or Mac), we only support a simple regex
|
||||||
|
// syntax implemented as part of Google Test. This limited
|
||||||
|
// implementation should be enough most of the time when writing
|
||||||
|
// death tests; though it lacks many features you can find in PCRE
|
||||||
|
// or POSIX extended regex syntax. For example, we don't support
|
||||||
|
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
|
||||||
|
// repetition count ("x{5,7}"), among others.
|
||||||
|
//
|
||||||
|
// Below is the syntax that we do support. We chose it to be a
|
||||||
|
// subset of both PCRE and POSIX extended regex, so it's easy to
|
||||||
|
// learn wherever you come from. In the following: 'A' denotes a
|
||||||
|
// literal character, period (.), or a single \\ escape sequence;
|
||||||
|
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
|
||||||
|
// natural numbers.
|
||||||
|
//
|
||||||
|
// c matches any literal character c
|
||||||
|
// \\d matches any decimal digit
|
||||||
|
// \\D matches any character that's not a decimal digit
|
||||||
|
// \\f matches \f
|
||||||
|
// \\n matches \n
|
||||||
|
// \\r matches \r
|
||||||
|
// \\s matches any ASCII whitespace, including \n
|
||||||
|
// \\S matches any character that's not a whitespace
|
||||||
|
// \\t matches \t
|
||||||
|
// \\v matches \v
|
||||||
|
// \\w matches any letter, _, or decimal digit
|
||||||
|
// \\W matches any character that \\w doesn't match
|
||||||
|
// \\c matches any literal character c, which must be a punctuation
|
||||||
|
// . matches any single character except \n
|
||||||
|
// A? matches 0 or 1 occurrences of A
|
||||||
|
// A* matches 0 or many occurrences of A
|
||||||
|
// A+ matches 1 or many occurrences of A
|
||||||
|
// ^ matches the beginning of a string (not that of each line)
|
||||||
|
// $ matches the end of a string (not that of each line)
|
||||||
|
// xy matches x followed by y
|
||||||
|
//
|
||||||
|
// If you accidentally use PCRE or POSIX extended regex features
|
||||||
|
// not implemented by us, you will get a run-time failure. In that
|
||||||
|
// case, please try to rewrite your regular expression within the
|
||||||
|
// above syntax.
|
||||||
|
//
|
||||||
|
// This implementation is *not* meant to be as highly tuned or robust
|
||||||
|
// as a compiled regex library, but should perform well enough for a
|
||||||
|
// death test, which already incurs significant overhead by launching
|
||||||
|
// a child process.
|
||||||
|
//
|
||||||
|
// Known caveats:
|
||||||
|
//
|
||||||
|
// A "threadsafe" style death test obtains the path to the test
|
||||||
|
// program from argv[0] and re-executes it in the sub-process. For
|
||||||
|
// simplicity, the current implementation doesn't search the PATH
|
||||||
|
// when launching the sub-process. This means that the user must
|
||||||
|
// invoke the test program via a path that contains at least one
|
||||||
|
// path separator (e.g. path/to/foo_test and
|
||||||
|
// /absolute/path/to/bar_test are fine, but foo_test is not). This
|
||||||
|
// is rarely a problem as people usually don't put the test binary
|
||||||
|
// directory in PATH.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Asserts that a given statement causes the program to exit, with an
|
||||||
|
// integer exit status that satisfies predicate, and emitting error output
|
||||||
|
// that matches regex.
|
||||||
|
# define ASSERT_EXIT(statement, predicate, regex) \
|
||||||
|
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
|
||||||
|
|
||||||
|
// Like ASSERT_EXIT, but continues on to successive tests in the
|
||||||
|
// test suite, if any:
|
||||||
|
# define EXPECT_EXIT(statement, predicate, regex) \
|
||||||
|
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
|
||||||
|
|
||||||
|
// Asserts that a given statement causes the program to exit, either by
|
||||||
|
// explicitly exiting with a nonzero exit code or being killed by a
|
||||||
|
// signal, and emitting error output that matches regex.
|
||||||
|
# define ASSERT_DEATH(statement, regex) \
|
||||||
|
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||||
|
|
||||||
|
// Like ASSERT_DEATH, but continues on to successive tests in the
|
||||||
|
// test suite, if any:
|
||||||
|
# define EXPECT_DEATH(statement, regex) \
|
||||||
|
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||||
|
|
||||||
|
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
|
||||||
|
|
||||||
|
// Tests that an exit code describes a normal exit with a given exit code.
|
||||||
|
class GTEST_API_ ExitedWithCode {
|
||||||
|
public:
|
||||||
|
explicit ExitedWithCode(int exit_code);
|
||||||
|
bool operator()(int exit_status) const;
|
||||||
|
private:
|
||||||
|
// No implementation - assignment is unsupported.
|
||||||
|
void operator=(const ExitedWithCode& other);
|
||||||
|
|
||||||
|
const int exit_code_;
|
||||||
|
};
|
||||||
|
|
||||||
|
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
||||||
|
// Tests that an exit code describes an exit due to termination by a
|
||||||
|
// given signal.
|
||||||
|
// GOOGLETEST_CM0006 DO NOT DELETE
|
||||||
|
class GTEST_API_ KilledBySignal {
|
||||||
|
public:
|
||||||
|
explicit KilledBySignal(int signum);
|
||||||
|
bool operator()(int exit_status) const;
|
||||||
|
private:
|
||||||
|
const int signum_;
|
||||||
|
};
|
||||||
|
# endif // !GTEST_OS_WINDOWS
|
||||||
|
|
||||||
|
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
|
||||||
|
// The death testing framework causes this to have interesting semantics,
|
||||||
|
// since the sideeffects of the call are only visible in opt mode, and not
|
||||||
|
// in debug mode.
|
||||||
|
//
|
||||||
|
// In practice, this can be used to test functions that utilize the
|
||||||
|
// LOG(DFATAL) macro using the following style:
|
||||||
|
//
|
||||||
|
// int DieInDebugOr12(int* sideeffect) {
|
||||||
|
// if (sideeffect) {
|
||||||
|
// *sideeffect = 12;
|
||||||
|
// }
|
||||||
|
// LOG(DFATAL) << "death";
|
||||||
|
// return 12;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) {
|
||||||
|
// int sideeffect = 0;
|
||||||
|
// // Only asserts in dbg.
|
||||||
|
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
|
||||||
|
//
|
||||||
|
// #ifdef NDEBUG
|
||||||
|
// // opt-mode has sideeffect visible.
|
||||||
|
// EXPECT_EQ(12, sideeffect);
|
||||||
|
// #else
|
||||||
|
// // dbg-mode no visible sideeffect.
|
||||||
|
// EXPECT_EQ(0, sideeffect);
|
||||||
|
// #endif
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// This will assert that DieInDebugReturn12InOpt() crashes in debug
|
||||||
|
// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
|
||||||
|
// appropriate fallback value (12 in this case) in opt mode. If you
|
||||||
|
// need to test that a function has appropriate side-effects in opt
|
||||||
|
// mode, include assertions against the side-effects. A general
|
||||||
|
// pattern for this is:
|
||||||
|
//
|
||||||
|
// EXPECT_DEBUG_DEATH({
|
||||||
|
// // Side-effects here will have an effect after this statement in
|
||||||
|
// // opt mode, but none in debug mode.
|
||||||
|
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
|
||||||
|
// }, "death");
|
||||||
|
//
|
||||||
|
# ifdef NDEBUG
|
||||||
|
|
||||||
|
# define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||||
|
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||||
|
|
||||||
|
# define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||||
|
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
# define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||||
|
EXPECT_DEATH(statement, regex)
|
||||||
|
|
||||||
|
# define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||||
|
ASSERT_DEATH(statement, regex)
|
||||||
|
|
||||||
|
# endif // NDEBUG for EXPECT_DEBUG_DEATH
|
||||||
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
|
// This macro is used for implementing macros such as
|
||||||
|
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
|
||||||
|
// death tests are not supported. Those macros must compile on such systems
|
||||||
|
// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters
|
||||||
|
// on systems that support death tests. This allows one to write such a macro on
|
||||||
|
// a system that does not support death tests and be sure that it will compile
|
||||||
|
// on a death-test supporting system. It is exposed publicly so that systems
|
||||||
|
// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST
|
||||||
|
// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and
|
||||||
|
// ASSERT_DEATH_IF_SUPPORTED.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// statement - A statement that a macro such as EXPECT_DEATH would test
|
||||||
|
// for program termination. This macro has to make sure this
|
||||||
|
// statement is compiled but not executed, to ensure that
|
||||||
|
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
||||||
|
// parameter if and only if EXPECT_DEATH compiles with it.
|
||||||
|
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
||||||
|
// the output of statement. This parameter has to be
|
||||||
|
// compiled but not evaluated by this macro, to ensure that
|
||||||
|
// this macro only accepts expressions that a macro such as
|
||||||
|
// EXPECT_DEATH would accept.
|
||||||
|
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
|
||||||
|
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
|
||||||
|
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
|
||||||
|
// compile inside functions where ASSERT_DEATH doesn't
|
||||||
|
// compile.
|
||||||
|
//
|
||||||
|
// The branch that has an always false condition is used to ensure that
|
||||||
|
// statement and regex are compiled (and thus syntactically correct) but
|
||||||
|
// never executed. The unreachable code macro protects the terminator
|
||||||
|
// statement from generating an 'unreachable code' warning in case
|
||||||
|
// statement unconditionally returns or throws. The Message constructor at
|
||||||
|
// the end allows the syntax of streaming additional messages into the
|
||||||
|
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
|
||||||
|
# define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
|
||||||
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||||
|
if (::testing::internal::AlwaysTrue()) { \
|
||||||
|
GTEST_LOG_(WARNING) \
|
||||||
|
<< "Death tests are not supported on this platform.\n" \
|
||||||
|
<< "Statement '" #statement "' cannot be verified."; \
|
||||||
|
} else if (::testing::internal::AlwaysFalse()) { \
|
||||||
|
::testing::internal::RE::PartialMatch(".*", (regex)); \
|
||||||
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||||
|
terminator; \
|
||||||
|
} else \
|
||||||
|
::testing::Message()
|
||||||
|
|
||||||
|
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
|
||||||
|
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
||||||
|
// death tests are supported; otherwise they just issue a warning. This is
|
||||||
|
// useful when you are combining death test assertions with normal test
|
||||||
|
// assertions in one test.
|
||||||
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||||
|
EXPECT_DEATH(statement, regex)
|
||||||
|
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||||
|
ASSERT_DEATH(statement, regex)
|
||||||
|
#else
|
||||||
|
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||||
|
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
|
||||||
|
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||||
|
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
|
@ -0,0 +1,750 @@
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// This file implements just enough of the matcher interface to allow
|
||||||
|
// EXPECT_DEATH and friends to accept a matcher argument.
|
||||||
|
|
||||||
|
// IWYU pragma: private, include "testing/base/public/gunit.h"
|
||||||
|
// IWYU pragma: friend third_party/googletest/googlemock/.*
|
||||||
|
// IWYU pragma: friend third_party/googletest/googletest/.*
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "gtest/gtest-printers.h"
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
// MSVC warning C5046 is new as of VS2017 version 15.8.
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1915
|
||||||
|
#define GTEST_MAYBE_5046_ 5046
|
||||||
|
#else
|
||||||
|
#define GTEST_MAYBE_5046_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
||||||
|
4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by
|
||||||
|
clients of class B */
|
||||||
|
/* Symbol involving type with internal linkage not defined */)
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// To implement a matcher Foo for type T, define:
|
||||||
|
// 1. a class FooMatcherImpl that implements the
|
||||||
|
// MatcherInterface<T> interface, and
|
||||||
|
// 2. a factory function that creates a Matcher<T> object from a
|
||||||
|
// FooMatcherImpl*.
|
||||||
|
//
|
||||||
|
// The two-level delegation design makes it possible to allow a user
|
||||||
|
// to write "v" instead of "Eq(v)" where a Matcher is expected, which
|
||||||
|
// is impossible if we pass matchers by pointers. It also eases
|
||||||
|
// ownership management as Matcher objects can now be copied like
|
||||||
|
// plain values.
|
||||||
|
|
||||||
|
// MatchResultListener is an abstract class. Its << operator can be
|
||||||
|
// used by a matcher to explain why a value matches or doesn't match.
|
||||||
|
//
|
||||||
|
class MatchResultListener {
|
||||||
|
public:
|
||||||
|
// Creates a listener object with the given underlying ostream. The
|
||||||
|
// listener does not own the ostream, and does not dereference it
|
||||||
|
// in the constructor or destructor.
|
||||||
|
explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
|
||||||
|
virtual ~MatchResultListener() = 0; // Makes this class abstract.
|
||||||
|
|
||||||
|
// Streams x to the underlying ostream; does nothing if the ostream
|
||||||
|
// is NULL.
|
||||||
|
template <typename T>
|
||||||
|
MatchResultListener& operator<<(const T& x) {
|
||||||
|
if (stream_ != nullptr) *stream_ << x;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the underlying ostream.
|
||||||
|
::std::ostream* stream() { return stream_; }
|
||||||
|
|
||||||
|
// Returns true if and only if the listener is interested in an explanation
|
||||||
|
// of the match result. A matcher's MatchAndExplain() method can use
|
||||||
|
// this information to avoid generating the explanation when no one
|
||||||
|
// intends to hear it.
|
||||||
|
bool IsInterested() const { return stream_ != nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
::std::ostream* const stream_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline MatchResultListener::~MatchResultListener() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// An instance of a subclass of this knows how to describe itself as a
|
||||||
|
// matcher.
|
||||||
|
class MatcherDescriberInterface {
|
||||||
|
public:
|
||||||
|
virtual ~MatcherDescriberInterface() {}
|
||||||
|
|
||||||
|
// Describes this matcher to an ostream. The function should print
|
||||||
|
// a verb phrase that describes the property a value matching this
|
||||||
|
// matcher should have. The subject of the verb phrase is the value
|
||||||
|
// being matched. For example, the DescribeTo() method of the Gt(7)
|
||||||
|
// matcher prints "is greater than 7".
|
||||||
|
virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||||
|
|
||||||
|
// Describes the negation of this matcher to an ostream. For
|
||||||
|
// example, if the description of this matcher is "is greater than
|
||||||
|
// 7", the negated description could be "is not greater than 7".
|
||||||
|
// You are not required to override this when implementing
|
||||||
|
// MatcherInterface, but it is highly advised so that your matcher
|
||||||
|
// can produce good error messages.
|
||||||
|
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
*os << "not (";
|
||||||
|
DescribeTo(os);
|
||||||
|
*os << ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The implementation of a matcher.
|
||||||
|
template <typename T>
|
||||||
|
class MatcherInterface : public MatcherDescriberInterface {
|
||||||
|
public:
|
||||||
|
// Returns true if and only if the matcher matches x; also explains the
|
||||||
|
// match result to 'listener' if necessary (see the next paragraph), in
|
||||||
|
// the form of a non-restrictive relative clause ("which ...",
|
||||||
|
// "whose ...", etc) that describes x. For example, the
|
||||||
|
// MatchAndExplain() method of the Pointee(...) matcher should
|
||||||
|
// generate an explanation like "which points to ...".
|
||||||
|
//
|
||||||
|
// Implementations of MatchAndExplain() should add an explanation of
|
||||||
|
// the match result *if and only if* they can provide additional
|
||||||
|
// information that's not already present (or not obvious) in the
|
||||||
|
// print-out of x and the matcher's description. Whether the match
|
||||||
|
// succeeds is not a factor in deciding whether an explanation is
|
||||||
|
// needed, as sometimes the caller needs to print a failure message
|
||||||
|
// when the match succeeds (e.g. when the matcher is used inside
|
||||||
|
// Not()).
|
||||||
|
//
|
||||||
|
// For example, a "has at least 10 elements" matcher should explain
|
||||||
|
// what the actual element count is, regardless of the match result,
|
||||||
|
// as it is useful information to the reader; on the other hand, an
|
||||||
|
// "is empty" matcher probably only needs to explain what the actual
|
||||||
|
// size is when the match fails, as it's redundant to say that the
|
||||||
|
// size is 0 when the value is already known to be empty.
|
||||||
|
//
|
||||||
|
// You should override this method when defining a new matcher.
|
||||||
|
//
|
||||||
|
// It's the responsibility of the caller (Google Test) to guarantee
|
||||||
|
// that 'listener' is not NULL. This helps to simplify a matcher's
|
||||||
|
// implementation when it doesn't care about the performance, as it
|
||||||
|
// can talk to 'listener' without checking its validity first.
|
||||||
|
// However, in order to implement dummy listeners efficiently,
|
||||||
|
// listener->stream() may be NULL.
|
||||||
|
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
|
||||||
|
|
||||||
|
// Inherits these methods from MatcherDescriberInterface:
|
||||||
|
// virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||||
|
// virtual void DescribeNegationTo(::std::ostream* os) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Converts a MatcherInterface<T> to a MatcherInterface<const T&>.
|
||||||
|
template <typename T>
|
||||||
|
class MatcherInterfaceAdapter : public MatcherInterface<const T&> {
|
||||||
|
public:
|
||||||
|
explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl)
|
||||||
|
: impl_(impl) {}
|
||||||
|
~MatcherInterfaceAdapter() override { delete impl_; }
|
||||||
|
|
||||||
|
void DescribeTo(::std::ostream* os) const override { impl_->DescribeTo(os); }
|
||||||
|
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const override {
|
||||||
|
impl_->DescribeNegationTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MatchAndExplain(const T& x,
|
||||||
|
MatchResultListener* listener) const override {
|
||||||
|
return impl_->MatchAndExplain(x, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const MatcherInterface<T>* const impl_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnyEq {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a == b; }
|
||||||
|
};
|
||||||
|
struct AnyNe {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a != b; }
|
||||||
|
};
|
||||||
|
struct AnyLt {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a < b; }
|
||||||
|
};
|
||||||
|
struct AnyGt {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a > b; }
|
||||||
|
};
|
||||||
|
struct AnyLe {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a <= b; }
|
||||||
|
};
|
||||||
|
struct AnyGe {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a >= b; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// A match result listener that ignores the explanation.
|
||||||
|
class DummyMatchResultListener : public MatchResultListener {
|
||||||
|
public:
|
||||||
|
DummyMatchResultListener() : MatchResultListener(nullptr) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener);
|
||||||
|
};
|
||||||
|
|
||||||
|
// A match result listener that forwards the explanation to a given
|
||||||
|
// ostream. The difference between this and MatchResultListener is
|
||||||
|
// that the former is concrete.
|
||||||
|
class StreamMatchResultListener : public MatchResultListener {
|
||||||
|
public:
|
||||||
|
explicit StreamMatchResultListener(::std::ostream* os)
|
||||||
|
: MatchResultListener(os) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener);
|
||||||
|
};
|
||||||
|
|
||||||
|
// An internal class for implementing Matcher<T>, which will derive
|
||||||
|
// from it. We put functionalities common to all Matcher<T>
|
||||||
|
// specializations here to avoid code duplication.
|
||||||
|
template <typename T>
|
||||||
|
class MatcherBase {
|
||||||
|
public:
|
||||||
|
// Returns true if and only if the matcher matches x; also explains the
|
||||||
|
// match result to 'listener'.
|
||||||
|
bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
|
||||||
|
return impl_->MatchAndExplain(x, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if and only if this matcher matches x.
|
||||||
|
bool Matches(const T& x) const {
|
||||||
|
DummyMatchResultListener dummy;
|
||||||
|
return MatchAndExplain(x, &dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describes this matcher to an ostream.
|
||||||
|
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
|
||||||
|
|
||||||
|
// Describes the negation of this matcher to an ostream.
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
impl_->DescribeNegationTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explains why x matches, or doesn't match, the matcher.
|
||||||
|
void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {
|
||||||
|
StreamMatchResultListener listener(os);
|
||||||
|
MatchAndExplain(x, &listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the describer for this matcher object; retains ownership
|
||||||
|
// of the describer, which is only guaranteed to be alive when
|
||||||
|
// this matcher object is alive.
|
||||||
|
const MatcherDescriberInterface* GetDescriber() const {
|
||||||
|
return impl_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MatcherBase() {}
|
||||||
|
|
||||||
|
// Constructs a matcher from its implementation.
|
||||||
|
explicit MatcherBase(const MatcherInterface<const T&>* impl) : impl_(impl) {}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
explicit MatcherBase(
|
||||||
|
const MatcherInterface<U>* impl,
|
||||||
|
typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
|
||||||
|
nullptr)
|
||||||
|
: impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
|
||||||
|
|
||||||
|
MatcherBase(const MatcherBase&) = default;
|
||||||
|
MatcherBase& operator=(const MatcherBase&) = default;
|
||||||
|
MatcherBase(MatcherBase&&) = default;
|
||||||
|
MatcherBase& operator=(MatcherBase&&) = default;
|
||||||
|
|
||||||
|
virtual ~MatcherBase() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<const MatcherInterface<const T&>> impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
|
||||||
|
// object that can check whether a value of type T matches. The
|
||||||
|
// implementation of Matcher<T> is just a std::shared_ptr to const
|
||||||
|
// MatcherInterface<T>. Don't inherit from Matcher!
|
||||||
|
template <typename T>
|
||||||
|
class Matcher : public internal::MatcherBase<T> {
|
||||||
|
public:
|
||||||
|
// Constructs a null matcher. Needed for storing Matcher objects in STL
|
||||||
|
// containers. A default-constructed matcher is not yet initialized. You
|
||||||
|
// cannot use it until a valid value has been assigned to it.
|
||||||
|
explicit Matcher() {} // NOLINT
|
||||||
|
|
||||||
|
// Constructs a matcher from its implementation.
|
||||||
|
explicit Matcher(const MatcherInterface<const T&>* impl)
|
||||||
|
: internal::MatcherBase<T>(impl) {}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
explicit Matcher(
|
||||||
|
const MatcherInterface<U>* impl,
|
||||||
|
typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
|
||||||
|
nullptr)
|
||||||
|
: internal::MatcherBase<T>(impl) {}
|
||||||
|
|
||||||
|
// Implicit constructor here allows people to write
|
||||||
|
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
|
||||||
|
Matcher(T value); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
|
// The following two specializations allow the user to write str
|
||||||
|
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
|
||||||
|
// matcher is expected.
|
||||||
|
template <>
|
||||||
|
class GTEST_API_ Matcher<const std::string&>
|
||||||
|
: public internal::MatcherBase<const std::string&> {
|
||||||
|
public:
|
||||||
|
Matcher() {}
|
||||||
|
|
||||||
|
explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
||||||
|
: internal::MatcherBase<const std::string&>(impl) {}
|
||||||
|
|
||||||
|
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||||
|
// str is a std::string object.
|
||||||
|
Matcher(const std::string& s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||||
|
Matcher(const char* s); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class GTEST_API_ Matcher<std::string>
|
||||||
|
: public internal::MatcherBase<std::string> {
|
||||||
|
public:
|
||||||
|
Matcher() {}
|
||||||
|
|
||||||
|
explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
||||||
|
: internal::MatcherBase<std::string>(impl) {}
|
||||||
|
explicit Matcher(const MatcherInterface<std::string>* impl)
|
||||||
|
: internal::MatcherBase<std::string>(impl) {}
|
||||||
|
|
||||||
|
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||||
|
// str is a string object.
|
||||||
|
Matcher(const std::string& s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||||
|
Matcher(const char* s); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
// The following two specializations allow the user to write str
|
||||||
|
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
|
||||||
|
// matcher is expected.
|
||||||
|
template <>
|
||||||
|
class GTEST_API_ Matcher<const internal::StringView&>
|
||||||
|
: public internal::MatcherBase<const internal::StringView&> {
|
||||||
|
public:
|
||||||
|
Matcher() {}
|
||||||
|
|
||||||
|
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
|
||||||
|
: internal::MatcherBase<const internal::StringView&>(impl) {}
|
||||||
|
|
||||||
|
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||||
|
// str is a std::string object.
|
||||||
|
Matcher(const std::string& s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||||
|
Matcher(const char* s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to pass absl::string_views or std::string_views directly.
|
||||||
|
Matcher(internal::StringView s); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class GTEST_API_ Matcher<internal::StringView>
|
||||||
|
: public internal::MatcherBase<internal::StringView> {
|
||||||
|
public:
|
||||||
|
Matcher() {}
|
||||||
|
|
||||||
|
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
|
||||||
|
: internal::MatcherBase<internal::StringView>(impl) {}
|
||||||
|
explicit Matcher(const MatcherInterface<internal::StringView>* impl)
|
||||||
|
: internal::MatcherBase<internal::StringView>(impl) {}
|
||||||
|
|
||||||
|
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||||
|
// str is a std::string object.
|
||||||
|
Matcher(const std::string& s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||||
|
Matcher(const char* s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to pass absl::string_views or std::string_views directly.
|
||||||
|
Matcher(internal::StringView s); // NOLINT
|
||||||
|
};
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
|
||||||
|
// Prints a matcher in a human-readable format.
|
||||||
|
template <typename T>
|
||||||
|
std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
|
||||||
|
matcher.DescribeTo(&os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The PolymorphicMatcher class template makes it easy to implement a
|
||||||
|
// polymorphic matcher (i.e. a matcher that can match values of more
|
||||||
|
// than one type, e.g. Eq(n) and NotNull()).
|
||||||
|
//
|
||||||
|
// To define a polymorphic matcher, a user should provide an Impl
|
||||||
|
// class that has a DescribeTo() method and a DescribeNegationTo()
|
||||||
|
// method, and define a member function (or member function template)
|
||||||
|
//
|
||||||
|
// bool MatchAndExplain(const Value& value,
|
||||||
|
// MatchResultListener* listener) const;
|
||||||
|
//
|
||||||
|
// See the definition of NotNull() for a complete example.
|
||||||
|
template <class Impl>
|
||||||
|
class PolymorphicMatcher {
|
||||||
|
public:
|
||||||
|
explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
|
||||||
|
|
||||||
|
// Returns a mutable reference to the underlying matcher
|
||||||
|
// implementation object.
|
||||||
|
Impl& mutable_impl() { return impl_; }
|
||||||
|
|
||||||
|
// Returns an immutable reference to the underlying matcher
|
||||||
|
// implementation object.
|
||||||
|
const Impl& impl() const { return impl_; }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
operator Matcher<T>() const {
|
||||||
|
return Matcher<T>(new MonomorphicImpl<const T&>(impl_));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
class MonomorphicImpl : public MatcherInterface<T> {
|
||||||
|
public:
|
||||||
|
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
|
||||||
|
|
||||||
|
void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }
|
||||||
|
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const override {
|
||||||
|
impl_.DescribeNegationTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MatchAndExplain(T x, MatchResultListener* listener) const override {
|
||||||
|
return impl_.MatchAndExplain(x, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Impl impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
Impl impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates a matcher from its implementation.
|
||||||
|
// DEPRECATED: Especially in the generic code, prefer:
|
||||||
|
// Matcher<T>(new MyMatcherImpl<const T&>(...));
|
||||||
|
//
|
||||||
|
// MakeMatcher may create a Matcher that accepts its argument by value, which
|
||||||
|
// leads to unnecessary copies & lack of support for non-copyable types.
|
||||||
|
template <typename T>
|
||||||
|
inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
|
||||||
|
return Matcher<T>(impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher from its implementation. This is
|
||||||
|
// easier to use than the PolymorphicMatcher<Impl> constructor as it
|
||||||
|
// doesn't require you to explicitly write the template argument, e.g.
|
||||||
|
//
|
||||||
|
// MakePolymorphicMatcher(foo);
|
||||||
|
// vs
|
||||||
|
// PolymorphicMatcher<TypeOfFoo>(foo);
|
||||||
|
template <class Impl>
|
||||||
|
inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
|
||||||
|
return PolymorphicMatcher<Impl>(impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
// Implements a matcher that compares a given value with a
|
||||||
|
// pre-supplied value using one of the ==, <=, <, etc, operators. The
|
||||||
|
// two values being compared don't have to have the same type.
|
||||||
|
//
|
||||||
|
// The matcher defined here is polymorphic (for example, Eq(5) can be
|
||||||
|
// used to match an int, a short, a double, etc). Therefore we use
|
||||||
|
// a template type conversion operator in the implementation.
|
||||||
|
//
|
||||||
|
// The following template definition assumes that the Rhs parameter is
|
||||||
|
// a "bare" type (i.e. neither 'const T' nor 'T&').
|
||||||
|
template <typename D, typename Rhs, typename Op>
|
||||||
|
class ComparisonBase {
|
||||||
|
public:
|
||||||
|
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
|
||||||
|
template <typename Lhs>
|
||||||
|
operator Matcher<Lhs>() const {
|
||||||
|
return Matcher<Lhs>(new Impl<const Lhs&>(rhs_));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
static const T& Unwrap(const T& v) { return v; }
|
||||||
|
template <typename T>
|
||||||
|
static const T& Unwrap(std::reference_wrapper<T> v) { return v; }
|
||||||
|
|
||||||
|
template <typename Lhs, typename = Rhs>
|
||||||
|
class Impl : public MatcherInterface<Lhs> {
|
||||||
|
public:
|
||||||
|
explicit Impl(const Rhs& rhs) : rhs_(rhs) {}
|
||||||
|
bool MatchAndExplain(Lhs lhs,
|
||||||
|
MatchResultListener* /* listener */) const override {
|
||||||
|
return Op()(lhs, Unwrap(rhs_));
|
||||||
|
}
|
||||||
|
void DescribeTo(::std::ostream* os) const override {
|
||||||
|
*os << D::Desc() << " ";
|
||||||
|
UniversalPrint(Unwrap(rhs_), os);
|
||||||
|
}
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const override {
|
||||||
|
*os << D::NegatedDesc() << " ";
|
||||||
|
UniversalPrint(Unwrap(rhs_), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Rhs rhs_;
|
||||||
|
};
|
||||||
|
Rhs rhs_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Rhs>
|
||||||
|
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
|
||||||
|
public:
|
||||||
|
explicit EqMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
|
||||||
|
static const char* Desc() { return "is equal to"; }
|
||||||
|
static const char* NegatedDesc() { return "isn't equal to"; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
|
||||||
|
public:
|
||||||
|
explicit NeMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
|
||||||
|
static const char* Desc() { return "isn't equal to"; }
|
||||||
|
static const char* NegatedDesc() { return "is equal to"; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
|
||||||
|
public:
|
||||||
|
explicit LtMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
|
||||||
|
static const char* Desc() { return "is <"; }
|
||||||
|
static const char* NegatedDesc() { return "isn't <"; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
|
||||||
|
public:
|
||||||
|
explicit GtMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
|
||||||
|
static const char* Desc() { return "is >"; }
|
||||||
|
static const char* NegatedDesc() { return "isn't >"; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
|
||||||
|
public:
|
||||||
|
explicit LeMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
|
||||||
|
static const char* Desc() { return "is <="; }
|
||||||
|
static const char* NegatedDesc() { return "isn't <="; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
|
||||||
|
public:
|
||||||
|
explicit GeMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
|
||||||
|
static const char* Desc() { return "is >="; }
|
||||||
|
static const char* NegatedDesc() { return "isn't >="; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implements polymorphic matchers MatchesRegex(regex) and
|
||||||
|
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
|
||||||
|
// T can be converted to a string.
|
||||||
|
class MatchesRegexMatcher {
|
||||||
|
public:
|
||||||
|
MatchesRegexMatcher(const RE* regex, bool full_match)
|
||||||
|
: regex_(regex), full_match_(full_match) {}
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
bool MatchAndExplain(const internal::StringView& s,
|
||||||
|
MatchResultListener* listener) const {
|
||||||
|
return MatchAndExplain(std::string(s), listener);
|
||||||
|
}
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
|
||||||
|
// Accepts pointer types, particularly:
|
||||||
|
// const char*
|
||||||
|
// char*
|
||||||
|
// const wchar_t*
|
||||||
|
// wchar_t*
|
||||||
|
template <typename CharType>
|
||||||
|
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
|
||||||
|
return s != nullptr && MatchAndExplain(std::string(s), listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matches anything that can convert to std::string.
|
||||||
|
//
|
||||||
|
// This is a template, not just a plain function with const std::string&,
|
||||||
|
// because absl::string_view has some interfering non-explicit constructors.
|
||||||
|
template <class MatcheeStringType>
|
||||||
|
bool MatchAndExplain(const MatcheeStringType& s,
|
||||||
|
MatchResultListener* /* listener */) const {
|
||||||
|
const std::string& s2(s);
|
||||||
|
return full_match_ ? RE::FullMatch(s2, *regex_)
|
||||||
|
: RE::PartialMatch(s2, *regex_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeTo(::std::ostream* os) const {
|
||||||
|
*os << (full_match_ ? "matches" : "contains") << " regular expression ";
|
||||||
|
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
*os << "doesn't " << (full_match_ ? "match" : "contain")
|
||||||
|
<< " regular expression ";
|
||||||
|
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::shared_ptr<const RE> regex_;
|
||||||
|
const bool full_match_;
|
||||||
|
};
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Matches a string that fully matches regular expression 'regex'.
|
||||||
|
// The matcher takes ownership of 'regex'.
|
||||||
|
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
|
||||||
|
const internal::RE* regex) {
|
||||||
|
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
|
||||||
|
}
|
||||||
|
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
|
||||||
|
const std::string& regex) {
|
||||||
|
return MatchesRegex(new internal::RE(regex));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matches a string that contains regular expression 'regex'.
|
||||||
|
// The matcher takes ownership of 'regex'.
|
||||||
|
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
|
||||||
|
const internal::RE* regex) {
|
||||||
|
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
|
||||||
|
}
|
||||||
|
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
|
||||||
|
const std::string& regex) {
|
||||||
|
return ContainsRegex(new internal::RE(regex));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything equal to x.
|
||||||
|
// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
|
||||||
|
// wouldn't compile.
|
||||||
|
template <typename T>
|
||||||
|
inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
|
||||||
|
|
||||||
|
// Constructs a Matcher<T> from a 'value' of type T. The constructed
|
||||||
|
// matcher matches any value that's equal to 'value'.
|
||||||
|
template <typename T>
|
||||||
|
Matcher<T>::Matcher(T value) { *this = Eq(value); }
|
||||||
|
|
||||||
|
// Creates a monomorphic matcher that matches anything with type Lhs
|
||||||
|
// and equal to rhs. A user may need to use this instead of Eq(...)
|
||||||
|
// in order to resolve an overloading ambiguity.
|
||||||
|
//
|
||||||
|
// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
|
||||||
|
// or Matcher<T>(x), but more readable than the latter.
|
||||||
|
//
|
||||||
|
// We could define similar monomorphic matchers for other comparison
|
||||||
|
// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
|
||||||
|
// it yet as those are used much less than Eq() in practice. A user
|
||||||
|
// can always write Matcher<T>(Lt(5)) to be explicit about the type,
|
||||||
|
// for example.
|
||||||
|
template <typename Lhs, typename Rhs>
|
||||||
|
inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything >= x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::GeMatcher<Rhs> Ge(Rhs x) {
|
||||||
|
return internal::GeMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything > x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::GtMatcher<Rhs> Gt(Rhs x) {
|
||||||
|
return internal::GtMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything <= x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::LeMatcher<Rhs> Le(Rhs x) {
|
||||||
|
return internal::LeMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything < x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::LtMatcher<Rhs> Lt(Rhs x) {
|
||||||
|
return internal::LtMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything != x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::NeMatcher<Rhs> Ne(Rhs x) {
|
||||||
|
return internal::NeMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
|
@ -0,0 +1,219 @@
|
||||||
|
// Copyright 2005, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// This header file defines the Message class.
|
||||||
|
//
|
||||||
|
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
|
||||||
|
// leave some internal implementation details in this header file.
|
||||||
|
// They are clearly marked by comments like this:
|
||||||
|
//
|
||||||
|
// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||||
|
//
|
||||||
|
// Such code is NOT meant to be used by a user directly, and is subject
|
||||||
|
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
||||||
|
// program!
|
||||||
|
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
|
// Ensures that there is at least one operator<< in the global namespace.
|
||||||
|
// See Message& operator<<(...) below for why.
|
||||||
|
void operator<<(const testing::internal::Secret&, int);
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// The Message class works like an ostream repeater.
|
||||||
|
//
|
||||||
|
// Typical usage:
|
||||||
|
//
|
||||||
|
// 1. You stream a bunch of values to a Message object.
|
||||||
|
// It will remember the text in a stringstream.
|
||||||
|
// 2. Then you stream the Message object to an ostream.
|
||||||
|
// This causes the text in the Message to be streamed
|
||||||
|
// to the ostream.
|
||||||
|
//
|
||||||
|
// For example;
|
||||||
|
//
|
||||||
|
// testing::Message foo;
|
||||||
|
// foo << 1 << " != " << 2;
|
||||||
|
// std::cout << foo;
|
||||||
|
//
|
||||||
|
// will print "1 != 2".
|
||||||
|
//
|
||||||
|
// Message is not intended to be inherited from. In particular, its
|
||||||
|
// destructor is not virtual.
|
||||||
|
//
|
||||||
|
// Note that stringstream behaves differently in gcc and in MSVC. You
|
||||||
|
// can stream a NULL char pointer to it in the former, but not in the
|
||||||
|
// latter (it causes an access violation if you do). The Message
|
||||||
|
// class hides this difference by treating a NULL char pointer as
|
||||||
|
// "(null)".
|
||||||
|
class GTEST_API_ Message {
|
||||||
|
private:
|
||||||
|
// The type of basic IO manipulators (endl, ends, and flush) for
|
||||||
|
// narrow streams.
|
||||||
|
typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructs an empty Message.
|
||||||
|
Message();
|
||||||
|
|
||||||
|
// Copy constructor.
|
||||||
|
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
|
||||||
|
*ss_ << msg.GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a Message from a C-string.
|
||||||
|
explicit Message(const char* str) : ss_(new ::std::stringstream) {
|
||||||
|
*ss_ << str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Streams a non-pointer value to this object.
|
||||||
|
template <typename T>
|
||||||
|
inline Message& operator <<(const T& val) {
|
||||||
|
// Some libraries overload << for STL containers. These
|
||||||
|
// overloads are defined in the global namespace instead of ::std.
|
||||||
|
//
|
||||||
|
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
|
||||||
|
// overloads are visible in either the std namespace or the global
|
||||||
|
// namespace, but not other namespaces, including the testing
|
||||||
|
// namespace which Google Test's Message class is in.
|
||||||
|
//
|
||||||
|
// To allow STL containers (and other types that has a << operator
|
||||||
|
// defined in the global namespace) to be used in Google Test
|
||||||
|
// assertions, testing::Message must access the custom << operator
|
||||||
|
// from the global namespace. With this using declaration,
|
||||||
|
// overloads of << defined in the global namespace and those
|
||||||
|
// visible via Koenig lookup are both exposed in this function.
|
||||||
|
using ::operator <<;
|
||||||
|
*ss_ << val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Streams a pointer value to this object.
|
||||||
|
//
|
||||||
|
// This function is an overload of the previous one. When you
|
||||||
|
// stream a pointer to a Message, this definition will be used as it
|
||||||
|
// is more specialized. (The C++ Standard, section
|
||||||
|
// [temp.func.order].) If you stream a non-pointer, then the
|
||||||
|
// previous definition will be used.
|
||||||
|
//
|
||||||
|
// The reason for this overload is that streaming a NULL pointer to
|
||||||
|
// ostream is undefined behavior. Depending on the compiler, you
|
||||||
|
// may get "0", "(nil)", "(null)", or an access violation. To
|
||||||
|
// ensure consistent result across compilers, we always treat NULL
|
||||||
|
// as "(null)".
|
||||||
|
template <typename T>
|
||||||
|
inline Message& operator <<(T* const& pointer) { // NOLINT
|
||||||
|
if (pointer == nullptr) {
|
||||||
|
*ss_ << "(null)";
|
||||||
|
} else {
|
||||||
|
*ss_ << pointer;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since the basic IO manipulators are overloaded for both narrow
|
||||||
|
// and wide streams, we have to provide this specialized definition
|
||||||
|
// of operator <<, even though its body is the same as the
|
||||||
|
// templatized version above. Without this definition, streaming
|
||||||
|
// endl or other basic IO manipulators to Message will confuse the
|
||||||
|
// compiler.
|
||||||
|
Message& operator <<(BasicNarrowIoManip val) {
|
||||||
|
*ss_ << val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instead of 1/0, we want to see true/false for bool values.
|
||||||
|
Message& operator <<(bool b) {
|
||||||
|
return *this << (b ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
// These two overloads allow streaming a wide C string to a Message
|
||||||
|
// using the UTF-8 encoding.
|
||||||
|
Message& operator <<(const wchar_t* wide_c_str);
|
||||||
|
Message& operator <<(wchar_t* wide_c_str);
|
||||||
|
|
||||||
|
#if GTEST_HAS_STD_WSTRING
|
||||||
|
// Converts the given wide string to a narrow string using the UTF-8
|
||||||
|
// encoding, and streams the result to this Message object.
|
||||||
|
Message& operator <<(const ::std::wstring& wstr);
|
||||||
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
|
// Gets the text streamed to this object so far as an std::string.
|
||||||
|
// Each '\0' character in the buffer is replaced with "\\0".
|
||||||
|
//
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||||
|
std::string GetString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// We'll hold the text streamed to this object here.
|
||||||
|
const std::unique_ptr< ::std::stringstream> ss_;
|
||||||
|
|
||||||
|
// We declare (but don't implement) this to prevent the compiler
|
||||||
|
// from implementing the assignment operator.
|
||||||
|
void operator=(const Message&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Streams a Message to an ostream.
|
||||||
|
inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
|
||||||
|
return os << sb.GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Converts a streamable value to an std::string. A NULL pointer is
|
||||||
|
// converted to "(null)". When the input value is a ::string,
|
||||||
|
// ::std::string, ::wstring, or ::std::wstring object, each NUL
|
||||||
|
// character in it is replaced with "\\0".
|
||||||
|
template <typename T>
|
||||||
|
std::string StreamableToString(const T& streamable) {
|
||||||
|
return (Message() << streamable).GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
|
@ -0,0 +1,511 @@
|
||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Macros and functions for implementing parameterized tests
|
||||||
|
// in Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||||
|
//
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||||
|
|
||||||
|
|
||||||
|
// Value-parameterized tests allow you to test your code with different
|
||||||
|
// parameters without writing multiple copies of the same test.
|
||||||
|
//
|
||||||
|
// Here is how you use value-parameterized tests:
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
// To write value-parameterized tests, first you should define a fixture
|
||||||
|
// class. It is usually derived from testing::TestWithParam<T> (see below for
|
||||||
|
// another inheritance scheme that's sometimes useful in more complicated
|
||||||
|
// class hierarchies), where the type of your parameter values.
|
||||||
|
// TestWithParam<T> is itself derived from testing::Test. T can be any
|
||||||
|
// copyable type. If it's a raw pointer, you are responsible for managing the
|
||||||
|
// lifespan of the pointed values.
|
||||||
|
|
||||||
|
class FooTest : public ::testing::TestWithParam<const char*> {
|
||||||
|
// You can implement all the usual class fixture members here.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Then, use the TEST_P macro to define as many parameterized tests
|
||||||
|
// for this fixture as you want. The _P suffix is for "parameterized"
|
||||||
|
// or "pattern", whichever you prefer to think.
|
||||||
|
|
||||||
|
TEST_P(FooTest, DoesBlah) {
|
||||||
|
// Inside a test, access the test parameter with the GetParam() method
|
||||||
|
// of the TestWithParam<T> class:
|
||||||
|
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(FooTest, HasBlahBlah) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test
|
||||||
|
// case with any set of parameters you want. Google Test defines a number
|
||||||
|
// of functions for generating test parameters. They return what we call
|
||||||
|
// (surprise!) parameter generators. Here is a summary of them, which
|
||||||
|
// are all in the testing namespace:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Range(begin, end [, step]) - Yields values {begin, begin+step,
|
||||||
|
// begin+step+step, ...}. The values do not
|
||||||
|
// include end. step defaults to 1.
|
||||||
|
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
|
||||||
|
// ValuesIn(container) - Yields values from a C-style array, an STL
|
||||||
|
// ValuesIn(begin,end) container, or an iterator range [begin, end).
|
||||||
|
// Bool() - Yields sequence {false, true}.
|
||||||
|
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
|
||||||
|
// for the math savvy) of the values generated
|
||||||
|
// by the N generators.
|
||||||
|
//
|
||||||
|
// For more details, see comments at the definitions of these functions below
|
||||||
|
// in this file.
|
||||||
|
//
|
||||||
|
// The following statement will instantiate tests from the FooTest test suite
|
||||||
|
// each with parameter values "meeny", "miny", and "moe".
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(InstantiationName,
|
||||||
|
FooTest,
|
||||||
|
Values("meeny", "miny", "moe"));
|
||||||
|
|
||||||
|
// To distinguish different instances of the pattern, (yes, you
|
||||||
|
// can instantiate it more than once) the first argument to the
|
||||||
|
// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the
|
||||||
|
// actual test suite name. Remember to pick unique prefixes for different
|
||||||
|
// instantiations. The tests from the instantiation above will have
|
||||||
|
// these names:
|
||||||
|
//
|
||||||
|
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
|
||||||
|
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
|
||||||
|
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
|
||||||
|
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
|
||||||
|
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
|
||||||
|
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
|
||||||
|
//
|
||||||
|
// You can use these names in --gtest_filter.
|
||||||
|
//
|
||||||
|
// This statement will instantiate all tests from FooTest again, each
|
||||||
|
// with parameter values "cat" and "dog":
|
||||||
|
|
||||||
|
const char* pets[] = {"cat", "dog"};
|
||||||
|
INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
|
||||||
|
|
||||||
|
// The tests from the instantiation above will have these names:
|
||||||
|
//
|
||||||
|
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
|
||||||
|
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
|
||||||
|
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
|
||||||
|
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
|
||||||
|
//
|
||||||
|
// Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests
|
||||||
|
// in the given test suite, whether their definitions come before or
|
||||||
|
// AFTER the INSTANTIATE_TEST_SUITE_P statement.
|
||||||
|
//
|
||||||
|
// Please also note that generator expressions (including parameters to the
|
||||||
|
// generators) are evaluated in InitGoogleTest(), after main() has started.
|
||||||
|
// This allows the user on one hand, to adjust generator parameters in order
|
||||||
|
// to dynamically determine a set of tests to run and on the other hand,
|
||||||
|
// give the user a chance to inspect the generated tests with Google Test
|
||||||
|
// reflection API before RUN_ALL_TESTS() is executed.
|
||||||
|
//
|
||||||
|
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
|
||||||
|
// for more examples.
|
||||||
|
//
|
||||||
|
// In the future, we plan to publish the API for defining new parameter
|
||||||
|
// generators. But for now this interface remains part of the internal
|
||||||
|
// implementation and is subject to change.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// A parameterized test fixture must be derived from testing::Test and from
|
||||||
|
// testing::WithParamInterface<T>, where T is the type of the parameter
|
||||||
|
// values. Inheriting from TestWithParam<T> satisfies that requirement because
|
||||||
|
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
|
||||||
|
// complicated hierarchies, however, it is occasionally useful to inherit
|
||||||
|
// separately from Test and WithParamInterface. For example:
|
||||||
|
|
||||||
|
class BaseTest : public ::testing::Test {
|
||||||
|
// You can inherit all the usual members for a non-parameterized test
|
||||||
|
// fixture here.
|
||||||
|
};
|
||||||
|
|
||||||
|
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
|
||||||
|
// The usual test fixture members go here too.
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(BaseTest, HasFoo) {
|
||||||
|
// This is an ordinary non-parameterized test.
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(DerivedTest, DoesBlah) {
|
||||||
|
// GetParam works just the same here as if you inherit from TestWithParam.
|
||||||
|
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-param-util.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// Functions producing parameter generators.
|
||||||
|
//
|
||||||
|
// Google Test uses these generators to produce parameters for value-
|
||||||
|
// parameterized tests. When a parameterized test suite is instantiated
|
||||||
|
// with a particular generator, Google Test creates and runs tests
|
||||||
|
// for each element in the sequence produced by the generator.
|
||||||
|
//
|
||||||
|
// In the following sample, tests from test suite FooTest are instantiated
|
||||||
|
// each three times with parameter values 3, 5, and 8:
|
||||||
|
//
|
||||||
|
// class FooTest : public TestWithParam<int> { ... };
|
||||||
|
//
|
||||||
|
// TEST_P(FooTest, TestThis) {
|
||||||
|
// }
|
||||||
|
// TEST_P(FooTest, TestThat) {
|
||||||
|
// }
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8));
|
||||||
|
//
|
||||||
|
|
||||||
|
// Range() returns generators providing sequences of values in a range.
|
||||||
|
//
|
||||||
|
// Synopsis:
|
||||||
|
// Range(start, end)
|
||||||
|
// - returns a generator producing a sequence of values {start, start+1,
|
||||||
|
// start+2, ..., }.
|
||||||
|
// Range(start, end, step)
|
||||||
|
// - returns a generator producing a sequence of values {start, start+step,
|
||||||
|
// start+step+step, ..., }.
|
||||||
|
// Notes:
|
||||||
|
// * The generated sequences never include end. For example, Range(1, 5)
|
||||||
|
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
|
||||||
|
// returns a generator producing {1, 3, 5, 7}.
|
||||||
|
// * start and end must have the same type. That type may be any integral or
|
||||||
|
// floating-point type or a user defined type satisfying these conditions:
|
||||||
|
// * It must be assignable (have operator=() defined).
|
||||||
|
// * It must have operator+() (operator+(int-compatible type) for
|
||||||
|
// two-operand version).
|
||||||
|
// * It must have operator<() defined.
|
||||||
|
// Elements in the resulting sequences will also have that type.
|
||||||
|
// * Condition start < end must be satisfied in order for resulting sequences
|
||||||
|
// to contain any elements.
|
||||||
|
//
|
||||||
|
template <typename T, typename IncrementT>
|
||||||
|
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
|
||||||
|
return internal::ParamGenerator<T>(
|
||||||
|
new internal::RangeGenerator<T, IncrementT>(start, end, step));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
internal::ParamGenerator<T> Range(T start, T end) {
|
||||||
|
return Range(start, end, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValuesIn() function allows generation of tests with parameters coming from
|
||||||
|
// a container.
|
||||||
|
//
|
||||||
|
// Synopsis:
|
||||||
|
// ValuesIn(const T (&array)[N])
|
||||||
|
// - returns a generator producing sequences with elements from
|
||||||
|
// a C-style array.
|
||||||
|
// ValuesIn(const Container& container)
|
||||||
|
// - returns a generator producing sequences with elements from
|
||||||
|
// an STL-style container.
|
||||||
|
// ValuesIn(Iterator begin, Iterator end)
|
||||||
|
// - returns a generator producing sequences with elements from
|
||||||
|
// a range [begin, end) defined by a pair of STL-style iterators. These
|
||||||
|
// iterators can also be plain C pointers.
|
||||||
|
//
|
||||||
|
// Please note that ValuesIn copies the values from the containers
|
||||||
|
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// This instantiates tests from test suite StringTest
|
||||||
|
// each with C-string values of "foo", "bar", and "baz":
|
||||||
|
//
|
||||||
|
// const char* strings[] = {"foo", "bar", "baz"};
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings));
|
||||||
|
//
|
||||||
|
// This instantiates tests from test suite StlStringTest
|
||||||
|
// each with STL strings with values "a" and "b":
|
||||||
|
//
|
||||||
|
// ::std::vector< ::std::string> GetParameterStrings() {
|
||||||
|
// ::std::vector< ::std::string> v;
|
||||||
|
// v.push_back("a");
|
||||||
|
// v.push_back("b");
|
||||||
|
// return v;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(CharSequence,
|
||||||
|
// StlStringTest,
|
||||||
|
// ValuesIn(GetParameterStrings()));
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// This will also instantiate tests from CharTest
|
||||||
|
// each with parameter values 'a' and 'b':
|
||||||
|
//
|
||||||
|
// ::std::list<char> GetParameterChars() {
|
||||||
|
// ::std::list<char> list;
|
||||||
|
// list.push_back('a');
|
||||||
|
// list.push_back('b');
|
||||||
|
// return list;
|
||||||
|
// }
|
||||||
|
// ::std::list<char> l = GetParameterChars();
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(CharSequence2,
|
||||||
|
// CharTest,
|
||||||
|
// ValuesIn(l.begin(), l.end()));
|
||||||
|
//
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
internal::ParamGenerator<
|
||||||
|
typename std::iterator_traits<ForwardIterator>::value_type>
|
||||||
|
ValuesIn(ForwardIterator begin, ForwardIterator end) {
|
||||||
|
typedef typename std::iterator_traits<ForwardIterator>::value_type ParamType;
|
||||||
|
return internal::ParamGenerator<ParamType>(
|
||||||
|
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, size_t N>
|
||||||
|
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
|
||||||
|
return ValuesIn(array, array + N);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Container>
|
||||||
|
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||||
|
const Container& container) {
|
||||||
|
return ValuesIn(container.begin(), container.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values() allows generating tests from explicitly specified list of
|
||||||
|
// parameters.
|
||||||
|
//
|
||||||
|
// Synopsis:
|
||||||
|
// Values(T v1, T v2, ..., T vN)
|
||||||
|
// - returns a generator producing sequences with elements v1, v2, ..., vN.
|
||||||
|
//
|
||||||
|
// For example, this instantiates tests from test suite BarTest each
|
||||||
|
// with values "one", "two", and "three":
|
||||||
|
//
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(NumSequence,
|
||||||
|
// BarTest,
|
||||||
|
// Values("one", "two", "three"));
|
||||||
|
//
|
||||||
|
// This instantiates tests from test suite BazTest each with values 1, 2, 3.5.
|
||||||
|
// The exact type of values will depend on the type of parameter in BazTest.
|
||||||
|
//
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
|
||||||
|
//
|
||||||
|
//
|
||||||
|
template <typename... T>
|
||||||
|
internal::ValueArray<T...> Values(T... v) {
|
||||||
|
return internal::ValueArray<T...>(std::move(v)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool() allows generating tests with parameters in a set of (false, true).
|
||||||
|
//
|
||||||
|
// Synopsis:
|
||||||
|
// Bool()
|
||||||
|
// - returns a generator producing sequences with elements {false, true}.
|
||||||
|
//
|
||||||
|
// It is useful when testing code that depends on Boolean flags. Combinations
|
||||||
|
// of multiple flags can be tested when several Bool()'s are combined using
|
||||||
|
// Combine() function.
|
||||||
|
//
|
||||||
|
// In the following example all tests in the test suite FlagDependentTest
|
||||||
|
// will be instantiated twice with parameters false and true.
|
||||||
|
//
|
||||||
|
// class FlagDependentTest : public testing::TestWithParam<bool> {
|
||||||
|
// virtual void SetUp() {
|
||||||
|
// external_flag = GetParam();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());
|
||||||
|
//
|
||||||
|
inline internal::ParamGenerator<bool> Bool() {
|
||||||
|
return Values(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine() allows the user to combine two or more sequences to produce
|
||||||
|
// values of a Cartesian product of those sequences' elements.
|
||||||
|
//
|
||||||
|
// Synopsis:
|
||||||
|
// Combine(gen1, gen2, ..., genN)
|
||||||
|
// - returns a generator producing sequences with elements coming from
|
||||||
|
// the Cartesian product of elements from the sequences generated by
|
||||||
|
// gen1, gen2, ..., genN. The sequence elements will have a type of
|
||||||
|
// std::tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
|
||||||
|
// of elements from sequences produces by gen1, gen2, ..., genN.
|
||||||
|
//
|
||||||
|
// Combine can have up to 10 arguments.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// This will instantiate tests in test suite AnimalTest each one with
|
||||||
|
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
||||||
|
// tuple("dog", BLACK), and tuple("dog", WHITE):
|
||||||
|
//
|
||||||
|
// enum Color { BLACK, GRAY, WHITE };
|
||||||
|
// class AnimalTest
|
||||||
|
// : public testing::TestWithParam<std::tuple<const char*, Color> > {...};
|
||||||
|
//
|
||||||
|
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
||||||
|
//
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,
|
||||||
|
// Combine(Values("cat", "dog"),
|
||||||
|
// Values(BLACK, WHITE)));
|
||||||
|
//
|
||||||
|
// This will instantiate tests in FlagDependentTest with all variations of two
|
||||||
|
// Boolean flags:
|
||||||
|
//
|
||||||
|
// class FlagDependentTest
|
||||||
|
// : public testing::TestWithParam<std::tuple<bool, bool> > {
|
||||||
|
// virtual void SetUp() {
|
||||||
|
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
|
||||||
|
// std::tie(external_flag_1, external_flag_2) = GetParam();
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// TEST_P(FlagDependentTest, TestFeature1) {
|
||||||
|
// // Test your code using external_flag_1 and external_flag_2 here.
|
||||||
|
// }
|
||||||
|
// INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest,
|
||||||
|
// Combine(Bool(), Bool()));
|
||||||
|
//
|
||||||
|
template <typename... Generator>
|
||||||
|
internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
||||||
|
return internal::CartesianProductHolder<Generator...>(g...);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEST_P(test_suite_name, test_name) \
|
||||||
|
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
||||||
|
: public test_suite_name { \
|
||||||
|
public: \
|
||||||
|
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
|
||||||
|
void TestBody() override; \
|
||||||
|
\
|
||||||
|
private: \
|
||||||
|
static int AddToRegistry() { \
|
||||||
|
::testing::UnitTest::GetInstance() \
|
||||||
|
->parameterized_test_registry() \
|
||||||
|
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||||
|
GTEST_STRINGIFY_(test_suite_name), \
|
||||||
|
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||||
|
->AddTestPattern( \
|
||||||
|
GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name), \
|
||||||
|
new ::testing::internal::TestMetaFactory<GTEST_TEST_CLASS_NAME_( \
|
||||||
|
test_suite_name, test_name)>()); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||||
|
test_name)); \
|
||||||
|
}; \
|
||||||
|
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||||
|
test_name)::gtest_registering_dummy_ = \
|
||||||
|
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry(); \
|
||||||
|
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
|
||||||
|
|
||||||
|
// The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify
|
||||||
|
// generator and an optional function or functor that generates custom test name
|
||||||
|
// suffixes based on the test parameters. Such a function or functor should
|
||||||
|
// accept one argument of type testing::TestParamInfo<class ParamType>, and
|
||||||
|
// return std::string.
|
||||||
|
//
|
||||||
|
// testing::PrintToStringParamName is a builtin test suffix generator that
|
||||||
|
// returns the value of testing::PrintToString(GetParam()).
|
||||||
|
//
|
||||||
|
// Note: test names must be non-empty, unique, and may only contain ASCII
|
||||||
|
// alphanumeric characters or underscore. Because PrintToString adds quotes
|
||||||
|
// to std::string and C strings, it won't work for these types.
|
||||||
|
|
||||||
|
#define GTEST_EXPAND_(arg) arg
|
||||||
|
#define GTEST_GET_FIRST_(first, ...) first
|
||||||
|
#define GTEST_GET_SECOND_(first, second, ...) second
|
||||||
|
|
||||||
|
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
||||||
|
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
||||||
|
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||||
|
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
||||||
|
} \
|
||||||
|
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
||||||
|
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
||||||
|
if (::testing::internal::AlwaysFalse()) { \
|
||||||
|
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||||
|
__VA_ARGS__, \
|
||||||
|
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||||
|
DUMMY_PARAM_))); \
|
||||||
|
auto t = std::make_tuple(__VA_ARGS__); \
|
||||||
|
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
||||||
|
"Too Many Args!"); \
|
||||||
|
} \
|
||||||
|
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||||
|
__VA_ARGS__, \
|
||||||
|
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||||
|
DUMMY_PARAM_))))(info); \
|
||||||
|
} \
|
||||||
|
static int gtest_##prefix##test_suite_name##_dummy_ \
|
||||||
|
GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
|
::testing::UnitTest::GetInstance() \
|
||||||
|
->parameterized_test_registry() \
|
||||||
|
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||||
|
GTEST_STRINGIFY_(test_suite_name), \
|
||||||
|
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||||
|
->AddTestSuiteInstantiation( \
|
||||||
|
GTEST_STRINGIFY_(prefix), \
|
||||||
|
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||||
|
>est_##prefix##test_suite_name##_EvalGenerateName_, \
|
||||||
|
__FILE__, __LINE__)
|
||||||
|
|
||||||
|
|
||||||
|
// Allow Marking a Parameterized test class as not needing to be instantiated.
|
||||||
|
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
|
||||||
|
namespace gtest_do_not_use_outside_namespace_scope {} \
|
||||||
|
static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \
|
||||||
|
GTEST_STRINGIFY_(T))
|
||||||
|
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
#define INSTANTIATE_TEST_CASE_P \
|
||||||
|
static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \
|
||||||
|
""); \
|
||||||
|
INSTANTIATE_TEST_SUITE_P
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
|
@ -0,0 +1,832 @@
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
// Google Test - The Google C++ Testing and Mocking Framework
|
||||||
|
//
|
||||||
|
// This file implements a universal value printer that can print a
|
||||||
|
// value of any type T:
|
||||||
|
//
|
||||||
|
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||||
|
//
|
||||||
|
// A user can teach this function how to print a class type T by
|
||||||
|
// defining either operator<<() or PrintTo() in the namespace that
|
||||||
|
// defines T. More specifically, the FIRST defined function in the
|
||||||
|
// following list will be used (assuming T is defined in namespace
|
||||||
|
// foo):
|
||||||
|
//
|
||||||
|
// 1. foo::PrintTo(const T&, ostream*)
|
||||||
|
// 2. operator<<(ostream&, const T&) defined in either foo or the
|
||||||
|
// global namespace.
|
||||||
|
//
|
||||||
|
// However if T is an STL-style container then it is printed element-wise
|
||||||
|
// unless foo::PrintTo(const T&, ostream*) is defined. Note that
|
||||||
|
// operator<<() is ignored for container types.
|
||||||
|
//
|
||||||
|
// If none of the above is defined, it will print the debug string of
|
||||||
|
// the value if it is a protocol buffer, or print the raw bytes in the
|
||||||
|
// value otherwise.
|
||||||
|
//
|
||||||
|
// To aid debugging: when T is a reference type, the address of the
|
||||||
|
// value is also printed; when T is a (const) char pointer, both the
|
||||||
|
// pointer value and the NUL-terminated string it points to are
|
||||||
|
// printed.
|
||||||
|
//
|
||||||
|
// We also provide some convenient wrappers:
|
||||||
|
//
|
||||||
|
// // Prints a value to a string. For a (const or not) char
|
||||||
|
// // pointer, the NUL-terminated string (but not the pointer) is
|
||||||
|
// // printed.
|
||||||
|
// std::string ::testing::PrintToString(const T& value);
|
||||||
|
//
|
||||||
|
// // Prints a value tersely: for a reference type, the referenced
|
||||||
|
// // value (but not the address) is printed; for a (const or not) char
|
||||||
|
// // pointer, the NUL-terminated string (but not the pointer) is
|
||||||
|
// // printed.
|
||||||
|
// void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
|
||||||
|
//
|
||||||
|
// // Prints value using the type inferred by the compiler. The difference
|
||||||
|
// // from UniversalTersePrint() is that this function prints both the
|
||||||
|
// // pointer and the NUL-terminated string for a (const or not) char pointer.
|
||||||
|
// void ::testing::internal::UniversalPrint(const T& value, ostream*);
|
||||||
|
//
|
||||||
|
// // Prints the fields of a tuple tersely to a string vector, one
|
||||||
|
// // element for each field. Tuple support must be enabled in
|
||||||
|
// // gtest-port.h.
|
||||||
|
// std::vector<string> UniversalTersePrintTupleFieldsToStrings(
|
||||||
|
// const Tuple& value);
|
||||||
|
//
|
||||||
|
// Known limitation:
|
||||||
|
//
|
||||||
|
// The print primitives print the elements of an STL-style container
|
||||||
|
// using the compiler-inferred type of *iter where iter is a
|
||||||
|
// const_iterator of the container. When const_iterator is an input
|
||||||
|
// iterator but not a forward iterator, this inferred type may not
|
||||||
|
// match value_type, and the print output may be incorrect. In
|
||||||
|
// practice, this is rarely a problem as for most containers
|
||||||
|
// const_iterator is a forward iterator. We'll fix this if there's an
|
||||||
|
// actual need for it. Note that this fix cannot rely on value_type
|
||||||
|
// being defined as many user-defined container types don't have
|
||||||
|
// value_type.
|
||||||
|
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <ostream> // NOLINT
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
#if GTEST_HAS_ABSL
|
||||||
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "absl/types/optional.h"
|
||||||
|
#include "absl/types/variant.h"
|
||||||
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// Definitions in the internal* namespaces are subject to change without notice.
|
||||||
|
// DO NOT USE THEM IN USER CODE!
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void UniversalPrint(const T& value, ::std::ostream* os);
|
||||||
|
|
||||||
|
// Used to print an STL-style container when the user doesn't define
|
||||||
|
// a PrintTo() for it.
|
||||||
|
struct ContainerPrinter {
|
||||||
|
template <typename T,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
||||||
|
!IsRecursiveContainer<T>::value>::type>
|
||||||
|
static void PrintValue(const T& container, std::ostream* os) {
|
||||||
|
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||||
|
*os << '{';
|
||||||
|
size_t count = 0;
|
||||||
|
for (auto&& elem : container) {
|
||||||
|
if (count > 0) {
|
||||||
|
*os << ',';
|
||||||
|
if (count == kMaxCount) { // Enough has been printed.
|
||||||
|
*os << " ...";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*os << ' ';
|
||||||
|
// We cannot call PrintTo(elem, os) here as PrintTo() doesn't
|
||||||
|
// handle `elem` being a native array.
|
||||||
|
internal::UniversalPrint(elem, os);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
*os << ' ';
|
||||||
|
}
|
||||||
|
*os << '}';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used to print a pointer that is neither a char pointer nor a member
|
||||||
|
// pointer, when the user doesn't define PrintTo() for it. (A member
|
||||||
|
// variable pointer or member function pointer doesn't really point to
|
||||||
|
// a location in the address space. Their representation is
|
||||||
|
// implementation-defined. Therefore they will be printed as raw
|
||||||
|
// bytes.)
|
||||||
|
struct FunctionPointerPrinter {
|
||||||
|
template <typename T, typename = typename std::enable_if<
|
||||||
|
std::is_function<T>::value>::type>
|
||||||
|
static void PrintValue(T* p, ::std::ostream* os) {
|
||||||
|
if (p == nullptr) {
|
||||||
|
*os << "NULL";
|
||||||
|
} else {
|
||||||
|
// T is a function type, so '*os << p' doesn't do what we want
|
||||||
|
// (it just prints p as bool). We want to print p as a const
|
||||||
|
// void*.
|
||||||
|
*os << reinterpret_cast<const void*>(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PointerPrinter {
|
||||||
|
template <typename T>
|
||||||
|
static void PrintValue(T* p, ::std::ostream* os) {
|
||||||
|
if (p == nullptr) {
|
||||||
|
*os << "NULL";
|
||||||
|
} else {
|
||||||
|
// T is not a function type. We just call << to print p,
|
||||||
|
// relying on ADL to pick up user-defined << for their pointer
|
||||||
|
// types, if any.
|
||||||
|
*os << p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal_stream {
|
||||||
|
|
||||||
|
struct Sentinel;
|
||||||
|
template <typename Char, typename CharTraits, typename T>
|
||||||
|
Sentinel* operator<<(::std::basic_ostream<Char, CharTraits>& os, const T& x);
|
||||||
|
|
||||||
|
// Check if the user has a user-defined operator<< for their type.
|
||||||
|
//
|
||||||
|
// We put this in its own namespace to inject a custom operator<< that allows us
|
||||||
|
// to probe the type's operator.
|
||||||
|
//
|
||||||
|
// Note that this operator<< takes a generic std::basic_ostream<Char,
|
||||||
|
// CharTraits> type instead of the more restricted std::ostream. If
|
||||||
|
// we define it to take an std::ostream instead, we'll get an
|
||||||
|
// "ambiguous overloads" compiler error when trying to print a type
|
||||||
|
// Foo that supports streaming to std::basic_ostream<Char,
|
||||||
|
// CharTraits>, as the compiler cannot tell whether
|
||||||
|
// operator<<(std::ostream&, const T&) or
|
||||||
|
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
|
||||||
|
// specific.
|
||||||
|
template <typename T>
|
||||||
|
constexpr bool UseStreamOperator() {
|
||||||
|
return !std::is_same<decltype(std::declval<std::ostream&>()
|
||||||
|
<< std::declval<const T&>()),
|
||||||
|
Sentinel*>::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal_stream
|
||||||
|
|
||||||
|
struct StreamPrinter {
|
||||||
|
template <typename T, typename = typename std::enable_if<
|
||||||
|
internal_stream::UseStreamOperator<T>()>::type>
|
||||||
|
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||||
|
*os << value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProtobufPrinter {
|
||||||
|
// We print a protobuf using its ShortDebugString() when the string
|
||||||
|
// doesn't exceed this many characters; otherwise we print it using
|
||||||
|
// DebugString() for better readability.
|
||||||
|
static const size_t kProtobufOneLinerMaxLength = 50;
|
||||||
|
|
||||||
|
template <typename T, typename = typename std::enable_if<
|
||||||
|
internal::IsAProtocolMessage<T>::value>::type>
|
||||||
|
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||||
|
std::string pretty_str = value.ShortDebugString();
|
||||||
|
if (pretty_str.length() > kProtobufOneLinerMaxLength) {
|
||||||
|
pretty_str = "\n" + value.DebugString();
|
||||||
|
}
|
||||||
|
*os << ("<" + pretty_str + ">");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConvertibleToIntegerPrinter {
|
||||||
|
// Since T has no << operator or PrintTo() but can be implicitly
|
||||||
|
// converted to BiggestInt, we print it as a BiggestInt.
|
||||||
|
//
|
||||||
|
// Most likely T is an enum type (either named or unnamed), in which
|
||||||
|
// case printing it as an integer is the desired behavior. In case
|
||||||
|
// T is not an enum, printing it as an integer is the best we can do
|
||||||
|
// given that it has no user-defined printer.
|
||||||
|
static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {
|
||||||
|
*os << value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConvertibleToStringViewPrinter {
|
||||||
|
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
static void PrintValue(internal::StringView value, ::std::ostream* os) {
|
||||||
|
internal::UniversalPrint(value, os);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Prints the given number of bytes in the given object to the given
|
||||||
|
// ostream.
|
||||||
|
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
|
||||||
|
size_t count,
|
||||||
|
::std::ostream* os);
|
||||||
|
struct FallbackPrinter {
|
||||||
|
template <typename T>
|
||||||
|
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||||
|
PrintBytesInObjectTo(
|
||||||
|
static_cast<const unsigned char*>(
|
||||||
|
reinterpret_cast<const void*>(std::addressof(value))),
|
||||||
|
sizeof(value), os);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Try every printer in order and return the first one that works.
|
||||||
|
template <typename T, typename E, typename Printer, typename... Printers>
|
||||||
|
struct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {};
|
||||||
|
|
||||||
|
template <typename T, typename Printer, typename... Printers>
|
||||||
|
struct FindFirstPrinter<
|
||||||
|
T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)),
|
||||||
|
Printer, Printers...> {
|
||||||
|
using type = Printer;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Select the best printer in the following order:
|
||||||
|
// - Print containers (they have begin/end/etc).
|
||||||
|
// - Print function pointers.
|
||||||
|
// - Print object pointers.
|
||||||
|
// - Use the stream operator, if available.
|
||||||
|
// - Print protocol buffers.
|
||||||
|
// - Print types convertible to BiggestInt.
|
||||||
|
// - Print types convertible to StringView, if available.
|
||||||
|
// - Fallback to printing the raw bytes of the object.
|
||||||
|
template <typename T>
|
||||||
|
void PrintWithFallback(const T& value, ::std::ostream* os) {
|
||||||
|
using Printer = typename FindFirstPrinter<
|
||||||
|
T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
|
||||||
|
StreamPrinter, ProtobufPrinter, ConvertibleToIntegerPrinter,
|
||||||
|
ConvertibleToStringViewPrinter, FallbackPrinter>::type;
|
||||||
|
Printer::PrintValue(value, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
|
||||||
|
// value of type ToPrint that is an operand of a comparison assertion
|
||||||
|
// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in
|
||||||
|
// the comparison, and is used to help determine the best way to
|
||||||
|
// format the value. In particular, when the value is a C string
|
||||||
|
// (char pointer) and the other operand is an STL string object, we
|
||||||
|
// want to format the C string as a string, since we know it is
|
||||||
|
// compared by value with the string object. If the value is a char
|
||||||
|
// pointer but the other operand is not an STL string object, we don't
|
||||||
|
// know whether the pointer is supposed to point to a NUL-terminated
|
||||||
|
// string, and thus want to print it as a pointer to be safe.
|
||||||
|
//
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||||
|
|
||||||
|
// The default case.
|
||||||
|
template <typename ToPrint, typename OtherOperand>
|
||||||
|
class FormatForComparison {
|
||||||
|
public:
|
||||||
|
static ::std::string Format(const ToPrint& value) {
|
||||||
|
return ::testing::PrintToString(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Array.
|
||||||
|
template <typename ToPrint, size_t N, typename OtherOperand>
|
||||||
|
class FormatForComparison<ToPrint[N], OtherOperand> {
|
||||||
|
public:
|
||||||
|
static ::std::string Format(const ToPrint* value) {
|
||||||
|
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// By default, print C string as pointers to be safe, as we don't know
|
||||||
|
// whether they actually point to a NUL-terminated string.
|
||||||
|
|
||||||
|
#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \
|
||||||
|
template <typename OtherOperand> \
|
||||||
|
class FormatForComparison<CharType*, OtherOperand> { \
|
||||||
|
public: \
|
||||||
|
static ::std::string Format(CharType* value) { \
|
||||||
|
return ::testing::PrintToString(static_cast<const void*>(value)); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
|
||||||
|
|
||||||
|
#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
|
||||||
|
|
||||||
|
// If a C string is compared with an STL string object, we know it's meant
|
||||||
|
// to point to a NUL-terminated string, and thus can print it as a string.
|
||||||
|
|
||||||
|
#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
|
||||||
|
template <> \
|
||||||
|
class FormatForComparison<CharType*, OtherStringType> { \
|
||||||
|
public: \
|
||||||
|
static ::std::string Format(CharType* value) { \
|
||||||
|
return ::testing::PrintToString(value); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
|
||||||
|
|
||||||
|
#if GTEST_HAS_STD_WSTRING
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
|
||||||
|
|
||||||
|
// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
|
||||||
|
// operand to be used in a failure message. The type (but not value)
|
||||||
|
// of the other operand may affect the format. This allows us to
|
||||||
|
// print a char* as a raw pointer when it is compared against another
|
||||||
|
// char* or void*, and print it as a C string when it is compared
|
||||||
|
// against an std::string object, for example.
|
||||||
|
//
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
std::string FormatForComparisonFailureMessage(
|
||||||
|
const T1& value, const T2& /* other_operand */) {
|
||||||
|
return FormatForComparison<T1, T2>::Format(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
|
||||||
|
// value to the given ostream. The caller must ensure that
|
||||||
|
// 'ostream_ptr' is not NULL, or the behavior is undefined.
|
||||||
|
//
|
||||||
|
// We define UniversalPrinter as a class template (as opposed to a
|
||||||
|
// function template), as we need to partially specialize it for
|
||||||
|
// reference types, which cannot be done with function templates.
|
||||||
|
template <typename T>
|
||||||
|
class UniversalPrinter;
|
||||||
|
|
||||||
|
// Prints the given value using the << operator if it has one;
|
||||||
|
// otherwise prints the bytes in it. This is what
|
||||||
|
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
|
||||||
|
// or overloaded for type T.
|
||||||
|
//
|
||||||
|
// A user can override this behavior for a class type Foo by defining
|
||||||
|
// an overload of PrintTo() in the namespace where Foo is defined. We
|
||||||
|
// give the user this option as sometimes defining a << operator for
|
||||||
|
// Foo is not desirable (e.g. the coding style may prevent doing it,
|
||||||
|
// or there is already a << operator but it doesn't do what the user
|
||||||
|
// wants).
|
||||||
|
template <typename T>
|
||||||
|
void PrintTo(const T& value, ::std::ostream* os) {
|
||||||
|
internal::PrintWithFallback(value, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following list of PrintTo() overloads tells
|
||||||
|
// UniversalPrinter<T>::Print() how to print standard types (built-in
|
||||||
|
// types, strings, plain arrays, and pointers).
|
||||||
|
|
||||||
|
// Overloads for various char types.
|
||||||
|
GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
|
||||||
|
GTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
|
||||||
|
inline void PrintTo(char c, ::std::ostream* os) {
|
||||||
|
// When printing a plain char, we always treat it as unsigned. This
|
||||||
|
// way, the output won't be affected by whether the compiler thinks
|
||||||
|
// char is signed or not.
|
||||||
|
PrintTo(static_cast<unsigned char>(c), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overloads for other simple built-in types.
|
||||||
|
inline void PrintTo(bool x, ::std::ostream* os) {
|
||||||
|
*os << (x ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload for wchar_t type.
|
||||||
|
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||||
|
// code otherwise and also as its decimal code (except for L'\0').
|
||||||
|
// The L'\0' char is printed as "L'\\0'". The decimal code is printed
|
||||||
|
// as signed integer when wchar_t is implemented by the compiler
|
||||||
|
// as a signed type and is printed as an unsigned integer when wchar_t
|
||||||
|
// is implemented as an unsigned type.
|
||||||
|
GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
|
||||||
|
|
||||||
|
// Overloads for C strings.
|
||||||
|
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
||||||
|
inline void PrintTo(char* s, ::std::ostream* os) {
|
||||||
|
PrintTo(ImplicitCast_<const char*>(s), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// signed/unsigned char is often used for representing binary data, so
|
||||||
|
// we print pointers to it as void* to be safe.
|
||||||
|
inline void PrintTo(const signed char* s, ::std::ostream* os) {
|
||||||
|
PrintTo(ImplicitCast_<const void*>(s), os);
|
||||||
|
}
|
||||||
|
inline void PrintTo(signed char* s, ::std::ostream* os) {
|
||||||
|
PrintTo(ImplicitCast_<const void*>(s), os);
|
||||||
|
}
|
||||||
|
inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
|
||||||
|
PrintTo(ImplicitCast_<const void*>(s), os);
|
||||||
|
}
|
||||||
|
inline void PrintTo(unsigned char* s, ::std::ostream* os) {
|
||||||
|
PrintTo(ImplicitCast_<const void*>(s), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MSVC can be configured to define wchar_t as a typedef of unsigned
|
||||||
|
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
|
||||||
|
// type. When wchar_t is a typedef, defining an overload for const
|
||||||
|
// wchar_t* would cause unsigned short* be printed as a wide string,
|
||||||
|
// possibly causing invalid memory accesses.
|
||||||
|
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||||
|
// Overloads for wide C strings
|
||||||
|
GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
|
||||||
|
inline void PrintTo(wchar_t* s, ::std::ostream* os) {
|
||||||
|
PrintTo(ImplicitCast_<const wchar_t*>(s), os);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Overload for C arrays. Multi-dimensional arrays are printed
|
||||||
|
// properly.
|
||||||
|
|
||||||
|
// Prints the given number of elements in an array, without printing
|
||||||
|
// the curly braces.
|
||||||
|
template <typename T>
|
||||||
|
void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
|
||||||
|
UniversalPrint(a[0], os);
|
||||||
|
for (size_t i = 1; i != count; i++) {
|
||||||
|
*os << ", ";
|
||||||
|
UniversalPrint(a[i], os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overloads for ::std::string.
|
||||||
|
GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);
|
||||||
|
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
||||||
|
PrintStringTo(s, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overloads for ::std::wstring.
|
||||||
|
#if GTEST_HAS_STD_WSTRING
|
||||||
|
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
|
||||||
|
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
||||||
|
PrintWideStringTo(s, os);
|
||||||
|
}
|
||||||
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
// Overload for internal::StringView.
|
||||||
|
inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
|
||||||
|
PrintTo(::std::string(sp), os);
|
||||||
|
}
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
|
||||||
|
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
|
||||||
|
UniversalPrinter<T&>::Print(ref.get(), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function for printing a tuple. T must be instantiated with
|
||||||
|
// a tuple type.
|
||||||
|
template <typename T>
|
||||||
|
void PrintTupleTo(const T&, std::integral_constant<size_t, 0>,
|
||||||
|
::std::ostream*) {}
|
||||||
|
|
||||||
|
template <typename T, size_t I>
|
||||||
|
void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
|
||||||
|
::std::ostream* os) {
|
||||||
|
PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);
|
||||||
|
GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
||||||
|
if (I > 1) {
|
||||||
|
GTEST_INTENTIONAL_CONST_COND_POP_()
|
||||||
|
*os << ", ";
|
||||||
|
}
|
||||||
|
UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
|
||||||
|
std::get<I - 1>(t), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
|
||||||
|
*os << "(";
|
||||||
|
PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);
|
||||||
|
*os << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload for std::pair.
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
|
||||||
|
*os << '(';
|
||||||
|
// We cannot use UniversalPrint(value.first, os) here, as T1 may be
|
||||||
|
// a reference type. The same for printing value.second.
|
||||||
|
UniversalPrinter<T1>::Print(value.first, os);
|
||||||
|
*os << ", ";
|
||||||
|
UniversalPrinter<T2>::Print(value.second, os);
|
||||||
|
*os << ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements printing a non-reference type T by letting the compiler
|
||||||
|
// pick the right overload of PrintTo() for T.
|
||||||
|
template <typename T>
|
||||||
|
class UniversalPrinter {
|
||||||
|
public:
|
||||||
|
// MSVC warns about adding const to a function type, so we want to
|
||||||
|
// disable the warning.
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
|
||||||
|
|
||||||
|
// Note: we deliberately don't call this PrintTo(), as that name
|
||||||
|
// conflicts with ::testing::internal::PrintTo in the body of the
|
||||||
|
// function.
|
||||||
|
static void Print(const T& value, ::std::ostream* os) {
|
||||||
|
// By default, ::testing::internal::PrintTo() is used for printing
|
||||||
|
// the value.
|
||||||
|
//
|
||||||
|
// Thanks to Koenig look-up, if T is a class and has its own
|
||||||
|
// PrintTo() function defined in its namespace, that function will
|
||||||
|
// be visible here. Since it is more specific than the generic ones
|
||||||
|
// in ::testing::internal, it will be picked by the compiler in the
|
||||||
|
// following statement - exactly what we want.
|
||||||
|
PrintTo(value, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||||
|
};
|
||||||
|
|
||||||
|
#if GTEST_HAS_ABSL
|
||||||
|
|
||||||
|
// Printer for absl::optional
|
||||||
|
|
||||||
|
template <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 << ')';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Printer for absl::variant
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
class UniversalPrinter<::absl::variant<T...>> {
|
||||||
|
public:
|
||||||
|
static void Print(const ::absl::variant<T...>& value, ::std::ostream* os) {
|
||||||
|
*os << '(';
|
||||||
|
absl::visit(Visitor{os}, value);
|
||||||
|
*os << ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Visitor {
|
||||||
|
template <typename U>
|
||||||
|
void operator()(const U& u) const {
|
||||||
|
*os << "'" << GetTypeName<U>() << "' with value ";
|
||||||
|
UniversalPrint(u, os);
|
||||||
|
}
|
||||||
|
::std::ostream* os;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
|
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||||
|
// elements, starting at address 'begin'.
|
||||||
|
template <typename T>
|
||||||
|
void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
|
||||||
|
if (len == 0) {
|
||||||
|
*os << "{}";
|
||||||
|
} else {
|
||||||
|
*os << "{ ";
|
||||||
|
const size_t kThreshold = 18;
|
||||||
|
const size_t kChunkSize = 8;
|
||||||
|
// If the array has more than kThreshold elements, we'll have to
|
||||||
|
// omit some details by printing only the first and the last
|
||||||
|
// kChunkSize elements.
|
||||||
|
if (len <= kThreshold) {
|
||||||
|
PrintRawArrayTo(begin, len, os);
|
||||||
|
} else {
|
||||||
|
PrintRawArrayTo(begin, kChunkSize, os);
|
||||||
|
*os << ", ..., ";
|
||||||
|
PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
|
||||||
|
}
|
||||||
|
*os << " }";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This overload prints a (const) char array compactly.
|
||||||
|
GTEST_API_ void UniversalPrintArray(
|
||||||
|
const char* begin, size_t len, ::std::ostream* os);
|
||||||
|
|
||||||
|
// This overload prints a (const) wchar_t array compactly.
|
||||||
|
GTEST_API_ void UniversalPrintArray(
|
||||||
|
const wchar_t* begin, size_t len, ::std::ostream* os);
|
||||||
|
|
||||||
|
// Implements printing an array type T[N].
|
||||||
|
template <typename T, size_t N>
|
||||||
|
class UniversalPrinter<T[N]> {
|
||||||
|
public:
|
||||||
|
// Prints the given array, omitting some elements when there are too
|
||||||
|
// many.
|
||||||
|
static void Print(const T (&a)[N], ::std::ostream* os) {
|
||||||
|
UniversalPrintArray(a, N, os);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implements printing a reference type T&.
|
||||||
|
template <typename T>
|
||||||
|
class UniversalPrinter<T&> {
|
||||||
|
public:
|
||||||
|
// MSVC warns about adding const to a function type, so we want to
|
||||||
|
// disable the warning.
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
|
||||||
|
|
||||||
|
static void Print(const T& value, ::std::ostream* os) {
|
||||||
|
// Prints the address of the value. We use reinterpret_cast here
|
||||||
|
// as static_cast doesn't compile when T is a function type.
|
||||||
|
*os << "@" << reinterpret_cast<const void*>(&value) << " ";
|
||||||
|
|
||||||
|
// Then prints the value itself.
|
||||||
|
UniversalPrint(value, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prints a value tersely: for a reference type, the referenced value
|
||||||
|
// (but not the address) is printed; for a (const) char pointer, the
|
||||||
|
// NUL-terminated string (but not the pointer) is printed.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class UniversalTersePrinter {
|
||||||
|
public:
|
||||||
|
static void Print(const T& value, ::std::ostream* os) {
|
||||||
|
UniversalPrint(value, os);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
class UniversalTersePrinter<T&> {
|
||||||
|
public:
|
||||||
|
static void Print(const T& value, ::std::ostream* os) {
|
||||||
|
UniversalPrint(value, os);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename T, size_t N>
|
||||||
|
class UniversalTersePrinter<T[N]> {
|
||||||
|
public:
|
||||||
|
static void Print(const T (&value)[N], ::std::ostream* os) {
|
||||||
|
UniversalPrinter<T[N]>::Print(value, os);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
class UniversalTersePrinter<const char*> {
|
||||||
|
public:
|
||||||
|
static void Print(const char* str, ::std::ostream* os) {
|
||||||
|
if (str == nullptr) {
|
||||||
|
*os << "NULL";
|
||||||
|
} else {
|
||||||
|
UniversalPrint(std::string(str), os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
class UniversalTersePrinter<char*> {
|
||||||
|
public:
|
||||||
|
static void Print(char* str, ::std::ostream* os) {
|
||||||
|
UniversalTersePrinter<const char*>::Print(str, os);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if GTEST_HAS_STD_WSTRING
|
||||||
|
template <>
|
||||||
|
class UniversalTersePrinter<const wchar_t*> {
|
||||||
|
public:
|
||||||
|
static void Print(const wchar_t* str, ::std::ostream* os) {
|
||||||
|
if (str == nullptr) {
|
||||||
|
*os << "NULL";
|
||||||
|
} else {
|
||||||
|
UniversalPrint(::std::wstring(str), os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class UniversalTersePrinter<wchar_t*> {
|
||||||
|
public:
|
||||||
|
static void Print(wchar_t* str, ::std::ostream* os) {
|
||||||
|
UniversalTersePrinter<const wchar_t*>::Print(str, os);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void UniversalTersePrint(const T& value, ::std::ostream* os) {
|
||||||
|
UniversalTersePrinter<T>::Print(value, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a value using the type inferred by the compiler. The
|
||||||
|
// difference between this and UniversalTersePrint() is that for a
|
||||||
|
// (const) char pointer, this prints both the pointer and the
|
||||||
|
// NUL-terminated string.
|
||||||
|
template <typename T>
|
||||||
|
void UniversalPrint(const T& value, ::std::ostream* os) {
|
||||||
|
// A workarond for the bug in VC++ 7.1 that prevents us from instantiating
|
||||||
|
// UniversalPrinter with T directly.
|
||||||
|
typedef T T1;
|
||||||
|
UniversalPrinter<T1>::Print(value, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef ::std::vector< ::std::string> Strings;
|
||||||
|
|
||||||
|
// Tersely prints the first N fields of a tuple to a string vector,
|
||||||
|
// one element for each field.
|
||||||
|
template <typename Tuple>
|
||||||
|
void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,
|
||||||
|
Strings*) {}
|
||||||
|
template <typename Tuple, size_t I>
|
||||||
|
void TersePrintPrefixToStrings(const Tuple& t,
|
||||||
|
std::integral_constant<size_t, I>,
|
||||||
|
Strings* strings) {
|
||||||
|
TersePrintPrefixToStrings(t, std::integral_constant<size_t, I - 1>(),
|
||||||
|
strings);
|
||||||
|
::std::stringstream ss;
|
||||||
|
UniversalTersePrint(std::get<I - 1>(t), &ss);
|
||||||
|
strings->push_back(ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints the fields of a tuple tersely to a string vector, one
|
||||||
|
// element for each field. See the comment before
|
||||||
|
// UniversalTersePrint() for how we define "tersely".
|
||||||
|
template <typename Tuple>
|
||||||
|
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
||||||
|
Strings result;
|
||||||
|
TersePrintPrefixToStrings(
|
||||||
|
value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),
|
||||||
|
&result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
::std::string PrintToString(const T& value) {
|
||||||
|
::std::stringstream ss;
|
||||||
|
internal::UniversalTersePrinter<T>::Print(value, &ss);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
// Include any custom printer added by the local installation.
|
||||||
|
// We must include this header at the end to make sure it can use the
|
||||||
|
// declarations from this file.
|
||||||
|
#include "gtest/internal/custom/gtest-printers.h"
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
|
@ -0,0 +1,238 @@
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Utilities for testing Google Test itself and code that uses Google Test
|
||||||
|
// (e.g. frameworks built on top of Google Test).
|
||||||
|
|
||||||
|
// GOOGLETEST_CM0004 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// This helper class can be used to mock out Google Test failure reporting
|
||||||
|
// so that we can test Google Test or code that builds on Google Test.
|
||||||
|
//
|
||||||
|
// An object of this class appends a TestPartResult object to the
|
||||||
|
// TestPartResultArray object given in the constructor whenever a Google Test
|
||||||
|
// failure is reported. It can either intercept only failures that are
|
||||||
|
// generated in the same thread that created this object or it can intercept
|
||||||
|
// all generated failures. The scope of this mock object can be controlled with
|
||||||
|
// the second argument to the two arguments constructor.
|
||||||
|
class GTEST_API_ ScopedFakeTestPartResultReporter
|
||||||
|
: public TestPartResultReporterInterface {
|
||||||
|
public:
|
||||||
|
// The two possible mocking modes of this object.
|
||||||
|
enum InterceptMode {
|
||||||
|
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
|
||||||
|
INTERCEPT_ALL_THREADS // Intercepts all failures.
|
||||||
|
};
|
||||||
|
|
||||||
|
// The c'tor sets this object as the test part result reporter used
|
||||||
|
// by Google Test. The 'result' parameter specifies where to report the
|
||||||
|
// results. This reporter will only catch failures generated in the current
|
||||||
|
// thread. DEPRECATED
|
||||||
|
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
|
||||||
|
|
||||||
|
// Same as above, but you can choose the interception scope of this object.
|
||||||
|
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
|
||||||
|
TestPartResultArray* result);
|
||||||
|
|
||||||
|
// The d'tor restores the previous test part result reporter.
|
||||||
|
~ScopedFakeTestPartResultReporter() override;
|
||||||
|
|
||||||
|
// Appends the TestPartResult object to the TestPartResultArray
|
||||||
|
// received in the constructor.
|
||||||
|
//
|
||||||
|
// This method is from the TestPartResultReporterInterface
|
||||||
|
// interface.
|
||||||
|
void ReportTestPartResult(const TestPartResult& result) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
const InterceptMode intercept_mode_;
|
||||||
|
TestPartResultReporterInterface* old_reporter_;
|
||||||
|
TestPartResultArray* const result_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// A helper class for implementing EXPECT_FATAL_FAILURE() and
|
||||||
|
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
|
||||||
|
// TestPartResultArray contains exactly one failure that has the given
|
||||||
|
// type and contains the given substring. If that's not the case, a
|
||||||
|
// non-fatal failure will be generated.
|
||||||
|
class GTEST_API_ SingleFailureChecker {
|
||||||
|
public:
|
||||||
|
// The constructor remembers the arguments.
|
||||||
|
SingleFailureChecker(const TestPartResultArray* results,
|
||||||
|
TestPartResult::Type type, const std::string& substr);
|
||||||
|
~SingleFailureChecker();
|
||||||
|
private:
|
||||||
|
const TestPartResultArray* const results_;
|
||||||
|
const TestPartResult::Type type_;
|
||||||
|
const std::string substr_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
|
|
||||||
|
// A set of macros for testing Google Test assertions or code that's expected
|
||||||
|
// to generate Google Test fatal failures. It verifies that the given
|
||||||
|
// statement will cause exactly one fatal Google Test failure with 'substr'
|
||||||
|
// being part of the failure message.
|
||||||
|
//
|
||||||
|
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
|
||||||
|
// affects and considers failures generated in the current thread and
|
||||||
|
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||||
|
//
|
||||||
|
// The verification of the assertion is done correctly even when the statement
|
||||||
|
// throws an exception or aborts the current function.
|
||||||
|
//
|
||||||
|
// Known restrictions:
|
||||||
|
// - 'statement' cannot reference local non-static variables or
|
||||||
|
// non-static members of the current object.
|
||||||
|
// - 'statement' cannot return a value.
|
||||||
|
// - You cannot stream a failure message to this macro.
|
||||||
|
//
|
||||||
|
// Note that even though the implementations of the following two
|
||||||
|
// macros are much alike, we cannot refactor them to use a common
|
||||||
|
// helper macro, due to some peculiarity in how the preprocessor
|
||||||
|
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
|
||||||
|
// gtest_unittest.cc will fail to compile if we do that.
|
||||||
|
#define EXPECT_FATAL_FAILURE(statement, substr) \
|
||||||
|
do { \
|
||||||
|
class GTestExpectFatalFailureHelper {\
|
||||||
|
public:\
|
||||||
|
static void Execute() { statement; }\
|
||||||
|
};\
|
||||||
|
::testing::TestPartResultArray gtest_failures;\
|
||||||
|
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||||
|
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||||
|
{\
|
||||||
|
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||||
|
::testing::ScopedFakeTestPartResultReporter:: \
|
||||||
|
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||||
|
GTestExpectFatalFailureHelper::Execute();\
|
||||||
|
}\
|
||||||
|
} while (::testing::internal::AlwaysFalse())
|
||||||
|
|
||||||
|
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||||
|
do { \
|
||||||
|
class GTestExpectFatalFailureHelper {\
|
||||||
|
public:\
|
||||||
|
static void Execute() { statement; }\
|
||||||
|
};\
|
||||||
|
::testing::TestPartResultArray gtest_failures;\
|
||||||
|
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||||
|
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||||
|
{\
|
||||||
|
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||||
|
::testing::ScopedFakeTestPartResultReporter:: \
|
||||||
|
INTERCEPT_ALL_THREADS, >est_failures);\
|
||||||
|
GTestExpectFatalFailureHelper::Execute();\
|
||||||
|
}\
|
||||||
|
} while (::testing::internal::AlwaysFalse())
|
||||||
|
|
||||||
|
// A macro for testing Google Test assertions or code that's expected to
|
||||||
|
// generate Google Test non-fatal failures. It asserts that the given
|
||||||
|
// statement will cause exactly one non-fatal Google Test failure with 'substr'
|
||||||
|
// being part of the failure message.
|
||||||
|
//
|
||||||
|
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
|
||||||
|
// affects and considers failures generated in the current thread and
|
||||||
|
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||||
|
//
|
||||||
|
// 'statement' is allowed to reference local variables and members of
|
||||||
|
// the current object.
|
||||||
|
//
|
||||||
|
// The verification of the assertion is done correctly even when the statement
|
||||||
|
// throws an exception or aborts the current function.
|
||||||
|
//
|
||||||
|
// Known restrictions:
|
||||||
|
// - You cannot stream a failure message to this macro.
|
||||||
|
//
|
||||||
|
// Note that even though the implementations of the following two
|
||||||
|
// macros are much alike, we cannot refactor them to use a common
|
||||||
|
// helper macro, due to some peculiarity in how the preprocessor
|
||||||
|
// works. If we do that, the code won't compile when the user gives
|
||||||
|
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
|
||||||
|
// expands to code containing an unprotected comma. The
|
||||||
|
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
|
||||||
|
// catches that.
|
||||||
|
//
|
||||||
|
// For the same reason, we have to write
|
||||||
|
// if (::testing::internal::AlwaysTrue()) { statement; }
|
||||||
|
// instead of
|
||||||
|
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||||
|
// to avoid an MSVC warning on unreachable code.
|
||||||
|
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
|
||||||
|
do {\
|
||||||
|
::testing::TestPartResultArray gtest_failures;\
|
||||||
|
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||||
|
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||||
|
(substr));\
|
||||||
|
{\
|
||||||
|
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||||
|
::testing::ScopedFakeTestPartResultReporter:: \
|
||||||
|
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||||
|
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||||
|
}\
|
||||||
|
} while (::testing::internal::AlwaysFalse())
|
||||||
|
|
||||||
|
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||||
|
do {\
|
||||||
|
::testing::TestPartResultArray gtest_failures;\
|
||||||
|
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||||
|
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||||
|
(substr));\
|
||||||
|
{\
|
||||||
|
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||||
|
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
|
||||||
|
>est_failures);\
|
||||||
|
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||||
|
}\
|
||||||
|
} while (::testing::internal::AlwaysFalse())
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
|
@ -0,0 +1,184 @@
|
||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <vector>
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-string.h"
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// A copyable object representing the result of a test part (i.e. an
|
||||||
|
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
||||||
|
//
|
||||||
|
// Don't inherit from TestPartResult as its destructor is not virtual.
|
||||||
|
class GTEST_API_ TestPartResult {
|
||||||
|
public:
|
||||||
|
// The possible outcomes of a test part (i.e. an assertion or an
|
||||||
|
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||||
|
enum Type {
|
||||||
|
kSuccess, // Succeeded.
|
||||||
|
kNonFatalFailure, // Failed but the test can continue.
|
||||||
|
kFatalFailure, // Failed and the test should be terminated.
|
||||||
|
kSkip // Skipped.
|
||||||
|
};
|
||||||
|
|
||||||
|
// C'tor. TestPartResult does NOT have a default constructor.
|
||||||
|
// Always use this constructor (with parameters) to create a
|
||||||
|
// TestPartResult object.
|
||||||
|
TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
|
||||||
|
const char* a_message)
|
||||||
|
: type_(a_type),
|
||||||
|
file_name_(a_file_name == nullptr ? "" : a_file_name),
|
||||||
|
line_number_(a_line_number),
|
||||||
|
summary_(ExtractSummary(a_message)),
|
||||||
|
message_(a_message) {}
|
||||||
|
|
||||||
|
// Gets the outcome of the test part.
|
||||||
|
Type type() const { return type_; }
|
||||||
|
|
||||||
|
// Gets the name of the source file where the test part took place, or
|
||||||
|
// NULL if it's unknown.
|
||||||
|
const char* file_name() const {
|
||||||
|
return file_name_.empty() ? nullptr : file_name_.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the line in the source file where the test part took place,
|
||||||
|
// or -1 if it's unknown.
|
||||||
|
int line_number() const { return line_number_; }
|
||||||
|
|
||||||
|
// Gets the summary of the failure message.
|
||||||
|
const char* summary() const { return summary_.c_str(); }
|
||||||
|
|
||||||
|
// Gets the message associated with the test part.
|
||||||
|
const char* message() const { return message_.c_str(); }
|
||||||
|
|
||||||
|
// Returns true if and only if the test part was skipped.
|
||||||
|
bool skipped() const { return type_ == kSkip; }
|
||||||
|
|
||||||
|
// Returns true if and only if the test part passed.
|
||||||
|
bool passed() const { return type_ == kSuccess; }
|
||||||
|
|
||||||
|
// Returns true if and only if the test part non-fatally failed.
|
||||||
|
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
|
||||||
|
|
||||||
|
// Returns true if and only if the test part fatally failed.
|
||||||
|
bool fatally_failed() const { return type_ == kFatalFailure; }
|
||||||
|
|
||||||
|
// Returns true if and only if the test part failed.
|
||||||
|
bool failed() const { return fatally_failed() || nonfatally_failed(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type type_;
|
||||||
|
|
||||||
|
// Gets the summary of the failure message by omitting the stack
|
||||||
|
// trace in it.
|
||||||
|
static std::string ExtractSummary(const char* message);
|
||||||
|
|
||||||
|
// The name of the source file where the test part took place, or
|
||||||
|
// "" if the source file is unknown.
|
||||||
|
std::string file_name_;
|
||||||
|
// The line in the source file where the test part took place, or -1
|
||||||
|
// if the line number is unknown.
|
||||||
|
int line_number_;
|
||||||
|
std::string summary_; // The test failure summary.
|
||||||
|
std::string message_; // The test failure message.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prints a TestPartResult object.
|
||||||
|
std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
|
||||||
|
|
||||||
|
// An array of TestPartResult objects.
|
||||||
|
//
|
||||||
|
// Don't inherit from TestPartResultArray as its destructor is not
|
||||||
|
// virtual.
|
||||||
|
class GTEST_API_ TestPartResultArray {
|
||||||
|
public:
|
||||||
|
TestPartResultArray() {}
|
||||||
|
|
||||||
|
// Appends the given TestPartResult to the array.
|
||||||
|
void Append(const TestPartResult& result);
|
||||||
|
|
||||||
|
// Returns the TestPartResult at the given index (0-based).
|
||||||
|
const TestPartResult& GetTestPartResult(int index) const;
|
||||||
|
|
||||||
|
// Returns the number of TestPartResult objects in the array.
|
||||||
|
int size() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<TestPartResult> array_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
|
||||||
|
};
|
||||||
|
|
||||||
|
// This interface knows how to report a test part result.
|
||||||
|
class GTEST_API_ TestPartResultReporterInterface {
|
||||||
|
public:
|
||||||
|
virtual ~TestPartResultReporterInterface() {}
|
||||||
|
|
||||||
|
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
|
||||||
|
// statement generates new fatal failures. To do so it registers itself as the
|
||||||
|
// current test part result reporter. Besides checking if fatal failures were
|
||||||
|
// reported, it only delegates the reporting to the former result reporter.
|
||||||
|
// The original result reporter is restored in the destructor.
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||||
|
class GTEST_API_ HasNewFatalFailureHelper
|
||||||
|
: public TestPartResultReporterInterface {
|
||||||
|
public:
|
||||||
|
HasNewFatalFailureHelper();
|
||||||
|
~HasNewFatalFailureHelper() override;
|
||||||
|
void ReportTestPartResult(const TestPartResult& result) override;
|
||||||
|
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
|
||||||
|
private:
|
||||||
|
bool has_new_fatal_failure_;
|
||||||
|
TestPartResultReporterInterface* original_reporter_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
|
@ -0,0 +1,337 @@
|
||||||
|
// Copyright 2008 Google Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||||
|
|
||||||
|
// This header implements typed tests and type-parameterized tests.
|
||||||
|
|
||||||
|
// Typed (aka type-driven) tests repeat the same test for types in a
|
||||||
|
// list. You must know which types you want to test with when writing
|
||||||
|
// typed tests. Here's how you do it:
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
// First, define a fixture class template. It should be parameterized
|
||||||
|
// by a type. Remember to derive it from testing::Test.
|
||||||
|
template <typename T>
|
||||||
|
class FooTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
...
|
||||||
|
typedef std::list<T> List;
|
||||||
|
static T shared_;
|
||||||
|
T value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Next, associate a list of types with the test suite, which will be
|
||||||
|
// repeated for each type in the list. The typedef is necessary for
|
||||||
|
// the macro to parse correctly.
|
||||||
|
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||||
|
TYPED_TEST_SUITE(FooTest, MyTypes);
|
||||||
|
|
||||||
|
// If the type list contains only one type, you can write that type
|
||||||
|
// directly without Types<...>:
|
||||||
|
// TYPED_TEST_SUITE(FooTest, int);
|
||||||
|
|
||||||
|
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
|
||||||
|
// tests for this test suite as you want.
|
||||||
|
TYPED_TEST(FooTest, DoesBlah) {
|
||||||
|
// Inside a test, refer to the special name TypeParam to get the type
|
||||||
|
// parameter. Since we are inside a derived class template, C++ requires
|
||||||
|
// us to visit the members of FooTest via 'this'.
|
||||||
|
TypeParam n = this->value_;
|
||||||
|
|
||||||
|
// To visit static members of the fixture, add the TestFixture::
|
||||||
|
// prefix.
|
||||||
|
n += TestFixture::shared_;
|
||||||
|
|
||||||
|
// To refer to typedefs in the fixture, add the "typename
|
||||||
|
// TestFixture::" prefix.
|
||||||
|
typename TestFixture::List values;
|
||||||
|
values.push_back(n);
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(FooTest, HasPropertyA) { ... }
|
||||||
|
|
||||||
|
// TYPED_TEST_SUITE takes an optional third argument which allows to specify a
|
||||||
|
// class that generates custom test name suffixes based on the type. This should
|
||||||
|
// be a class which has a static template function GetName(int index) returning
|
||||||
|
// a string for each type. The provided integer index equals the index of the
|
||||||
|
// type in the provided type list. In many cases the index can be ignored.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
// class MyTypeNames {
|
||||||
|
// public:
|
||||||
|
// template <typename T>
|
||||||
|
// static std::string GetName(int) {
|
||||||
|
// if (std::is_same<T, char>()) return "char";
|
||||||
|
// if (std::is_same<T, int>()) return "int";
|
||||||
|
// if (std::is_same<T, unsigned int>()) return "unsignedInt";
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames);
|
||||||
|
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
// Type-parameterized tests are abstract test patterns parameterized
|
||||||
|
// by a type. Compared with typed tests, type-parameterized tests
|
||||||
|
// allow you to define the test pattern without knowing what the type
|
||||||
|
// parameters are. The defined pattern can be instantiated with
|
||||||
|
// different types any number of times, in any number of translation
|
||||||
|
// units.
|
||||||
|
//
|
||||||
|
// If you are designing an interface or concept, you can define a
|
||||||
|
// suite of type-parameterized tests to verify properties that any
|
||||||
|
// valid implementation of the interface/concept should have. Then,
|
||||||
|
// each implementation can easily instantiate the test suite to verify
|
||||||
|
// that it conforms to the requirements, without having to write
|
||||||
|
// similar tests repeatedly. Here's an example:
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
// First, define a fixture class template. It should be parameterized
|
||||||
|
// by a type. Remember to derive it from testing::Test.
|
||||||
|
template <typename T>
|
||||||
|
class FooTest : public testing::Test {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
// Next, declare that you will define a type-parameterized test suite
|
||||||
|
// (the _P suffix is for "parameterized" or "pattern", whichever you
|
||||||
|
// prefer):
|
||||||
|
TYPED_TEST_SUITE_P(FooTest);
|
||||||
|
|
||||||
|
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
||||||
|
// for this type-parameterized test suite as you want.
|
||||||
|
TYPED_TEST_P(FooTest, DoesBlah) {
|
||||||
|
// Inside a test, refer to TypeParam to get the type parameter.
|
||||||
|
TypeParam n = 0;
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST_P(FooTest, HasPropertyA) { ... }
|
||||||
|
|
||||||
|
// Now the tricky part: you need to register all test patterns before
|
||||||
|
// you can instantiate them. The first argument of the macro is the
|
||||||
|
// test suite name; the rest are the names of the tests in this test
|
||||||
|
// case.
|
||||||
|
REGISTER_TYPED_TEST_SUITE_P(FooTest,
|
||||||
|
DoesBlah, HasPropertyA);
|
||||||
|
|
||||||
|
// Finally, you are free to instantiate the pattern with the types you
|
||||||
|
// want. If you put the above code in a header file, you can #include
|
||||||
|
// it in multiple C++ source files and instantiate it multiple times.
|
||||||
|
//
|
||||||
|
// To distinguish different instances of the pattern, the first
|
||||||
|
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||||
|
// to the actual test suite name. Remember to pick unique prefixes for
|
||||||
|
// different instances.
|
||||||
|
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||||
|
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||||
|
|
||||||
|
// If the type list contains only one type, you can write that type
|
||||||
|
// directly without Types<...>:
|
||||||
|
// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int);
|
||||||
|
//
|
||||||
|
// Similar to the optional argument of TYPED_TEST_SUITE above,
|
||||||
|
// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to
|
||||||
|
// generate custom names.
|
||||||
|
// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames);
|
||||||
|
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
#include "gtest/internal/gtest-type-util.h"
|
||||||
|
|
||||||
|
// Implements typed tests.
|
||||||
|
|
||||||
|
#if GTEST_HAS_TYPED_TEST
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// Expands to the name of the typedef for the type parameters of the
|
||||||
|
// given test suite.
|
||||||
|
#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_
|
||||||
|
|
||||||
|
// Expands to the name of the typedef for the NameGenerator, responsible for
|
||||||
|
// creating the suffixes of the name.
|
||||||
|
#define GTEST_NAME_GENERATOR_(TestSuiteName) \
|
||||||
|
gtest_type_params_##TestSuiteName##_NameGenerator
|
||||||
|
|
||||||
|
#define TYPED_TEST_SUITE(CaseName, Types, ...) \
|
||||||
|
typedef ::testing::internal::GenerateTypeList<Types>::type \
|
||||||
|
GTEST_TYPE_PARAMS_(CaseName); \
|
||||||
|
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
|
||||||
|
GTEST_NAME_GENERATOR_(CaseName)
|
||||||
|
|
||||||
|
#define TYPED_TEST(CaseName, TestName) \
|
||||||
|
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
|
||||||
|
"test-name must not be empty"); \
|
||||||
|
template <typename gtest_TypeParam_> \
|
||||||
|
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||||
|
: public CaseName<gtest_TypeParam_> { \
|
||||||
|
private: \
|
||||||
|
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||||
|
typedef gtest_TypeParam_ TypeParam; \
|
||||||
|
void TestBody() override; \
|
||||||
|
}; \
|
||||||
|
static bool gtest_##CaseName##_##TestName##_registered_ \
|
||||||
|
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
|
||||||
|
CaseName, \
|
||||||
|
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||||
|
TestName)>, \
|
||||||
|
GTEST_TYPE_PARAMS_( \
|
||||||
|
CaseName)>::Register("", \
|
||||||
|
::testing::internal::CodeLocation( \
|
||||||
|
__FILE__, __LINE__), \
|
||||||
|
GTEST_STRINGIFY_(CaseName), \
|
||||||
|
GTEST_STRINGIFY_(TestName), 0, \
|
||||||
|
::testing::internal::GenerateNames< \
|
||||||
|
GTEST_NAME_GENERATOR_(CaseName), \
|
||||||
|
GTEST_TYPE_PARAMS_(CaseName)>()); \
|
||||||
|
template <typename gtest_TypeParam_> \
|
||||||
|
void GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||||
|
TestName)<gtest_TypeParam_>::TestBody()
|
||||||
|
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
#define TYPED_TEST_CASE \
|
||||||
|
static_assert(::testing::internal::TypedTestCaseIsDeprecated(), ""); \
|
||||||
|
TYPED_TEST_SUITE
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_TYPED_TEST
|
||||||
|
|
||||||
|
// Implements type-parameterized tests.
|
||||||
|
|
||||||
|
#if GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// Expands to the namespace name that the type-parameterized tests for
|
||||||
|
// the given type-parameterized test suite are defined in. The exact
|
||||||
|
// name of the namespace is subject to change without notice.
|
||||||
|
#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// Expands to the name of the variable used to remember the names of
|
||||||
|
// the defined tests in the given test suite.
|
||||||
|
#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \
|
||||||
|
gtest_typed_test_suite_p_state_##TestSuiteName##_
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
||||||
|
//
|
||||||
|
// Expands to the name of the variable used to remember the names of
|
||||||
|
// the registered tests in the given test suite.
|
||||||
|
#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \
|
||||||
|
gtest_registered_test_names_##TestSuiteName##_
|
||||||
|
|
||||||
|
// The variables defined in the type-parameterized test macros are
|
||||||
|
// static as typically these macros are used in a .h file that can be
|
||||||
|
// #included in multiple translation units linked together.
|
||||||
|
#define TYPED_TEST_SUITE_P(SuiteName) \
|
||||||
|
static ::testing::internal::TypedTestSuitePState \
|
||||||
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
|
||||||
|
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
#define TYPED_TEST_CASE_P \
|
||||||
|
static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), ""); \
|
||||||
|
TYPED_TEST_SUITE_P
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
|
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||||
|
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||||
|
template <typename gtest_TypeParam_> \
|
||||||
|
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||||
|
private: \
|
||||||
|
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||||
|
typedef gtest_TypeParam_ TypeParam; \
|
||||||
|
void TestBody() override; \
|
||||||
|
}; \
|
||||||
|
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||||
|
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||||
|
GTEST_STRINGIFY_(TestName)); \
|
||||||
|
} \
|
||||||
|
template <typename gtest_TypeParam_> \
|
||||||
|
void GTEST_SUITE_NAMESPACE_( \
|
||||||
|
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
||||||
|
|
||||||
|
// Note: this won't work correctly if the trailing arguments are macros.
|
||||||
|
#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \
|
||||||
|
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||||
|
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
||||||
|
} \
|
||||||
|
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
||||||
|
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
||||||
|
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
#define REGISTER_TYPED_TEST_CASE_P \
|
||||||
|
static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \
|
||||||
|
""); \
|
||||||
|
REGISTER_TYPED_TEST_SUITE_P
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
|
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
||||||
|
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
||||||
|
"test-suit-prefix must not be empty"); \
|
||||||
|
static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
|
::testing::internal::TypeParameterizedTestSuite< \
|
||||||
|
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||||
|
::testing::internal::GenerateTypeList<Types>::type>:: \
|
||||||
|
Register(GTEST_STRINGIFY_(Prefix), \
|
||||||
|
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||||
|
>EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
|
||||||
|
GTEST_STRINGIFY_(SuiteName), \
|
||||||
|
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
|
||||||
|
::testing::internal::GenerateNames< \
|
||||||
|
::testing::internal::NameGeneratorSelector< \
|
||||||
|
__VA_ARGS__>::type, \
|
||||||
|
::testing::internal::GenerateTypeList<Types>::type>())
|
||||||
|
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
#define INSTANTIATE_TYPED_TEST_CASE_P \
|
||||||
|
static_assert( \
|
||||||
|
::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), ""); \
|
||||||
|
INSTANTIATE_TYPED_TEST_SUITE_P
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,359 @@
|
||||||
|
// Copyright 2006, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command
|
||||||
|
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||||
|
//
|
||||||
|
// Implements a family of generic predicate assertion macros.
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// This header implements a family of generic predicate assertion
|
||||||
|
// macros:
|
||||||
|
//
|
||||||
|
// ASSERT_PRED_FORMAT1(pred_format, v1)
|
||||||
|
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// where pred_format is a function or functor that takes n (in the
|
||||||
|
// case of ASSERT_PRED_FORMATn) values and their source expression
|
||||||
|
// text, and returns a testing::AssertionResult. See the definition
|
||||||
|
// of ASSERT_EQ in gtest.h for an example.
|
||||||
|
//
|
||||||
|
// If you don't care about formatting, you can use the more
|
||||||
|
// restrictive version:
|
||||||
|
//
|
||||||
|
// ASSERT_PRED1(pred, v1)
|
||||||
|
// ASSERT_PRED2(pred, v1, v2)
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// where pred is an n-ary function or functor that returns bool,
|
||||||
|
// and the values v1, v2, ..., must support the << operator for
|
||||||
|
// streaming to std::ostream.
|
||||||
|
//
|
||||||
|
// We also define the EXPECT_* variations.
|
||||||
|
//
|
||||||
|
// For now we only support predicates whose arity is at most 5.
|
||||||
|
// Please email googletestframework@googlegroups.com if you need
|
||||||
|
// support for higher arities.
|
||||||
|
|
||||||
|
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
||||||
|
// in this file reduce. Don't use this in your code.
|
||||||
|
|
||||||
|
#define GTEST_ASSERT_(expression, on_failure) \
|
||||||
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||||
|
if (const ::testing::AssertionResult gtest_ar = (expression)) \
|
||||||
|
; \
|
||||||
|
else \
|
||||||
|
on_failure(gtest_ar.failure_message())
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||||
|
// this in your code.
|
||||||
|
template <typename Pred,
|
||||||
|
typename T1>
|
||||||
|
AssertionResult AssertPred1Helper(const char* pred_text,
|
||||||
|
const char* e1,
|
||||||
|
Pred pred,
|
||||||
|
const T1& v1) {
|
||||||
|
if (pred(v1)) return AssertionSuccess();
|
||||||
|
|
||||||
|
return AssertionFailure()
|
||||||
|
<< pred_text << "(" << e1 << ") evaluates to false, where"
|
||||||
|
<< "\n"
|
||||||
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
|
||||||
|
// Don't use this in your code.
|
||||||
|
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
|
||||||
|
GTEST_ASSERT_(pred_format(#v1, v1), \
|
||||||
|
on_failure)
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||||
|
// this in your code.
|
||||||
|
#define GTEST_PRED1_(pred, v1, on_failure)\
|
||||||
|
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
|
||||||
|
#v1, \
|
||||||
|
pred, \
|
||||||
|
v1), on_failure)
|
||||||
|
|
||||||
|
// Unary predicate assertion macros.
|
||||||
|
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
|
||||||
|
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define EXPECT_PRED1(pred, v1) \
|
||||||
|
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
|
||||||
|
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED1(pred, v1) \
|
||||||
|
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||||
|
// this in your code.
|
||||||
|
template <typename Pred,
|
||||||
|
typename T1,
|
||||||
|
typename T2>
|
||||||
|
AssertionResult AssertPred2Helper(const char* pred_text,
|
||||||
|
const char* e1,
|
||||||
|
const char* e2,
|
||||||
|
Pred pred,
|
||||||
|
const T1& v1,
|
||||||
|
const T2& v2) {
|
||||||
|
if (pred(v1, v2)) return AssertionSuccess();
|
||||||
|
|
||||||
|
return AssertionFailure()
|
||||||
|
<< pred_text << "(" << e1 << ", " << e2
|
||||||
|
<< ") evaluates to false, where"
|
||||||
|
<< "\n"
|
||||||
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||||
|
<< e2 << " evaluates to " << ::testing::PrintToString(v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
|
||||||
|
// Don't use this in your code.
|
||||||
|
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
|
||||||
|
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
|
||||||
|
on_failure)
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||||
|
// this in your code.
|
||||||
|
#define GTEST_PRED2_(pred, v1, v2, on_failure)\
|
||||||
|
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
|
||||||
|
#v1, \
|
||||||
|
#v2, \
|
||||||
|
pred, \
|
||||||
|
v1, \
|
||||||
|
v2), on_failure)
|
||||||
|
|
||||||
|
// Binary predicate assertion macros.
|
||||||
|
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||||
|
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define EXPECT_PRED2(pred, v1, v2) \
|
||||||
|
GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||||
|
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED2(pred, v1, v2) \
|
||||||
|
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||||
|
// this in your code.
|
||||||
|
template <typename Pred,
|
||||||
|
typename T1,
|
||||||
|
typename T2,
|
||||||
|
typename T3>
|
||||||
|
AssertionResult AssertPred3Helper(const char* pred_text,
|
||||||
|
const char* e1,
|
||||||
|
const char* e2,
|
||||||
|
const char* e3,
|
||||||
|
Pred pred,
|
||||||
|
const T1& v1,
|
||||||
|
const T2& v2,
|
||||||
|
const T3& v3) {
|
||||||
|
if (pred(v1, v2, v3)) return AssertionSuccess();
|
||||||
|
|
||||||
|
return AssertionFailure()
|
||||||
|
<< pred_text << "(" << e1 << ", " << e2 << ", " << e3
|
||||||
|
<< ") evaluates to false, where"
|
||||||
|
<< "\n"
|
||||||
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||||
|
<< e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
||||||
|
<< e3 << " evaluates to " << ::testing::PrintToString(v3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
|
||||||
|
// Don't use this in your code.
|
||||||
|
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
|
||||||
|
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
|
||||||
|
on_failure)
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||||
|
// this in your code.
|
||||||
|
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
|
||||||
|
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
|
||||||
|
#v1, \
|
||||||
|
#v2, \
|
||||||
|
#v3, \
|
||||||
|
pred, \
|
||||||
|
v1, \
|
||||||
|
v2, \
|
||||||
|
v3), on_failure)
|
||||||
|
|
||||||
|
// Ternary predicate assertion macros.
|
||||||
|
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||||
|
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define EXPECT_PRED3(pred, v1, v2, v3) \
|
||||||
|
GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||||
|
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED3(pred, v1, v2, v3) \
|
||||||
|
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||||
|
// this in your code.
|
||||||
|
template <typename Pred,
|
||||||
|
typename T1,
|
||||||
|
typename T2,
|
||||||
|
typename T3,
|
||||||
|
typename T4>
|
||||||
|
AssertionResult AssertPred4Helper(const char* pred_text,
|
||||||
|
const char* e1,
|
||||||
|
const char* e2,
|
||||||
|
const char* e3,
|
||||||
|
const char* e4,
|
||||||
|
Pred pred,
|
||||||
|
const T1& v1,
|
||||||
|
const T2& v2,
|
||||||
|
const T3& v3,
|
||||||
|
const T4& v4) {
|
||||||
|
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
|
||||||
|
|
||||||
|
return AssertionFailure()
|
||||||
|
<< pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
|
||||||
|
<< ") evaluates to false, where"
|
||||||
|
<< "\n"
|
||||||
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||||
|
<< e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
||||||
|
<< e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
|
||||||
|
<< e4 << " evaluates to " << ::testing::PrintToString(v4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
|
||||||
|
// Don't use this in your code.
|
||||||
|
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
|
||||||
|
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
|
||||||
|
on_failure)
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||||
|
// this in your code.
|
||||||
|
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
|
||||||
|
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
|
||||||
|
#v1, \
|
||||||
|
#v2, \
|
||||||
|
#v3, \
|
||||||
|
#v4, \
|
||||||
|
pred, \
|
||||||
|
v1, \
|
||||||
|
v2, \
|
||||||
|
v3, \
|
||||||
|
v4), on_failure)
|
||||||
|
|
||||||
|
// 4-ary predicate assertion macros.
|
||||||
|
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||||
|
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
|
||||||
|
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||||
|
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
|
||||||
|
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||||
|
// this in your code.
|
||||||
|
template <typename Pred,
|
||||||
|
typename T1,
|
||||||
|
typename T2,
|
||||||
|
typename T3,
|
||||||
|
typename T4,
|
||||||
|
typename T5>
|
||||||
|
AssertionResult AssertPred5Helper(const char* pred_text,
|
||||||
|
const char* e1,
|
||||||
|
const char* e2,
|
||||||
|
const char* e3,
|
||||||
|
const char* e4,
|
||||||
|
const char* e5,
|
||||||
|
Pred pred,
|
||||||
|
const T1& v1,
|
||||||
|
const T2& v2,
|
||||||
|
const T3& v3,
|
||||||
|
const T4& v4,
|
||||||
|
const T5& v5) {
|
||||||
|
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
|
||||||
|
|
||||||
|
return AssertionFailure()
|
||||||
|
<< pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
|
||||||
|
<< ", " << e5 << ") evaluates to false, where"
|
||||||
|
<< "\n"
|
||||||
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||||
|
<< e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
||||||
|
<< e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
|
||||||
|
<< e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n"
|
||||||
|
<< e5 << " evaluates to " << ::testing::PrintToString(v5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
|
||||||
|
// Don't use this in your code.
|
||||||
|
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
|
||||||
|
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
|
||||||
|
on_failure)
|
||||||
|
|
||||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||||
|
// this in your code.
|
||||||
|
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
|
||||||
|
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
|
||||||
|
#v1, \
|
||||||
|
#v2, \
|
||||||
|
#v3, \
|
||||||
|
#v4, \
|
||||||
|
#v5, \
|
||||||
|
pred, \
|
||||||
|
v1, \
|
||||||
|
v2, \
|
||||||
|
v3, \
|
||||||
|
v4, \
|
||||||
|
v5), on_failure)
|
||||||
|
|
||||||
|
// 5-ary predicate assertion macros.
|
||||||
|
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||||
|
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||||
|
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||||
|
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||||
|
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||||
|
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright 2006, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Google C++ Testing and Mocking Framework definitions useful in production code.
|
||||||
|
// GOOGLETEST_CM0003 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||||
|
|
||||||
|
// When you need to test the private or protected members of a class,
|
||||||
|
// use the FRIEND_TEST macro to declare your tests as friends of the
|
||||||
|
// class. For example:
|
||||||
|
//
|
||||||
|
// class MyClass {
|
||||||
|
// private:
|
||||||
|
// void PrivateMethod();
|
||||||
|
// FRIEND_TEST(MyClassTest, PrivateMethodWorks);
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// class MyClassTest : public testing::Test {
|
||||||
|
// // ...
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// TEST_F(MyClassTest, PrivateMethodWorks) {
|
||||||
|
// // Can call MyClass::PrivateMethod() here.
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Note: The test class must be in the same namespace as the class being tested.
|
||||||
|
// For example, putting MyClassTest in an anonymous namespace will not work.
|
||||||
|
|
||||||
|
#define FRIEND_TEST(test_case_name, test_name)\
|
||||||
|
friend class test_case_name##_##test_name##_Test
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
|
@ -0,0 +1,56 @@
|
||||||
|
# Customization Points
|
||||||
|
|
||||||
|
The custom directory is an injection point for custom user configurations.
|
||||||
|
|
||||||
|
## Header `gtest.h`
|
||||||
|
|
||||||
|
### The following macros can be defined:
|
||||||
|
|
||||||
|
* `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of
|
||||||
|
`OsStackTraceGetterInterface`.
|
||||||
|
* `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See
|
||||||
|
`testing::TempDir` for semantics and signature.
|
||||||
|
|
||||||
|
## Header `gtest-port.h`
|
||||||
|
|
||||||
|
The following macros can be defined:
|
||||||
|
|
||||||
|
### Flag related macros:
|
||||||
|
|
||||||
|
* `GTEST_FLAG(flag_name)`
|
||||||
|
* `GTEST_USE_OWN_FLAGFILE_FLAG_` - Define to 0 when the system provides its
|
||||||
|
own flagfile flag parsing.
|
||||||
|
* `GTEST_DECLARE_bool_(name)`
|
||||||
|
* `GTEST_DECLARE_int32_(name)`
|
||||||
|
* `GTEST_DECLARE_string_(name)`
|
||||||
|
* `GTEST_DEFINE_bool_(name, default_val, doc)`
|
||||||
|
* `GTEST_DEFINE_int32_(name, default_val, doc)`
|
||||||
|
* `GTEST_DEFINE_string_(name, default_val, doc)`
|
||||||
|
|
||||||
|
### Logging:
|
||||||
|
|
||||||
|
* `GTEST_LOG_(severity)`
|
||||||
|
* `GTEST_CHECK_(condition)`
|
||||||
|
* Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too.
|
||||||
|
|
||||||
|
### Threading:
|
||||||
|
|
||||||
|
* `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided.
|
||||||
|
* `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal`
|
||||||
|
are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)`
|
||||||
|
and `GTEST_DEFINE_STATIC_MUTEX_(mutex)`
|
||||||
|
* `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)`
|
||||||
|
* `GTEST_LOCK_EXCLUDED_(locks)`
|
||||||
|
|
||||||
|
### Underlying library support features
|
||||||
|
|
||||||
|
* `GTEST_HAS_CXXABI_H_`
|
||||||
|
|
||||||
|
### Exporting API symbols:
|
||||||
|
|
||||||
|
* `GTEST_API_` - Specifier for exported symbols.
|
||||||
|
|
||||||
|
## Header `gtest-printers.h`
|
||||||
|
|
||||||
|
* See documentation at `gtest/gtest-printers.h` for details on how to define a
|
||||||
|
custom printer.
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2015, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Injection point for custom user configurations. See README for details
|
||||||
|
//
|
||||||
|
// ** Custom implementation starts here **
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2015, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// This file provides an injection point for custom printers in a local
|
||||||
|
// installation of gTest.
|
||||||
|
// It will be included from gtest-printers.h and the overrides in this file
|
||||||
|
// will be visible to everyone.
|
||||||
|
//
|
||||||
|
// Injection point for custom user configurations. See README for details
|
||||||
|
//
|
||||||
|
// ** Custom implementation starts here **
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2015, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Injection point for custom user configurations. See README for details
|
||||||
|
//
|
||||||
|
// ** Custom implementation starts here **
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
|
@ -0,0 +1,304 @@
|
||||||
|
// Copyright 2005, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// This header file defines internal utilities needed for implementing
|
||||||
|
// death tests. They are subject to change without notice.
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||||
|
|
||||||
|
#include "gtest/gtest-matchers.h"
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
GTEST_DECLARE_string_(internal_run_death_test);
|
||||||
|
|
||||||
|
// Names of the flags (needed for parsing Google Test flags).
|
||||||
|
const char kDeathTestStyleFlag[] = "death_test_style";
|
||||||
|
const char kDeathTestUseFork[] = "death_test_use_fork";
|
||||||
|
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
|
||||||
|
|
||||||
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
|
// DeathTest is a class that hides much of the complexity of the
|
||||||
|
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
|
||||||
|
// returns a concrete class that depends on the prevailing death test
|
||||||
|
// style, as defined by the --gtest_death_test_style and/or
|
||||||
|
// --gtest_internal_run_death_test flags.
|
||||||
|
|
||||||
|
// In describing the results of death tests, these terms are used with
|
||||||
|
// the corresponding definitions:
|
||||||
|
//
|
||||||
|
// exit status: The integer exit information in the format specified
|
||||||
|
// by wait(2)
|
||||||
|
// exit code: The integer code passed to exit(3), _exit(2), or
|
||||||
|
// returned from main()
|
||||||
|
class GTEST_API_ DeathTest {
|
||||||
|
public:
|
||||||
|
// Create returns false if there was an error determining the
|
||||||
|
// appropriate action to take for the current death test; for example,
|
||||||
|
// if the gtest_death_test_style flag is set to an invalid value.
|
||||||
|
// The LastMessage method will return a more detailed message in that
|
||||||
|
// case. Otherwise, the DeathTest pointer pointed to by the "test"
|
||||||
|
// argument is set. If the death test should be skipped, the pointer
|
||||||
|
// is set to NULL; otherwise, it is set to the address of a new concrete
|
||||||
|
// DeathTest object that controls the execution of the current test.
|
||||||
|
static bool Create(const char* statement, Matcher<const std::string&> matcher,
|
||||||
|
const char* file, int line, DeathTest** test);
|
||||||
|
DeathTest();
|
||||||
|
virtual ~DeathTest() { }
|
||||||
|
|
||||||
|
// A helper class that aborts a death test when it's deleted.
|
||||||
|
class ReturnSentinel {
|
||||||
|
public:
|
||||||
|
explicit ReturnSentinel(DeathTest* test) : test_(test) { }
|
||||||
|
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
|
||||||
|
private:
|
||||||
|
DeathTest* const test_;
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
|
||||||
|
} GTEST_ATTRIBUTE_UNUSED_;
|
||||||
|
|
||||||
|
// An enumeration of possible roles that may be taken when a death
|
||||||
|
// test is encountered. EXECUTE means that the death test logic should
|
||||||
|
// be executed immediately. OVERSEE means that the program should prepare
|
||||||
|
// the appropriate environment for a child process to execute the death
|
||||||
|
// test, then wait for it to complete.
|
||||||
|
enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
|
||||||
|
|
||||||
|
// An enumeration of the three reasons that a test might be aborted.
|
||||||
|
enum AbortReason {
|
||||||
|
TEST_ENCOUNTERED_RETURN_STATEMENT,
|
||||||
|
TEST_THREW_EXCEPTION,
|
||||||
|
TEST_DID_NOT_DIE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Assumes one of the above roles.
|
||||||
|
virtual TestRole AssumeRole() = 0;
|
||||||
|
|
||||||
|
// Waits for the death test to finish and returns its status.
|
||||||
|
virtual int Wait() = 0;
|
||||||
|
|
||||||
|
// Returns true if the death test passed; that is, the test process
|
||||||
|
// exited during the test, its exit status matches a user-supplied
|
||||||
|
// predicate, and its stderr output matches a user-supplied regular
|
||||||
|
// expression.
|
||||||
|
// The user-supplied predicate may be a macro expression rather
|
||||||
|
// than a function pointer or functor, or else Wait and Passed could
|
||||||
|
// be combined.
|
||||||
|
virtual bool Passed(bool exit_status_ok) = 0;
|
||||||
|
|
||||||
|
// Signals that the death test did not die as expected.
|
||||||
|
virtual void Abort(AbortReason reason) = 0;
|
||||||
|
|
||||||
|
// Returns a human-readable outcome message regarding the outcome of
|
||||||
|
// the last death test.
|
||||||
|
static const char* LastMessage();
|
||||||
|
|
||||||
|
static void set_last_death_test_message(const std::string& message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// A string containing a description of the outcome of the last death test.
|
||||||
|
static std::string last_death_test_message_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
|
||||||
|
};
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
|
|
||||||
|
// Factory interface for death tests. May be mocked out for testing.
|
||||||
|
class DeathTestFactory {
|
||||||
|
public:
|
||||||
|
virtual ~DeathTestFactory() { }
|
||||||
|
virtual bool Create(const char* statement,
|
||||||
|
Matcher<const std::string&> matcher, const char* file,
|
||||||
|
int line, DeathTest** test) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A concrete DeathTestFactory implementation for normal use.
|
||||||
|
class DefaultDeathTestFactory : public DeathTestFactory {
|
||||||
|
public:
|
||||||
|
bool Create(const char* statement, Matcher<const std::string&> matcher,
|
||||||
|
const char* file, int line, DeathTest** test) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns true if exit_status describes a process that was terminated
|
||||||
|
// by a signal, or exited normally with a nonzero exit code.
|
||||||
|
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
||||||
|
|
||||||
|
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
|
||||||
|
// and interpreted as a regex (rather than an Eq matcher) for legacy
|
||||||
|
// compatibility.
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||||
|
::testing::internal::RE regex) {
|
||||||
|
return ContainsRegex(regex.pattern());
|
||||||
|
}
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
|
||||||
|
return ContainsRegex(regex);
|
||||||
|
}
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||||
|
const ::std::string& regex) {
|
||||||
|
return ContainsRegex(regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
|
||||||
|
// used directly.
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||||
|
Matcher<const ::std::string&> matcher) {
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traps C++ exceptions escaping statement and reports them as test
|
||||||
|
// failures. Note that trapping SEH exceptions is not implemented here.
|
||||||
|
# if GTEST_HAS_EXCEPTIONS
|
||||||
|
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
||||||
|
try { \
|
||||||
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||||
|
} catch (const ::std::exception& gtest_exception) { \
|
||||||
|
fprintf(\
|
||||||
|
stderr, \
|
||||||
|
"\n%s: Caught std::exception-derived exception escaping the " \
|
||||||
|
"death test statement. Exception message: %s\n", \
|
||||||
|
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
|
||||||
|
gtest_exception.what()); \
|
||||||
|
fflush(stderr); \
|
||||||
|
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
||||||
|
} catch (...) { \
|
||||||
|
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
||||||
|
}
|
||||||
|
|
||||||
|
# else
|
||||||
|
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
||||||
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
|
||||||
|
// ASSERT_EXIT*, and EXPECT_EXIT*.
|
||||||
|
#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail) \
|
||||||
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||||
|
if (::testing::internal::AlwaysTrue()) { \
|
||||||
|
::testing::internal::DeathTest* gtest_dt; \
|
||||||
|
if (!::testing::internal::DeathTest::Create( \
|
||||||
|
#statement, \
|
||||||
|
::testing::internal::MakeDeathTestMatcher(regex_or_matcher), \
|
||||||
|
__FILE__, __LINE__, >est_dt)) { \
|
||||||
|
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||||
|
} \
|
||||||
|
if (gtest_dt != nullptr) { \
|
||||||
|
std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \
|
||||||
|
switch (gtest_dt->AssumeRole()) { \
|
||||||
|
case ::testing::internal::DeathTest::OVERSEE_TEST: \
|
||||||
|
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
|
||||||
|
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
|
||||||
|
::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
|
||||||
|
gtest_dt); \
|
||||||
|
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
|
||||||
|
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
default: \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} else \
|
||||||
|
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \
|
||||||
|
: fail(::testing::internal::DeathTest::LastMessage())
|
||||||
|
// The symbol "fail" here expands to something into which a message
|
||||||
|
// can be streamed.
|
||||||
|
|
||||||
|
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
|
||||||
|
// NDEBUG mode. In this case we need the statements to be executed and the macro
|
||||||
|
// must accept a streamed message even though the message is never printed.
|
||||||
|
// The regex object is not evaluated, but it is used to prevent "unused"
|
||||||
|
// warnings and to avoid an expression that doesn't compile in debug mode.
|
||||||
|
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
|
||||||
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||||
|
if (::testing::internal::AlwaysTrue()) { \
|
||||||
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||||
|
} else if (!::testing::internal::AlwaysTrue()) { \
|
||||||
|
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
||||||
|
} else \
|
||||||
|
::testing::Message()
|
||||||
|
|
||||||
|
// A class representing the parsed contents of the
|
||||||
|
// --gtest_internal_run_death_test flag, as it existed when
|
||||||
|
// RUN_ALL_TESTS was called.
|
||||||
|
class InternalRunDeathTestFlag {
|
||||||
|
public:
|
||||||
|
InternalRunDeathTestFlag(const std::string& a_file,
|
||||||
|
int a_line,
|
||||||
|
int an_index,
|
||||||
|
int a_write_fd)
|
||||||
|
: file_(a_file), line_(a_line), index_(an_index),
|
||||||
|
write_fd_(a_write_fd) {}
|
||||||
|
|
||||||
|
~InternalRunDeathTestFlag() {
|
||||||
|
if (write_fd_ >= 0)
|
||||||
|
posix::Close(write_fd_);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& file() const { return file_; }
|
||||||
|
int line() const { return line_; }
|
||||||
|
int index() const { return index_; }
|
||||||
|
int write_fd() const { return write_fd_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string file_;
|
||||||
|
int line_;
|
||||||
|
int index_;
|
||||||
|
int write_fd_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns a newly created InternalRunDeathTestFlag object with fields
|
||||||
|
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
||||||
|
// the flag is specified; otherwise returns NULL.
|
||||||
|
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
|
@ -0,0 +1,211 @@
|
||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Google Test filepath utilities
|
||||||
|
//
|
||||||
|
// This header file declares classes and functions used internally by
|
||||||
|
// Google Test. They are subject to change without notice.
|
||||||
|
//
|
||||||
|
// This file is #included in gtest/internal/gtest-internal.h.
|
||||||
|
// Do not include this header file separately!
|
||||||
|
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-string.h"
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// FilePath - a class for file and directory pathname manipulation which
|
||||||
|
// handles platform-specific conventions (like the pathname separator).
|
||||||
|
// Used for helper functions for naming files in a directory for xml output.
|
||||||
|
// Except for Set methods, all methods are const or static, which provides an
|
||||||
|
// "immutable value object" -- useful for peace of mind.
|
||||||
|
// A FilePath with a value ending in a path separator ("like/this/") represents
|
||||||
|
// a directory, otherwise it is assumed to represent a file. In either case,
|
||||||
|
// it may or may not represent an actual file or directory in the file system.
|
||||||
|
// Names are NOT checked for syntax correctness -- no checking for illegal
|
||||||
|
// characters, malformed paths, etc.
|
||||||
|
|
||||||
|
class GTEST_API_ FilePath {
|
||||||
|
public:
|
||||||
|
FilePath() : pathname_("") { }
|
||||||
|
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
|
||||||
|
|
||||||
|
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
|
||||||
|
Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath& operator=(const FilePath& rhs) {
|
||||||
|
Set(rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(const FilePath& rhs) {
|
||||||
|
pathname_ = rhs.pathname_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& string() const { return pathname_; }
|
||||||
|
const char* c_str() const { return pathname_.c_str(); }
|
||||||
|
|
||||||
|
// Returns the current working directory, or "" if unsuccessful.
|
||||||
|
static FilePath GetCurrentDir();
|
||||||
|
|
||||||
|
// Given directory = "dir", base_name = "test", number = 0,
|
||||||
|
// extension = "xml", returns "dir/test.xml". If number is greater
|
||||||
|
// than zero (e.g., 12), returns "dir/test_12.xml".
|
||||||
|
// On Windows platform, uses \ as the separator rather than /.
|
||||||
|
static FilePath MakeFileName(const FilePath& directory,
|
||||||
|
const FilePath& base_name,
|
||||||
|
int number,
|
||||||
|
const char* extension);
|
||||||
|
|
||||||
|
// Given directory = "dir", relative_path = "test.xml",
|
||||||
|
// returns "dir/test.xml".
|
||||||
|
// On Windows, uses \ as the separator rather than /.
|
||||||
|
static FilePath ConcatPaths(const FilePath& directory,
|
||||||
|
const FilePath& relative_path);
|
||||||
|
|
||||||
|
// Returns a pathname for a file that does not currently exist. The pathname
|
||||||
|
// will be directory/base_name.extension or
|
||||||
|
// directory/base_name_<number>.extension if directory/base_name.extension
|
||||||
|
// already exists. The number will be incremented until a pathname is found
|
||||||
|
// that does not already exist.
|
||||||
|
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
||||||
|
// There could be a race condition if two or more processes are calling this
|
||||||
|
// function at the same time -- they could both pick the same filename.
|
||||||
|
static FilePath GenerateUniqueFileName(const FilePath& directory,
|
||||||
|
const FilePath& base_name,
|
||||||
|
const char* extension);
|
||||||
|
|
||||||
|
// Returns true if and only if the path is "".
|
||||||
|
bool IsEmpty() const { return pathname_.empty(); }
|
||||||
|
|
||||||
|
// If input name has a trailing separator character, removes it and returns
|
||||||
|
// the name, otherwise return the name string unmodified.
|
||||||
|
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||||
|
FilePath RemoveTrailingPathSeparator() const;
|
||||||
|
|
||||||
|
// Returns a copy of the FilePath with the directory part removed.
|
||||||
|
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||||
|
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||||
|
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
||||||
|
// returns an empty FilePath ("").
|
||||||
|
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||||
|
FilePath RemoveDirectoryName() const;
|
||||||
|
|
||||||
|
// RemoveFileName returns the directory path with the filename removed.
|
||||||
|
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
||||||
|
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
||||||
|
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
||||||
|
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
||||||
|
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||||
|
FilePath RemoveFileName() const;
|
||||||
|
|
||||||
|
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||||
|
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
||||||
|
// FilePath("dir/file"). If a case-insensitive extension is not
|
||||||
|
// found, returns a copy of the original FilePath.
|
||||||
|
FilePath RemoveExtension(const char* extension) const;
|
||||||
|
|
||||||
|
// Creates directories so that path exists. Returns true if successful or if
|
||||||
|
// the directories already exist; returns false if unable to create
|
||||||
|
// directories for any reason. Will also return false if the FilePath does
|
||||||
|
// not represent a directory (that is, it doesn't end with a path separator).
|
||||||
|
bool CreateDirectoriesRecursively() const;
|
||||||
|
|
||||||
|
// Create the directory so that path exists. Returns true if successful or
|
||||||
|
// if the directory already exists; returns false if unable to create the
|
||||||
|
// directory for any reason, including if the parent directory does not
|
||||||
|
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||||
|
bool CreateFolder() const;
|
||||||
|
|
||||||
|
// Returns true if FilePath describes something in the file-system,
|
||||||
|
// either a file, directory, or whatever, and that something exists.
|
||||||
|
bool FileOrDirectoryExists() const;
|
||||||
|
|
||||||
|
// Returns true if pathname describes a directory in the file-system
|
||||||
|
// that exists.
|
||||||
|
bool DirectoryExists() const;
|
||||||
|
|
||||||
|
// Returns true if FilePath ends with a path separator, which indicates that
|
||||||
|
// it is intended to represent a directory. Returns false otherwise.
|
||||||
|
// This does NOT check that a directory (or file) actually exists.
|
||||||
|
bool IsDirectory() const;
|
||||||
|
|
||||||
|
// Returns true if pathname describes a root directory. (Windows has one
|
||||||
|
// root directory per disk drive.)
|
||||||
|
bool IsRootDirectory() const;
|
||||||
|
|
||||||
|
// Returns true if pathname describes an absolute path.
|
||||||
|
bool IsAbsolutePath() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Replaces multiple consecutive separators with a single separator.
|
||||||
|
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||||
|
// redundancies that might be in a pathname involving "." or "..".
|
||||||
|
//
|
||||||
|
// A pathname with multiple consecutive separators may occur either through
|
||||||
|
// user error or as a result of some scripts or APIs that generate a pathname
|
||||||
|
// with a trailing separator. On other platforms the same API or script
|
||||||
|
// may NOT generate a pathname with a trailing "/". Then elsewhere that
|
||||||
|
// pathname may have another "/" and pathname components added to it,
|
||||||
|
// without checking for the separator already being there.
|
||||||
|
// The script language and operating system may allow paths like "foo//bar"
|
||||||
|
// but some of the functions in FilePath will not handle that correctly. In
|
||||||
|
// particular, RemoveTrailingPathSeparator() only removes one separator, and
|
||||||
|
// it is called in CreateDirectoriesRecursively() assuming that it will change
|
||||||
|
// a pathname from directory syntax (trailing separator) to filename syntax.
|
||||||
|
//
|
||||||
|
// On Windows this method also replaces the alternate path separator '/' with
|
||||||
|
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
|
||||||
|
// "bar\\foo".
|
||||||
|
|
||||||
|
void Normalize();
|
||||||
|
|
||||||
|
// Returns a pointer to the last occurence of a valid path separator in
|
||||||
|
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||||
|
// separators. Returns NULL if no path separator was found.
|
||||||
|
const char* FindLastPathSeparator() const;
|
||||||
|
|
||||||
|
std::string pathname_;
|
||||||
|
}; // class FilePath
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,934 @@
|
||||||
|
// Copyright 2008 Google Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
// Type and function utilities for implementing parameterized tests.
|
||||||
|
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
#include "gtest/gtest-printers.h"
|
||||||
|
#include "gtest/gtest-test-part.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
// Input to a parameterized test name generator, describing a test parameter.
|
||||||
|
// Consists of the parameter value and the integer parameter index.
|
||||||
|
template <class ParamType>
|
||||||
|
struct TestParamInfo {
|
||||||
|
TestParamInfo(const ParamType& a_param, size_t an_index) :
|
||||||
|
param(a_param),
|
||||||
|
index(an_index) {}
|
||||||
|
ParamType param;
|
||||||
|
size_t index;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A builtin parameterized test name generator which returns the result of
|
||||||
|
// testing::PrintToString.
|
||||||
|
struct PrintToStringParamName {
|
||||||
|
template <class ParamType>
|
||||||
|
std::string operator()(const TestParamInfo<ParamType>& info) const {
|
||||||
|
return PrintToString(info.param);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
// Utility Functions
|
||||||
|
|
||||||
|
// Outputs a message explaining invalid registration of different
|
||||||
|
// fixture class for the same test suite. This may happen when
|
||||||
|
// TEST_P macro is used to define two tests with the same name
|
||||||
|
// but in different namespaces.
|
||||||
|
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
||||||
|
CodeLocation code_location);
|
||||||
|
|
||||||
|
template <typename> class ParamGeneratorInterface;
|
||||||
|
template <typename> class ParamGenerator;
|
||||||
|
|
||||||
|
// Interface for iterating over elements provided by an implementation
|
||||||
|
// of ParamGeneratorInterface<T>.
|
||||||
|
template <typename T>
|
||||||
|
class ParamIteratorInterface {
|
||||||
|
public:
|
||||||
|
virtual ~ParamIteratorInterface() {}
|
||||||
|
// A pointer to the base generator instance.
|
||||||
|
// Used only for the purposes of iterator comparison
|
||||||
|
// to make sure that two iterators belong to the same generator.
|
||||||
|
virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
|
||||||
|
// Advances iterator to point to the next element
|
||||||
|
// provided by the generator. The caller is responsible
|
||||||
|
// for not calling Advance() on an iterator equal to
|
||||||
|
// BaseGenerator()->End().
|
||||||
|
virtual void Advance() = 0;
|
||||||
|
// Clones the iterator object. Used for implementing copy semantics
|
||||||
|
// of ParamIterator<T>.
|
||||||
|
virtual ParamIteratorInterface* Clone() const = 0;
|
||||||
|
// Dereferences the current iterator and provides (read-only) access
|
||||||
|
// to the pointed value. It is the caller's responsibility not to call
|
||||||
|
// Current() on an iterator equal to BaseGenerator()->End().
|
||||||
|
// Used for implementing ParamGenerator<T>::operator*().
|
||||||
|
virtual const T* Current() const = 0;
|
||||||
|
// Determines whether the given iterator and other point to the same
|
||||||
|
// element in the sequence generated by the generator.
|
||||||
|
// Used for implementing ParamGenerator<T>::operator==().
|
||||||
|
virtual bool Equals(const ParamIteratorInterface& other) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Class iterating over elements provided by an implementation of
|
||||||
|
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
|
||||||
|
// and implements the const forward iterator concept.
|
||||||
|
template <typename T>
|
||||||
|
class ParamIterator {
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef const T& reference;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
|
||||||
|
// ParamIterator assumes ownership of the impl_ pointer.
|
||||||
|
ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
|
||||||
|
ParamIterator& operator=(const ParamIterator& other) {
|
||||||
|
if (this != &other)
|
||||||
|
impl_.reset(other.impl_->Clone());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator*() const { return *impl_->Current(); }
|
||||||
|
const T* operator->() const { return impl_->Current(); }
|
||||||
|
// Prefix version of operator++.
|
||||||
|
ParamIterator& operator++() {
|
||||||
|
impl_->Advance();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
// Postfix version of operator++.
|
||||||
|
ParamIterator operator++(int /*unused*/) {
|
||||||
|
ParamIteratorInterface<T>* clone = impl_->Clone();
|
||||||
|
impl_->Advance();
|
||||||
|
return ParamIterator(clone);
|
||||||
|
}
|
||||||
|
bool operator==(const ParamIterator& other) const {
|
||||||
|
return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
|
||||||
|
}
|
||||||
|
bool operator!=(const ParamIterator& other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class ParamGenerator<T>;
|
||||||
|
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
|
||||||
|
std::unique_ptr<ParamIteratorInterface<T> > impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ParamGeneratorInterface<T> is the binary interface to access generators
|
||||||
|
// defined in other translation units.
|
||||||
|
template <typename T>
|
||||||
|
class ParamGeneratorInterface {
|
||||||
|
public:
|
||||||
|
typedef T ParamType;
|
||||||
|
|
||||||
|
virtual ~ParamGeneratorInterface() {}
|
||||||
|
|
||||||
|
// Generator interface definition
|
||||||
|
virtual ParamIteratorInterface<T>* Begin() const = 0;
|
||||||
|
virtual ParamIteratorInterface<T>* End() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wraps ParamGeneratorInterface<T> and provides general generator syntax
|
||||||
|
// compatible with the STL Container concept.
|
||||||
|
// This class implements copy initialization semantics and the contained
|
||||||
|
// ParamGeneratorInterface<T> instance is shared among all copies
|
||||||
|
// of the original object. This is possible because that instance is immutable.
|
||||||
|
template<typename T>
|
||||||
|
class ParamGenerator {
|
||||||
|
public:
|
||||||
|
typedef ParamIterator<T> iterator;
|
||||||
|
|
||||||
|
explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
|
||||||
|
ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
|
||||||
|
|
||||||
|
ParamGenerator& operator=(const ParamGenerator& other) {
|
||||||
|
impl_ = other.impl_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator begin() const { return iterator(impl_->Begin()); }
|
||||||
|
iterator end() const { return iterator(impl_->End()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<const ParamGeneratorInterface<T> > impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generates values from a range of two comparable values. Can be used to
|
||||||
|
// generate sequences of user-defined types that implement operator+() and
|
||||||
|
// operator<().
|
||||||
|
// This class is used in the Range() function.
|
||||||
|
template <typename T, typename IncrementT>
|
||||||
|
class RangeGenerator : public ParamGeneratorInterface<T> {
|
||||||
|
public:
|
||||||
|
RangeGenerator(T begin, T end, IncrementT step)
|
||||||
|
: begin_(begin), end_(end),
|
||||||
|
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
|
||||||
|
~RangeGenerator() override {}
|
||||||
|
|
||||||
|
ParamIteratorInterface<T>* Begin() const override {
|
||||||
|
return new Iterator(this, begin_, 0, step_);
|
||||||
|
}
|
||||||
|
ParamIteratorInterface<T>* End() const override {
|
||||||
|
return new Iterator(this, end_, end_index_, step_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Iterator : public ParamIteratorInterface<T> {
|
||||||
|
public:
|
||||||
|
Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
|
||||||
|
IncrementT step)
|
||||||
|
: base_(base), value_(value), index_(index), step_(step) {}
|
||||||
|
~Iterator() override {}
|
||||||
|
|
||||||
|
const ParamGeneratorInterface<T>* BaseGenerator() const override {
|
||||||
|
return base_;
|
||||||
|
}
|
||||||
|
void Advance() override {
|
||||||
|
value_ = static_cast<T>(value_ + step_);
|
||||||
|
index_++;
|
||||||
|
}
|
||||||
|
ParamIteratorInterface<T>* Clone() const override {
|
||||||
|
return new Iterator(*this);
|
||||||
|
}
|
||||||
|
const T* Current() const override { return &value_; }
|
||||||
|
bool Equals(const ParamIteratorInterface<T>& other) const override {
|
||||||
|
// Having the same base generator guarantees that the other
|
||||||
|
// iterator is of the same type and we can downcast.
|
||||||
|
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
||||||
|
<< "The program attempted to compare iterators "
|
||||||
|
<< "from different generators." << std::endl;
|
||||||
|
const int other_index =
|
||||||
|
CheckedDowncastToActualType<const Iterator>(&other)->index_;
|
||||||
|
return index_ == other_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Iterator(const Iterator& other)
|
||||||
|
: ParamIteratorInterface<T>(),
|
||||||
|
base_(other.base_), value_(other.value_), index_(other.index_),
|
||||||
|
step_(other.step_) {}
|
||||||
|
|
||||||
|
// No implementation - assignment is unsupported.
|
||||||
|
void operator=(const Iterator& other);
|
||||||
|
|
||||||
|
const ParamGeneratorInterface<T>* const base_;
|
||||||
|
T value_;
|
||||||
|
int index_;
|
||||||
|
const IncrementT step_;
|
||||||
|
}; // class RangeGenerator::Iterator
|
||||||
|
|
||||||
|
static int CalculateEndIndex(const T& begin,
|
||||||
|
const T& end,
|
||||||
|
const IncrementT& step) {
|
||||||
|
int end_index = 0;
|
||||||
|
for (T i = begin; i < end; i = static_cast<T>(i + step))
|
||||||
|
end_index++;
|
||||||
|
return end_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No implementation - assignment is unsupported.
|
||||||
|
void operator=(const RangeGenerator& other);
|
||||||
|
|
||||||
|
const T begin_;
|
||||||
|
const T end_;
|
||||||
|
const IncrementT step_;
|
||||||
|
// The index for the end() iterator. All the elements in the generated
|
||||||
|
// sequence are indexed (0-based) to aid iterator comparison.
|
||||||
|
const int end_index_;
|
||||||
|
}; // class RangeGenerator
|
||||||
|
|
||||||
|
|
||||||
|
// Generates values from a pair of STL-style iterators. Used in the
|
||||||
|
// ValuesIn() function. The elements are copied from the source range
|
||||||
|
// since the source can be located on the stack, and the generator
|
||||||
|
// is likely to persist beyond that stack frame.
|
||||||
|
template <typename T>
|
||||||
|
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
||||||
|
public:
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
|
||||||
|
: container_(begin, end) {}
|
||||||
|
~ValuesInIteratorRangeGenerator() override {}
|
||||||
|
|
||||||
|
ParamIteratorInterface<T>* Begin() const override {
|
||||||
|
return new Iterator(this, container_.begin());
|
||||||
|
}
|
||||||
|
ParamIteratorInterface<T>* End() const override {
|
||||||
|
return new Iterator(this, container_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef typename ::std::vector<T> ContainerType;
|
||||||
|
|
||||||
|
class Iterator : public ParamIteratorInterface<T> {
|
||||||
|
public:
|
||||||
|
Iterator(const ParamGeneratorInterface<T>* base,
|
||||||
|
typename ContainerType::const_iterator iterator)
|
||||||
|
: base_(base), iterator_(iterator) {}
|
||||||
|
~Iterator() override {}
|
||||||
|
|
||||||
|
const ParamGeneratorInterface<T>* BaseGenerator() const override {
|
||||||
|
return base_;
|
||||||
|
}
|
||||||
|
void Advance() override {
|
||||||
|
++iterator_;
|
||||||
|
value_.reset();
|
||||||
|
}
|
||||||
|
ParamIteratorInterface<T>* Clone() const override {
|
||||||
|
return new Iterator(*this);
|
||||||
|
}
|
||||||
|
// We need to use cached value referenced by iterator_ because *iterator_
|
||||||
|
// can return a temporary object (and of type other then T), so just
|
||||||
|
// having "return &*iterator_;" doesn't work.
|
||||||
|
// value_ is updated here and not in Advance() because Advance()
|
||||||
|
// can advance iterator_ beyond the end of the range, and we cannot
|
||||||
|
// detect that fact. The client code, on the other hand, is
|
||||||
|
// responsible for not calling Current() on an out-of-range iterator.
|
||||||
|
const T* Current() const override {
|
||||||
|
if (value_.get() == nullptr) value_.reset(new T(*iterator_));
|
||||||
|
return value_.get();
|
||||||
|
}
|
||||||
|
bool Equals(const ParamIteratorInterface<T>& other) const override {
|
||||||
|
// Having the same base generator guarantees that the other
|
||||||
|
// iterator is of the same type and we can downcast.
|
||||||
|
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
||||||
|
<< "The program attempted to compare iterators "
|
||||||
|
<< "from different generators." << std::endl;
|
||||||
|
return iterator_ ==
|
||||||
|
CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Iterator(const Iterator& other)
|
||||||
|
// The explicit constructor call suppresses a false warning
|
||||||
|
// emitted by gcc when supplied with the -Wextra option.
|
||||||
|
: ParamIteratorInterface<T>(),
|
||||||
|
base_(other.base_),
|
||||||
|
iterator_(other.iterator_) {}
|
||||||
|
|
||||||
|
const ParamGeneratorInterface<T>* const base_;
|
||||||
|
typename ContainerType::const_iterator iterator_;
|
||||||
|
// A cached value of *iterator_. We keep it here to allow access by
|
||||||
|
// pointer in the wrapping iterator's operator->().
|
||||||
|
// value_ needs to be mutable to be accessed in Current().
|
||||||
|
// Use of std::unique_ptr helps manage cached value's lifetime,
|
||||||
|
// which is bound by the lifespan of the iterator itself.
|
||||||
|
mutable std::unique_ptr<const T> value_;
|
||||||
|
}; // class ValuesInIteratorRangeGenerator::Iterator
|
||||||
|
|
||||||
|
// No implementation - assignment is unsupported.
|
||||||
|
void operator=(const ValuesInIteratorRangeGenerator& other);
|
||||||
|
|
||||||
|
const ContainerType container_;
|
||||||
|
}; // class ValuesInIteratorRangeGenerator
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// Default parameterized test name generator, returns a string containing the
|
||||||
|
// integer test parameter index.
|
||||||
|
template <class ParamType>
|
||||||
|
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
||||||
|
Message name_stream;
|
||||||
|
name_stream << info.index;
|
||||||
|
return name_stream.GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T = int>
|
||||||
|
void TestNotEmpty() {
|
||||||
|
static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
|
||||||
|
}
|
||||||
|
template <typename T = int>
|
||||||
|
void TestNotEmpty(const T&) {}
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// Stores a parameter value and later creates tests parameterized with that
|
||||||
|
// value.
|
||||||
|
template <class TestClass>
|
||||||
|
class ParameterizedTestFactory : public TestFactoryBase {
|
||||||
|
public:
|
||||||
|
typedef typename TestClass::ParamType ParamType;
|
||||||
|
explicit ParameterizedTestFactory(ParamType parameter) :
|
||||||
|
parameter_(parameter) {}
|
||||||
|
Test* CreateTest() override {
|
||||||
|
TestClass::SetParam(¶meter_);
|
||||||
|
return new TestClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ParamType parameter_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
|
||||||
|
};
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// TestMetaFactoryBase is a base class for meta-factories that create
|
||||||
|
// test factories for passing into MakeAndRegisterTestInfo function.
|
||||||
|
template <class ParamType>
|
||||||
|
class TestMetaFactoryBase {
|
||||||
|
public:
|
||||||
|
virtual ~TestMetaFactoryBase() {}
|
||||||
|
|
||||||
|
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// TestMetaFactory creates test factories for passing into
|
||||||
|
// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
|
||||||
|
// ownership of test factory pointer, same factory object cannot be passed
|
||||||
|
// into that method twice. But ParameterizedTestSuiteInfo is going to call
|
||||||
|
// it for each Test/Parameter value combination. Thus it needs meta factory
|
||||||
|
// creator class.
|
||||||
|
template <class TestSuite>
|
||||||
|
class TestMetaFactory
|
||||||
|
: public TestMetaFactoryBase<typename TestSuite::ParamType> {
|
||||||
|
public:
|
||||||
|
using ParamType = typename TestSuite::ParamType;
|
||||||
|
|
||||||
|
TestMetaFactory() {}
|
||||||
|
|
||||||
|
TestFactoryBase* CreateTestFactory(ParamType parameter) override {
|
||||||
|
return new ParameterizedTestFactory<TestSuite>(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
|
||||||
|
};
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// ParameterizedTestSuiteInfoBase is a generic interface
|
||||||
|
// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
|
||||||
|
// accumulates test information provided by TEST_P macro invocations
|
||||||
|
// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
|
||||||
|
// and uses that information to register all resulting test instances
|
||||||
|
// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
|
||||||
|
// a collection of pointers to the ParameterizedTestSuiteInfo objects
|
||||||
|
// and calls RegisterTests() on each of them when asked.
|
||||||
|
class ParameterizedTestSuiteInfoBase {
|
||||||
|
public:
|
||||||
|
virtual ~ParameterizedTestSuiteInfoBase() {}
|
||||||
|
|
||||||
|
// Base part of test suite name for display purposes.
|
||||||
|
virtual const std::string& GetTestSuiteName() const = 0;
|
||||||
|
// Test case id to verify identity.
|
||||||
|
virtual TypeId GetTestSuiteTypeId() const = 0;
|
||||||
|
// UnitTest class invokes this method to register tests in this
|
||||||
|
// test suite right before running them in RUN_ALL_TESTS macro.
|
||||||
|
// This method should not be called more than once on any single
|
||||||
|
// instance of a ParameterizedTestSuiteInfoBase derived class.
|
||||||
|
virtual void RegisterTests() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ParameterizedTestSuiteInfoBase() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
|
||||||
|
};
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// Report a the name of a test_suit as safe to ignore
|
||||||
|
// as the side effect of construction of this type.
|
||||||
|
struct MarkAsIgnored {
|
||||||
|
explicit MarkAsIgnored(const char* test_suite);
|
||||||
|
};
|
||||||
|
|
||||||
|
GTEST_API_ void InsertSyntheticTestCase(const std::string& name,
|
||||||
|
CodeLocation location, bool has_test_p);
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
|
||||||
|
// macro invocations for a particular test suite and generators
|
||||||
|
// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
|
||||||
|
// test suite. It registers tests with all values generated by all
|
||||||
|
// generators when asked.
|
||||||
|
template <class TestSuite>
|
||||||
|
class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||||
|
public:
|
||||||
|
// ParamType and GeneratorCreationFunc are private types but are required
|
||||||
|
// for declarations of public methods AddTestPattern() and
|
||||||
|
// AddTestSuiteInstantiation().
|
||||||
|
using ParamType = typename TestSuite::ParamType;
|
||||||
|
// A function that returns an instance of appropriate generator type.
|
||||||
|
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
||||||
|
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
|
||||||
|
|
||||||
|
explicit ParameterizedTestSuiteInfo(const char* name,
|
||||||
|
CodeLocation code_location)
|
||||||
|
: test_suite_name_(name), code_location_(code_location) {}
|
||||||
|
|
||||||
|
// Test case base name for display purposes.
|
||||||
|
const std::string& GetTestSuiteName() const override {
|
||||||
|
return test_suite_name_;
|
||||||
|
}
|
||||||
|
// Test case id to verify identity.
|
||||||
|
TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
|
||||||
|
// TEST_P macro uses AddTestPattern() to record information
|
||||||
|
// about a single test in a LocalTestInfo structure.
|
||||||
|
// test_suite_name is the base name of the test suite (without invocation
|
||||||
|
// prefix). test_base_name is the name of an individual test without
|
||||||
|
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
||||||
|
// test suite base name and DoBar is test base name.
|
||||||
|
void AddTestPattern(const char* test_suite_name, const char* test_base_name,
|
||||||
|
TestMetaFactoryBase<ParamType>* meta_factory) {
|
||||||
|
tests_.push_back(std::shared_ptr<TestInfo>(
|
||||||
|
new TestInfo(test_suite_name, test_base_name, meta_factory)));
|
||||||
|
}
|
||||||
|
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
|
||||||
|
// about a generator.
|
||||||
|
int AddTestSuiteInstantiation(const std::string& instantiation_name,
|
||||||
|
GeneratorCreationFunc* func,
|
||||||
|
ParamNameGeneratorFunc* name_func,
|
||||||
|
const char* file, int line) {
|
||||||
|
instantiations_.push_back(
|
||||||
|
InstantiationInfo(instantiation_name, func, name_func, file, line));
|
||||||
|
return 0; // Return value used only to run this method in namespace scope.
|
||||||
|
}
|
||||||
|
// UnitTest class invokes this method to register tests in this test suite
|
||||||
|
// right before running tests in RUN_ALL_TESTS macro.
|
||||||
|
// This method should not be called more than once on any single
|
||||||
|
// instance of a ParameterizedTestSuiteInfoBase derived class.
|
||||||
|
// UnitTest has a guard to prevent from calling this method more than once.
|
||||||
|
void RegisterTests() override {
|
||||||
|
bool generated_instantiations = false;
|
||||||
|
|
||||||
|
for (typename TestInfoContainer::iterator test_it = tests_.begin();
|
||||||
|
test_it != tests_.end(); ++test_it) {
|
||||||
|
std::shared_ptr<TestInfo> test_info = *test_it;
|
||||||
|
for (typename InstantiationContainer::iterator gen_it =
|
||||||
|
instantiations_.begin(); gen_it != instantiations_.end();
|
||||||
|
++gen_it) {
|
||||||
|
const std::string& instantiation_name = gen_it->name;
|
||||||
|
ParamGenerator<ParamType> generator((*gen_it->generator)());
|
||||||
|
ParamNameGeneratorFunc* name_func = gen_it->name_func;
|
||||||
|
const char* file = gen_it->file;
|
||||||
|
int line = gen_it->line;
|
||||||
|
|
||||||
|
std::string test_suite_name;
|
||||||
|
if ( !instantiation_name.empty() )
|
||||||
|
test_suite_name = instantiation_name + "/";
|
||||||
|
test_suite_name += test_info->test_suite_base_name;
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
std::set<std::string> test_param_names;
|
||||||
|
for (typename ParamGenerator<ParamType>::iterator param_it =
|
||||||
|
generator.begin();
|
||||||
|
param_it != generator.end(); ++param_it, ++i) {
|
||||||
|
generated_instantiations = true;
|
||||||
|
|
||||||
|
Message test_name_stream;
|
||||||
|
|
||||||
|
std::string param_name = name_func(
|
||||||
|
TestParamInfo<ParamType>(*param_it, i));
|
||||||
|
|
||||||
|
GTEST_CHECK_(IsValidParamName(param_name))
|
||||||
|
<< "Parameterized test name '" << param_name
|
||||||
|
<< "' is invalid, in " << file
|
||||||
|
<< " line " << line << std::endl;
|
||||||
|
|
||||||
|
GTEST_CHECK_(test_param_names.count(param_name) == 0)
|
||||||
|
<< "Duplicate parameterized test name '" << param_name
|
||||||
|
<< "', in " << file << " line " << line << std::endl;
|
||||||
|
|
||||||
|
test_param_names.insert(param_name);
|
||||||
|
|
||||||
|
if (!test_info->test_base_name.empty()) {
|
||||||
|
test_name_stream << test_info->test_base_name << "/";
|
||||||
|
}
|
||||||
|
test_name_stream << param_name;
|
||||||
|
MakeAndRegisterTestInfo(
|
||||||
|
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
|
||||||
|
nullptr, // No type parameter.
|
||||||
|
PrintToString(*param_it).c_str(), code_location_,
|
||||||
|
GetTestSuiteTypeId(),
|
||||||
|
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
||||||
|
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
|
||||||
|
test_info->test_meta_factory->CreateTestFactory(*param_it));
|
||||||
|
} // for param_it
|
||||||
|
} // for gen_it
|
||||||
|
} // for test_it
|
||||||
|
|
||||||
|
if (!generated_instantiations) {
|
||||||
|
// There are no generaotrs, or they all generate nothing ...
|
||||||
|
InsertSyntheticTestCase(GetTestSuiteName(), code_location_,
|
||||||
|
!tests_.empty());
|
||||||
|
}
|
||||||
|
} // RegisterTests
|
||||||
|
|
||||||
|
private:
|
||||||
|
// LocalTestInfo structure keeps information about a single test registered
|
||||||
|
// with TEST_P macro.
|
||||||
|
struct TestInfo {
|
||||||
|
TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
|
||||||
|
TestMetaFactoryBase<ParamType>* a_test_meta_factory)
|
||||||
|
: test_suite_base_name(a_test_suite_base_name),
|
||||||
|
test_base_name(a_test_base_name),
|
||||||
|
test_meta_factory(a_test_meta_factory) {}
|
||||||
|
|
||||||
|
const std::string test_suite_base_name;
|
||||||
|
const std::string test_base_name;
|
||||||
|
const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
|
||||||
|
};
|
||||||
|
using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
|
||||||
|
// Records data received from INSTANTIATE_TEST_SUITE_P macros:
|
||||||
|
// <Instantiation name, Sequence generator creation function,
|
||||||
|
// Name generator function, Source file, Source line>
|
||||||
|
struct InstantiationInfo {
|
||||||
|
InstantiationInfo(const std::string &name_in,
|
||||||
|
GeneratorCreationFunc* generator_in,
|
||||||
|
ParamNameGeneratorFunc* name_func_in,
|
||||||
|
const char* file_in,
|
||||||
|
int line_in)
|
||||||
|
: name(name_in),
|
||||||
|
generator(generator_in),
|
||||||
|
name_func(name_func_in),
|
||||||
|
file(file_in),
|
||||||
|
line(line_in) {}
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
GeneratorCreationFunc* generator;
|
||||||
|
ParamNameGeneratorFunc* name_func;
|
||||||
|
const char* file;
|
||||||
|
int line;
|
||||||
|
};
|
||||||
|
typedef ::std::vector<InstantiationInfo> InstantiationContainer;
|
||||||
|
|
||||||
|
static bool IsValidParamName(const std::string& name) {
|
||||||
|
// Check for empty string
|
||||||
|
if (name.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check for invalid characters
|
||||||
|
for (std::string::size_type index = 0; index < name.size(); ++index) {
|
||||||
|
if (!isalnum(name[index]) && name[index] != '_')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string test_suite_name_;
|
||||||
|
CodeLocation code_location_;
|
||||||
|
TestInfoContainer tests_;
|
||||||
|
InstantiationContainer instantiations_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo);
|
||||||
|
}; // class ParameterizedTestSuiteInfo
|
||||||
|
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
template <class TestCase>
|
||||||
|
using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// ParameterizedTestSuiteRegistry contains a map of
|
||||||
|
// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
|
||||||
|
// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
|
||||||
|
// ParameterizedTestSuiteInfo descriptors.
|
||||||
|
class ParameterizedTestSuiteRegistry {
|
||||||
|
public:
|
||||||
|
ParameterizedTestSuiteRegistry() {}
|
||||||
|
~ParameterizedTestSuiteRegistry() {
|
||||||
|
for (auto& test_suite_info : test_suite_infos_) {
|
||||||
|
delete test_suite_info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Looks up or creates and returns a structure containing information about
|
||||||
|
// tests and instantiations of a particular test suite.
|
||||||
|
template <class TestSuite>
|
||||||
|
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
|
||||||
|
const char* test_suite_name, CodeLocation code_location) {
|
||||||
|
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
|
||||||
|
for (auto& test_suite_info : test_suite_infos_) {
|
||||||
|
if (test_suite_info->GetTestSuiteName() == test_suite_name) {
|
||||||
|
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
||||||
|
// Complain about incorrect usage of Google Test facilities
|
||||||
|
// and terminate the program since we cannot guaranty correct
|
||||||
|
// test suite setup and tear-down in this case.
|
||||||
|
ReportInvalidTestSuiteType(test_suite_name, code_location);
|
||||||
|
posix::Abort();
|
||||||
|
} else {
|
||||||
|
// At this point we are sure that the object we found is of the same
|
||||||
|
// type we are looking for, so we downcast it to that type
|
||||||
|
// without further checks.
|
||||||
|
typed_test_info = CheckedDowncastToActualType<
|
||||||
|
ParameterizedTestSuiteInfo<TestSuite> >(test_suite_info);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typed_test_info == nullptr) {
|
||||||
|
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
|
||||||
|
test_suite_name, code_location);
|
||||||
|
test_suite_infos_.push_back(typed_test_info);
|
||||||
|
}
|
||||||
|
return typed_test_info;
|
||||||
|
}
|
||||||
|
void RegisterTests() {
|
||||||
|
for (auto& test_suite_info : test_suite_infos_) {
|
||||||
|
test_suite_info->RegisterTests();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
template <class TestCase>
|
||||||
|
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
||||||
|
const char* test_case_name, CodeLocation code_location) {
|
||||||
|
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
|
private:
|
||||||
|
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
|
||||||
|
|
||||||
|
TestSuiteInfoContainer test_suite_infos_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Keep track of what type-parameterized test suite are defined and
|
||||||
|
// where as well as which are intatiated. This allows susequently
|
||||||
|
// identifying suits that are defined but never used.
|
||||||
|
class TypeParameterizedTestSuiteRegistry {
|
||||||
|
public:
|
||||||
|
// Add a suite definition
|
||||||
|
void RegisterTestSuite(const char* test_suite_name,
|
||||||
|
CodeLocation code_location);
|
||||||
|
|
||||||
|
// Add an instantiation of a suit.
|
||||||
|
void RegisterInstantiation(const char* test_suite_name);
|
||||||
|
|
||||||
|
// For each suit repored as defined but not reported as instantiation,
|
||||||
|
// emit a test that reports that fact (configurably, as an error).
|
||||||
|
void CheckForInstantiations();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct TypeParameterizedTestSuiteInfo {
|
||||||
|
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
|
||||||
|
: code_location(c), instantiated(false) {}
|
||||||
|
|
||||||
|
CodeLocation code_location;
|
||||||
|
bool instantiated;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<std::string, TypeParameterizedTestSuiteInfo> suites_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Forward declarations of ValuesIn(), which is implemented in
|
||||||
|
// include/gtest/gtest-param-test.h.
|
||||||
|
template <class Container>
|
||||||
|
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||||
|
const Container& container);
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
// Used in the Values() function to provide polymorphic capabilities.
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
class ValueArray {
|
||||||
|
public:
|
||||||
|
ValueArray(Ts... v) : v_{std::move(v)...} {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
operator ParamGenerator<T>() const { // NOLINT
|
||||||
|
return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T, size_t... I>
|
||||||
|
std::vector<T> MakeVector(IndexSequence<I...>) const {
|
||||||
|
return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatTuple<Ts...> v_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
class CartesianProductGenerator
|
||||||
|
: public ParamGeneratorInterface<::std::tuple<T...>> {
|
||||||
|
public:
|
||||||
|
typedef ::std::tuple<T...> ParamType;
|
||||||
|
|
||||||
|
CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
|
||||||
|
: generators_(g) {}
|
||||||
|
~CartesianProductGenerator() override {}
|
||||||
|
|
||||||
|
ParamIteratorInterface<ParamType>* Begin() const override {
|
||||||
|
return new Iterator(this, generators_, false);
|
||||||
|
}
|
||||||
|
ParamIteratorInterface<ParamType>* End() const override {
|
||||||
|
return new Iterator(this, generators_, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class I>
|
||||||
|
class IteratorImpl;
|
||||||
|
template <size_t... I>
|
||||||
|
class IteratorImpl<IndexSequence<I...>>
|
||||||
|
: public ParamIteratorInterface<ParamType> {
|
||||||
|
public:
|
||||||
|
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
|
||||||
|
const std::tuple<ParamGenerator<T>...>& generators, bool is_end)
|
||||||
|
: base_(base),
|
||||||
|
begin_(std::get<I>(generators).begin()...),
|
||||||
|
end_(std::get<I>(generators).end()...),
|
||||||
|
current_(is_end ? end_ : begin_) {
|
||||||
|
ComputeCurrentValue();
|
||||||
|
}
|
||||||
|
~IteratorImpl() override {}
|
||||||
|
|
||||||
|
const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
|
||||||
|
return base_;
|
||||||
|
}
|
||||||
|
// Advance should not be called on beyond-of-range iterators
|
||||||
|
// so no component iterators must be beyond end of range, either.
|
||||||
|
void Advance() override {
|
||||||
|
assert(!AtEnd());
|
||||||
|
// Advance the last iterator.
|
||||||
|
++std::get<sizeof...(T) - 1>(current_);
|
||||||
|
// if that reaches end, propagate that up.
|
||||||
|
AdvanceIfEnd<sizeof...(T) - 1>();
|
||||||
|
ComputeCurrentValue();
|
||||||
|
}
|
||||||
|
ParamIteratorInterface<ParamType>* Clone() const override {
|
||||||
|
return new IteratorImpl(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ParamType* Current() const override { return current_value_.get(); }
|
||||||
|
|
||||||
|
bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
|
||||||
|
// Having the same base generator guarantees that the other
|
||||||
|
// iterator is of the same type and we can downcast.
|
||||||
|
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
||||||
|
<< "The program attempted to compare iterators "
|
||||||
|
<< "from different generators." << std::endl;
|
||||||
|
const IteratorImpl* typed_other =
|
||||||
|
CheckedDowncastToActualType<const IteratorImpl>(&other);
|
||||||
|
|
||||||
|
// We must report iterators equal if they both point beyond their
|
||||||
|
// respective ranges. That can happen in a variety of fashions,
|
||||||
|
// so we have to consult AtEnd().
|
||||||
|
if (AtEnd() && typed_other->AtEnd()) return true;
|
||||||
|
|
||||||
|
bool same = true;
|
||||||
|
bool dummy[] = {
|
||||||
|
(same = same && std::get<I>(current_) ==
|
||||||
|
std::get<I>(typed_other->current_))...};
|
||||||
|
(void)dummy;
|
||||||
|
return same;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <size_t ThisI>
|
||||||
|
void AdvanceIfEnd() {
|
||||||
|
if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
|
||||||
|
|
||||||
|
bool last = ThisI == 0;
|
||||||
|
if (last) {
|
||||||
|
// We are done. Nothing else to propagate.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t NextI = ThisI - (ThisI != 0);
|
||||||
|
std::get<ThisI>(current_) = std::get<ThisI>(begin_);
|
||||||
|
++std::get<NextI>(current_);
|
||||||
|
AdvanceIfEnd<NextI>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeCurrentValue() {
|
||||||
|
if (!AtEnd())
|
||||||
|
current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
|
||||||
|
}
|
||||||
|
bool AtEnd() const {
|
||||||
|
bool at_end = false;
|
||||||
|
bool dummy[] = {
|
||||||
|
(at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
|
||||||
|
(void)dummy;
|
||||||
|
return at_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ParamGeneratorInterface<ParamType>* const base_;
|
||||||
|
std::tuple<typename ParamGenerator<T>::iterator...> begin_;
|
||||||
|
std::tuple<typename ParamGenerator<T>::iterator...> end_;
|
||||||
|
std::tuple<typename ParamGenerator<T>::iterator...> current_;
|
||||||
|
std::shared_ptr<ParamType> current_value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
|
||||||
|
|
||||||
|
std::tuple<ParamGenerator<T>...> generators_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class... Gen>
|
||||||
|
class CartesianProductHolder {
|
||||||
|
public:
|
||||||
|
CartesianProductHolder(const Gen&... g) : generators_(g...) {}
|
||||||
|
template <typename... T>
|
||||||
|
operator ParamGenerator<::std::tuple<T...>>() const {
|
||||||
|
return ParamGenerator<::std::tuple<T...>>(
|
||||||
|
new CartesianProductGenerator<T...>(generators_));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::tuple<Gen...> generators_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
|
@ -0,0 +1,111 @@
|
||||||
|
// Copyright 2015, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// This header file defines the GTEST_OS_* macro.
|
||||||
|
// It is separate from gtest-port.h so that custom/gtest-port.h can include it.
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||||
|
|
||||||
|
// Determines the platform on which Google Test is compiled.
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
# define GTEST_OS_CYGWIN 1
|
||||||
|
# elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||||
|
# define GTEST_OS_WINDOWS_MINGW 1
|
||||||
|
# define GTEST_OS_WINDOWS 1
|
||||||
|
#elif defined _WIN32
|
||||||
|
# define GTEST_OS_WINDOWS 1
|
||||||
|
# ifdef _WIN32_WCE
|
||||||
|
# define GTEST_OS_WINDOWS_MOBILE 1
|
||||||
|
# elif defined(WINAPI_FAMILY)
|
||||||
|
# include <winapifamily.h>
|
||||||
|
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
# define GTEST_OS_WINDOWS_DESKTOP 1
|
||||||
|
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
|
||||||
|
# define GTEST_OS_WINDOWS_PHONE 1
|
||||||
|
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
|
# define GTEST_OS_WINDOWS_RT 1
|
||||||
|
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
|
||||||
|
# define GTEST_OS_WINDOWS_PHONE 1
|
||||||
|
# define GTEST_OS_WINDOWS_TV_TITLE 1
|
||||||
|
# else
|
||||||
|
// WINAPI_FAMILY defined but no known partition matched.
|
||||||
|
// Default to desktop.
|
||||||
|
# define GTEST_OS_WINDOWS_DESKTOP 1
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define GTEST_OS_WINDOWS_DESKTOP 1
|
||||||
|
# endif // _WIN32_WCE
|
||||||
|
#elif defined __OS2__
|
||||||
|
# define GTEST_OS_OS2 1
|
||||||
|
#elif defined __APPLE__
|
||||||
|
# define GTEST_OS_MAC 1
|
||||||
|
# if TARGET_OS_IPHONE
|
||||||
|
# define GTEST_OS_IOS 1
|
||||||
|
# endif
|
||||||
|
#elif defined __DragonFly__
|
||||||
|
# define GTEST_OS_DRAGONFLY 1
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
# define GTEST_OS_FREEBSD 1
|
||||||
|
#elif defined __Fuchsia__
|
||||||
|
# define GTEST_OS_FUCHSIA 1
|
||||||
|
#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
|
||||||
|
# define GTEST_OS_GNU_KFREEBSD 1
|
||||||
|
#elif defined __linux__
|
||||||
|
# define GTEST_OS_LINUX 1
|
||||||
|
# if defined __ANDROID__
|
||||||
|
# define GTEST_OS_LINUX_ANDROID 1
|
||||||
|
# endif
|
||||||
|
#elif defined __MVS__
|
||||||
|
# define GTEST_OS_ZOS 1
|
||||||
|
#elif defined(__sun) && defined(__SVR4)
|
||||||
|
# define GTEST_OS_SOLARIS 1
|
||||||
|
#elif defined(_AIX)
|
||||||
|
# define GTEST_OS_AIX 1
|
||||||
|
#elif defined(__hpux)
|
||||||
|
# define GTEST_OS_HPUX 1
|
||||||
|
#elif defined __native_client__
|
||||||
|
# define GTEST_OS_NACL 1
|
||||||
|
#elif defined __NetBSD__
|
||||||
|
# define GTEST_OS_NETBSD 1
|
||||||
|
#elif defined __OpenBSD__
|
||||||
|
# define GTEST_OS_OPENBSD 1
|
||||||
|
#elif defined __QNX__
|
||||||
|
# define GTEST_OS_QNX 1
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
#define GTEST_OS_HAIKU 1
|
||||||
|
#elif defined ESP8266
|
||||||
|
#define GTEST_OS_ESP8266 1
|
||||||
|
#elif defined ESP32
|
||||||
|
#define GTEST_OS_ESP32 1
|
||||||
|
#endif // __CYGWIN__
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,172 @@
|
||||||
|
// Copyright 2005, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// This header file declares the String class and functions used internally by
|
||||||
|
// Google Test. They are subject to change without notice. They should not used
|
||||||
|
// by code external to Google Test.
|
||||||
|
//
|
||||||
|
// This header file is #included by gtest-internal.h.
|
||||||
|
// It should not be #included by other files.
|
||||||
|
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
// string.h is not guaranteed to provide strcpy on C++ Builder.
|
||||||
|
# include <mem.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// String - an abstract class holding static string utilities.
|
||||||
|
class GTEST_API_ String {
|
||||||
|
public:
|
||||||
|
// Static utility methods
|
||||||
|
|
||||||
|
// Clones a 0-terminated C string, allocating memory using new. The
|
||||||
|
// caller is responsible for deleting the return value using
|
||||||
|
// delete[]. Returns the cloned string, or NULL if the input is
|
||||||
|
// NULL.
|
||||||
|
//
|
||||||
|
// This is different from strdup() in string.h, which allocates
|
||||||
|
// memory using malloc().
|
||||||
|
static const char* CloneCString(const char* c_str);
|
||||||
|
|
||||||
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
|
||||||
|
// able to pass strings to Win32 APIs on CE we need to convert them
|
||||||
|
// to 'Unicode', UTF-16.
|
||||||
|
|
||||||
|
// Creates a UTF-16 wide string from the given ANSI string, allocating
|
||||||
|
// memory using new. The caller is responsible for deleting the return
|
||||||
|
// value using delete[]. Returns the wide string, or NULL if the
|
||||||
|
// input is NULL.
|
||||||
|
//
|
||||||
|
// The wide string is created using the ANSI codepage (CP_ACP) to
|
||||||
|
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||||
|
// C runtime.
|
||||||
|
static LPCWSTR AnsiToUtf16(const char* c_str);
|
||||||
|
|
||||||
|
// Creates an ANSI string from the given wide string, allocating
|
||||||
|
// memory using new. The caller is responsible for deleting the return
|
||||||
|
// value using delete[]. Returns the ANSI string, or NULL if the
|
||||||
|
// input is NULL.
|
||||||
|
//
|
||||||
|
// The returned string is created using the ANSI codepage (CP_ACP) to
|
||||||
|
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||||
|
// C runtime.
|
||||||
|
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Compares two C strings. Returns true if and only if they have the same
|
||||||
|
// content.
|
||||||
|
//
|
||||||
|
// Unlike strcmp(), this function can handle NULL argument(s). A
|
||||||
|
// NULL C string is considered different to any non-NULL C string,
|
||||||
|
// including the empty string.
|
||||||
|
static bool CStringEquals(const char* lhs, const char* rhs);
|
||||||
|
|
||||||
|
// Converts a wide C string to a String using the UTF-8 encoding.
|
||||||
|
// NULL will be converted to "(null)". If an error occurred during
|
||||||
|
// the conversion, "(failed to convert from wide string)" is
|
||||||
|
// returned.
|
||||||
|
static std::string ShowWideCString(const wchar_t* wide_c_str);
|
||||||
|
|
||||||
|
// Compares two wide C strings. Returns true if and only if they have the
|
||||||
|
// same content.
|
||||||
|
//
|
||||||
|
// Unlike wcscmp(), this function can handle NULL argument(s). A
|
||||||
|
// NULL C string is considered different to any non-NULL C string,
|
||||||
|
// including the empty string.
|
||||||
|
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
|
||||||
|
|
||||||
|
// Compares two C strings, ignoring case. Returns true if and only if
|
||||||
|
// they have the same content.
|
||||||
|
//
|
||||||
|
// Unlike strcasecmp(), this function can handle NULL argument(s).
|
||||||
|
// A NULL C string is considered different to any non-NULL C string,
|
||||||
|
// including the empty string.
|
||||||
|
static bool CaseInsensitiveCStringEquals(const char* lhs,
|
||||||
|
const char* rhs);
|
||||||
|
|
||||||
|
// Compares two wide C strings, ignoring case. Returns true if and only if
|
||||||
|
// they have the same content.
|
||||||
|
//
|
||||||
|
// Unlike wcscasecmp(), this function can handle NULL argument(s).
|
||||||
|
// A NULL C string is considered different to any non-NULL wide C string,
|
||||||
|
// including the empty string.
|
||||||
|
// NB: The implementations on different platforms slightly differ.
|
||||||
|
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
|
||||||
|
// environment variable. On GNU platform this method uses wcscasecmp
|
||||||
|
// which compares according to LC_CTYPE category of the current locale.
|
||||||
|
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
|
||||||
|
// current locale.
|
||||||
|
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
|
||||||
|
const wchar_t* rhs);
|
||||||
|
|
||||||
|
// Returns true if and only if the given string ends with the given suffix,
|
||||||
|
// ignoring case. Any string is considered to end with an empty suffix.
|
||||||
|
static bool EndsWithCaseInsensitive(
|
||||||
|
const std::string& str, const std::string& suffix);
|
||||||
|
|
||||||
|
// Formats an int value as "%02d".
|
||||||
|
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
|
||||||
|
|
||||||
|
// Formats an int value as "%X".
|
||||||
|
static std::string FormatHexInt(int value);
|
||||||
|
|
||||||
|
// Formats an int value as "%X".
|
||||||
|
static std::string FormatHexUInt32(uint32_t value);
|
||||||
|
|
||||||
|
// Formats a byte as "%02X".
|
||||||
|
static std::string FormatByte(unsigned char value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
String(); // Not meant to be instantiated.
|
||||||
|
}; // class String
|
||||||
|
|
||||||
|
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
|
||||||
|
// character in the buffer is replaced with "\\0".
|
||||||
|
GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
|
@ -0,0 +1,183 @@
|
||||||
|
// Copyright 2008 Google Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Type utilities needed for implementing typed and type-parameterized
|
||||||
|
// tests.
|
||||||
|
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
|
||||||
|
// libstdc++ (which is where cxxabi.h comes from).
|
||||||
|
# if GTEST_HAS_CXXABI_H_
|
||||||
|
# include <cxxabi.h>
|
||||||
|
# elif defined(__HP_aCC)
|
||||||
|
# include <acxx_demangle.h>
|
||||||
|
# endif // GTEST_HASH_CXXABI_H_
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Canonicalizes a given name with respect to the Standard C++ Library.
|
||||||
|
// This handles removing the inline namespace within `std` that is
|
||||||
|
// used by various standard libraries (e.g., `std::__1`). Names outside
|
||||||
|
// of namespace std are returned unmodified.
|
||||||
|
inline std::string CanonicalizeForStdLibVersioning(std::string s) {
|
||||||
|
static const char prefix[] = "std::__";
|
||||||
|
if (s.compare(0, strlen(prefix), prefix) == 0) {
|
||||||
|
std::string::size_type end = s.find("::", strlen(prefix));
|
||||||
|
if (end != s.npos) {
|
||||||
|
// Erase everything between the initial `std` and the second `::`.
|
||||||
|
s.erase(strlen("std"), end - strlen("std"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTypeName<T>() returns a human-readable name of type T.
|
||||||
|
// NB: This function is also used in Google Mock, so don't move it inside of
|
||||||
|
// the typed-test-only section below.
|
||||||
|
template <typename T>
|
||||||
|
std::string GetTypeName() {
|
||||||
|
# if GTEST_HAS_RTTI
|
||||||
|
|
||||||
|
const char* const name = typeid(T).name();
|
||||||
|
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
|
||||||
|
int status = 0;
|
||||||
|
// gcc's implementation of typeid(T).name() mangles the type name,
|
||||||
|
// so we have to demangle it.
|
||||||
|
# if GTEST_HAS_CXXABI_H_
|
||||||
|
using abi::__cxa_demangle;
|
||||||
|
# endif // GTEST_HAS_CXXABI_H_
|
||||||
|
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
|
||||||
|
const std::string name_str(status == 0 ? readable_name : name);
|
||||||
|
free(readable_name);
|
||||||
|
return CanonicalizeForStdLibVersioning(name_str);
|
||||||
|
# else
|
||||||
|
return name;
|
||||||
|
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
return "<type>";
|
||||||
|
|
||||||
|
# endif // GTEST_HAS_RTTI
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
|
// A unique type indicating an empty node
|
||||||
|
struct None {};
|
||||||
|
|
||||||
|
# define GTEST_TEMPLATE_ template <typename T> class
|
||||||
|
|
||||||
|
// The template "selector" struct TemplateSel<Tmpl> is used to
|
||||||
|
// represent Tmpl, which must be a class template with one type
|
||||||
|
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined
|
||||||
|
// as the type Tmpl<T>. This allows us to actually instantiate the
|
||||||
|
// template "selected" by TemplateSel<Tmpl>.
|
||||||
|
//
|
||||||
|
// This trick is necessary for simulating typedef for class templates,
|
||||||
|
// which C++ doesn't support directly.
|
||||||
|
template <GTEST_TEMPLATE_ Tmpl>
|
||||||
|
struct TemplateSel {
|
||||||
|
template <typename T>
|
||||||
|
struct Bind {
|
||||||
|
typedef Tmpl<T> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# define GTEST_BIND_(TmplSel, T) \
|
||||||
|
TmplSel::template Bind<T>::type
|
||||||
|
|
||||||
|
template <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_>
|
||||||
|
struct Templates {
|
||||||
|
using Head = TemplateSel<Head_>;
|
||||||
|
using Tail = Templates<Tail_...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <GTEST_TEMPLATE_ Head_>
|
||||||
|
struct Templates<Head_> {
|
||||||
|
using Head = TemplateSel<Head_>;
|
||||||
|
using Tail = None;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tuple-like type lists
|
||||||
|
template <typename Head_, typename... Tail_>
|
||||||
|
struct Types {
|
||||||
|
using Head = Head_;
|
||||||
|
using Tail = Types<Tail_...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Head_>
|
||||||
|
struct Types<Head_> {
|
||||||
|
using Head = Head_;
|
||||||
|
using Tail = None;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper metafunctions to tell apart a single type from types
|
||||||
|
// generated by ::testing::Types
|
||||||
|
template <typename... Ts>
|
||||||
|
struct ProxyTypeList {
|
||||||
|
using type = Types<Ts...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
struct is_proxy_type_list : std::false_type {};
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
struct is_proxy_type_list<ProxyTypeList<Ts...>> : std::true_type {};
|
||||||
|
|
||||||
|
// Generator which conditionally creates type lists.
|
||||||
|
// It recognizes if a requested type list should be created
|
||||||
|
// and prevents creating a new type list nested within another one.
|
||||||
|
template <typename T>
|
||||||
|
struct GenerateTypeList {
|
||||||
|
private:
|
||||||
|
using proxy = typename std::conditional<is_proxy_type_list<T>::value, T,
|
||||||
|
ProxyTypeList<T>>::type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using type = typename proxy::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
using Types = internal::ProxyTypeList<Ts...>;
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// Sometimes it's desirable to build Google Test by compiling a single file.
|
||||||
|
// This file serves this purpose.
|
||||||
|
|
||||||
|
// This line ensures that gtest.h can be compiled on its own, even
|
||||||
|
// when it's fused.
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
// The following lines pull in the real gtest *.cc files.
|
||||||
|
#include "src/gtest.cc"
|
||||||
|
#include "src/gtest-death-test.cc"
|
||||||
|
#include "src/gtest-filepath.cc"
|
||||||
|
#include "src/gtest-matchers.cc"
|
||||||
|
#include "src/gtest-port.cc"
|
||||||
|
#include "src/gtest-printers.cc"
|
||||||
|
#include "src/gtest-test-part.cc"
|
||||||
|
#include "src/gtest-typed-test.cc"
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,382 @@
|
||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-filepath.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
#include "gtest/gtest-message.h"
|
||||||
|
|
||||||
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
# include <windows.h>
|
||||||
|
#elif GTEST_OS_WINDOWS
|
||||||
|
# include <direct.h>
|
||||||
|
# include <io.h>
|
||||||
|
#else
|
||||||
|
# include <limits.h>
|
||||||
|
# include <climits> // Some Linux distributions define PATH_MAX here.
|
||||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-string.h"
|
||||||
|
|
||||||
|
#if GTEST_OS_WINDOWS
|
||||||
|
# define GTEST_PATH_MAX_ _MAX_PATH
|
||||||
|
#elif defined(PATH_MAX)
|
||||||
|
# define GTEST_PATH_MAX_ PATH_MAX
|
||||||
|
#elif defined(_XOPEN_PATH_MAX)
|
||||||
|
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
|
||||||
|
#else
|
||||||
|
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
|
||||||
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
#if GTEST_OS_WINDOWS
|
||||||
|
// On Windows, '\\' is the standard path separator, but many tools and the
|
||||||
|
// Windows API also accept '/' as an alternate path separator. Unless otherwise
|
||||||
|
// noted, a file path can contain either kind of path separators, or a mixture
|
||||||
|
// of them.
|
||||||
|
const char kPathSeparator = '\\';
|
||||||
|
const char kAlternatePathSeparator = '/';
|
||||||
|
const char kAlternatePathSeparatorString[] = "/";
|
||||||
|
# if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
// Windows CE doesn't have a current directory. You should not use
|
||||||
|
// the current directory in tests on Windows CE, but this at least
|
||||||
|
// provides a reasonable fallback.
|
||||||
|
const char kCurrentDirectoryString[] = "\\";
|
||||||
|
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
|
||||||
|
const DWORD kInvalidFileAttributes = 0xffffffff;
|
||||||
|
# else
|
||||||
|
const char kCurrentDirectoryString[] = ".\\";
|
||||||
|
# endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
#else
|
||||||
|
const char kPathSeparator = '/';
|
||||||
|
const char kCurrentDirectoryString[] = "./";
|
||||||
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
|
// Returns whether the given character is a valid path separator.
|
||||||
|
static bool IsPathSeparator(char c) {
|
||||||
|
#if GTEST_HAS_ALT_PATH_SEP_
|
||||||
|
return (c == kPathSeparator) || (c == kAlternatePathSeparator);
|
||||||
|
#else
|
||||||
|
return c == kPathSeparator;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the current working directory, or "" if unsuccessful.
|
||||||
|
FilePath FilePath::GetCurrentDir() {
|
||||||
|
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
|
||||||
|
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32
|
||||||
|
// These platforms do not have a current directory, so we just return
|
||||||
|
// something reasonable.
|
||||||
|
return FilePath(kCurrentDirectoryString);
|
||||||
|
#elif GTEST_OS_WINDOWS
|
||||||
|
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
|
||||||
|
return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd);
|
||||||
|
#else
|
||||||
|
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
|
||||||
|
char* result = getcwd(cwd, sizeof(cwd));
|
||||||
|
# if GTEST_OS_NACL
|
||||||
|
// getcwd will likely fail in NaCl due to the sandbox, so return something
|
||||||
|
// reasonable. The user may have provided a shim implementation for getcwd,
|
||||||
|
// however, so fallback only when failure is detected.
|
||||||
|
return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);
|
||||||
|
# endif // GTEST_OS_NACL
|
||||||
|
return FilePath(result == nullptr ? "" : cwd);
|
||||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||||
|
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
||||||
|
// FilePath("dir/file"). If a case-insensitive extension is not
|
||||||
|
// found, returns a copy of the original FilePath.
|
||||||
|
FilePath FilePath::RemoveExtension(const char* extension) const {
|
||||||
|
const std::string dot_extension = std::string(".") + extension;
|
||||||
|
if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
|
||||||
|
return FilePath(pathname_.substr(
|
||||||
|
0, pathname_.length() - dot_extension.length()));
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a pointer to the last occurrence of a valid path separator in
|
||||||
|
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||||
|
// separators. Returns NULL if no path separator was found.
|
||||||
|
const char* FilePath::FindLastPathSeparator() const {
|
||||||
|
const char* const last_sep = strrchr(c_str(), kPathSeparator);
|
||||||
|
#if GTEST_HAS_ALT_PATH_SEP_
|
||||||
|
const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
|
||||||
|
// Comparing two pointers of which only one is NULL is undefined.
|
||||||
|
if (last_alt_sep != nullptr &&
|
||||||
|
(last_sep == nullptr || last_alt_sep > last_sep)) {
|
||||||
|
return last_alt_sep;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return last_sep;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a copy of the FilePath with the directory part removed.
|
||||||
|
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||||
|
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||||
|
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
||||||
|
// returns an empty FilePath ("").
|
||||||
|
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||||
|
FilePath FilePath::RemoveDirectoryName() const {
|
||||||
|
const char* const last_sep = FindLastPathSeparator();
|
||||||
|
return last_sep ? FilePath(last_sep + 1) : *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveFileName returns the directory path with the filename removed.
|
||||||
|
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
||||||
|
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
||||||
|
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
||||||
|
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
||||||
|
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||||
|
FilePath FilePath::RemoveFileName() const {
|
||||||
|
const char* const last_sep = FindLastPathSeparator();
|
||||||
|
std::string dir;
|
||||||
|
if (last_sep) {
|
||||||
|
dir = std::string(c_str(), static_cast<size_t>(last_sep + 1 - c_str()));
|
||||||
|
} else {
|
||||||
|
dir = kCurrentDirectoryString;
|
||||||
|
}
|
||||||
|
return FilePath(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper functions for naming files in a directory for xml output.
|
||||||
|
|
||||||
|
// Given directory = "dir", base_name = "test", number = 0,
|
||||||
|
// extension = "xml", returns "dir/test.xml". If number is greater
|
||||||
|
// than zero (e.g., 12), returns "dir/test_12.xml".
|
||||||
|
// On Windows platform, uses \ as the separator rather than /.
|
||||||
|
FilePath FilePath::MakeFileName(const FilePath& directory,
|
||||||
|
const FilePath& base_name,
|
||||||
|
int number,
|
||||||
|
const char* extension) {
|
||||||
|
std::string file;
|
||||||
|
if (number == 0) {
|
||||||
|
file = base_name.string() + "." + extension;
|
||||||
|
} else {
|
||||||
|
file = base_name.string() + "_" + StreamableToString(number)
|
||||||
|
+ "." + extension;
|
||||||
|
}
|
||||||
|
return ConcatPaths(directory, FilePath(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
|
||||||
|
// On Windows, uses \ as the separator rather than /.
|
||||||
|
FilePath FilePath::ConcatPaths(const FilePath& directory,
|
||||||
|
const FilePath& relative_path) {
|
||||||
|
if (directory.IsEmpty())
|
||||||
|
return relative_path;
|
||||||
|
const FilePath dir(directory.RemoveTrailingPathSeparator());
|
||||||
|
return FilePath(dir.string() + kPathSeparator + relative_path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if pathname describes something findable in the file-system,
|
||||||
|
// either a file, directory, or whatever.
|
||||||
|
bool FilePath::FileOrDirectoryExists() const {
|
||||||
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
|
||||||
|
const DWORD attributes = GetFileAttributes(unicode);
|
||||||
|
delete [] unicode;
|
||||||
|
return attributes != kInvalidFileAttributes;
|
||||||
|
#else
|
||||||
|
posix::StatStruct file_stat;
|
||||||
|
return posix::Stat(pathname_.c_str(), &file_stat) == 0;
|
||||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if pathname describes a directory in the file-system
|
||||||
|
// that exists.
|
||||||
|
bool FilePath::DirectoryExists() const {
|
||||||
|
bool result = false;
|
||||||
|
#if GTEST_OS_WINDOWS
|
||||||
|
// Don't strip off trailing separator if path is a root directory on
|
||||||
|
// Windows (like "C:\\").
|
||||||
|
const FilePath& path(IsRootDirectory() ? *this :
|
||||||
|
RemoveTrailingPathSeparator());
|
||||||
|
#else
|
||||||
|
const FilePath& path(*this);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
|
||||||
|
const DWORD attributes = GetFileAttributes(unicode);
|
||||||
|
delete [] unicode;
|
||||||
|
if ((attributes != kInvalidFileAttributes) &&
|
||||||
|
(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
posix::StatStruct file_stat;
|
||||||
|
result = posix::Stat(path.c_str(), &file_stat) == 0 &&
|
||||||
|
posix::IsDir(file_stat);
|
||||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if pathname describes a root directory. (Windows has one
|
||||||
|
// root directory per disk drive.)
|
||||||
|
bool FilePath::IsRootDirectory() const {
|
||||||
|
#if GTEST_OS_WINDOWS
|
||||||
|
return pathname_.length() == 3 && IsAbsolutePath();
|
||||||
|
#else
|
||||||
|
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if pathname describes an absolute path.
|
||||||
|
bool FilePath::IsAbsolutePath() const {
|
||||||
|
const char* const name = pathname_.c_str();
|
||||||
|
#if GTEST_OS_WINDOWS
|
||||||
|
return pathname_.length() >= 3 &&
|
||||||
|
((name[0] >= 'a' && name[0] <= 'z') ||
|
||||||
|
(name[0] >= 'A' && name[0] <= 'Z')) &&
|
||||||
|
name[1] == ':' &&
|
||||||
|
IsPathSeparator(name[2]);
|
||||||
|
#else
|
||||||
|
return IsPathSeparator(name[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a pathname for a file that does not currently exist. The pathname
|
||||||
|
// will be directory/base_name.extension or
|
||||||
|
// directory/base_name_<number>.extension if directory/base_name.extension
|
||||||
|
// already exists. The number will be incremented until a pathname is found
|
||||||
|
// that does not already exist.
|
||||||
|
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
||||||
|
// There could be a race condition if two or more processes are calling this
|
||||||
|
// function at the same time -- they could both pick the same filename.
|
||||||
|
FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
|
||||||
|
const FilePath& base_name,
|
||||||
|
const char* extension) {
|
||||||
|
FilePath full_pathname;
|
||||||
|
int number = 0;
|
||||||
|
do {
|
||||||
|
full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
|
||||||
|
} while (full_pathname.FileOrDirectoryExists());
|
||||||
|
return full_pathname;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if FilePath ends with a path separator, which indicates that
|
||||||
|
// it is intended to represent a directory. Returns false otherwise.
|
||||||
|
// This does NOT check that a directory (or file) actually exists.
|
||||||
|
bool FilePath::IsDirectory() const {
|
||||||
|
return !pathname_.empty() &&
|
||||||
|
IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create directories so that path exists. Returns true if successful or if
|
||||||
|
// the directories already exist; returns false if unable to create directories
|
||||||
|
// for any reason.
|
||||||
|
bool FilePath::CreateDirectoriesRecursively() const {
|
||||||
|
if (!this->IsDirectory()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathname_.length() == 0 || this->DirectoryExists()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
|
||||||
|
return parent.CreateDirectoriesRecursively() && this->CreateFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the directory so that path exists. Returns true if successful or
|
||||||
|
// if the directory already exists; returns false if unable to create the
|
||||||
|
// directory for any reason, including if the parent directory does not
|
||||||
|
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||||
|
bool FilePath::CreateFolder() const {
|
||||||
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
FilePath removed_sep(this->RemoveTrailingPathSeparator());
|
||||||
|
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
|
||||||
|
int result = CreateDirectory(unicode, nullptr) ? 0 : -1;
|
||||||
|
delete [] unicode;
|
||||||
|
#elif GTEST_OS_WINDOWS
|
||||||
|
int result = _mkdir(pathname_.c_str());
|
||||||
|
#elif GTEST_OS_ESP8266
|
||||||
|
// do nothing
|
||||||
|
int result = 0;
|
||||||
|
#else
|
||||||
|
int result = mkdir(pathname_.c_str(), 0777);
|
||||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
|
if (result == -1) {
|
||||||
|
return this->DirectoryExists(); // An error is OK if the directory exists.
|
||||||
|
}
|
||||||
|
return true; // No error.
|
||||||
|
}
|
||||||
|
|
||||||
|
// If input name has a trailing separator character, remove it and return the
|
||||||
|
// name, otherwise return the name string unmodified.
|
||||||
|
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||||
|
FilePath FilePath::RemoveTrailingPathSeparator() const {
|
||||||
|
return IsDirectory()
|
||||||
|
? FilePath(pathname_.substr(0, pathname_.length() - 1))
|
||||||
|
: *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes any redundant separators that might be in the pathname.
|
||||||
|
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||||
|
// redundancies that might be in a pathname involving "." or "..".
|
||||||
|
void FilePath::Normalize() {
|
||||||
|
if (pathname_.c_str() == nullptr) {
|
||||||
|
pathname_ = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const char* src = pathname_.c_str();
|
||||||
|
char* const dest = new char[pathname_.length() + 1];
|
||||||
|
char* dest_ptr = dest;
|
||||||
|
memset(dest_ptr, 0, pathname_.length() + 1);
|
||||||
|
|
||||||
|
while (*src != '\0') {
|
||||||
|
*dest_ptr = *src;
|
||||||
|
if (!IsPathSeparator(*src)) {
|
||||||
|
src++;
|
||||||
|
} else {
|
||||||
|
#if GTEST_HAS_ALT_PATH_SEP_
|
||||||
|
if (*dest_ptr == kAlternatePathSeparator) {
|
||||||
|
*dest_ptr = kPathSeparator;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (IsPathSeparator(*src))
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
dest_ptr++;
|
||||||
|
}
|
||||||
|
*dest_ptr = '\0';
|
||||||
|
pathname_ = dest;
|
||||||
|
delete[] dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,97 @@
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// This file implements just enough of the matcher interface to allow
|
||||||
|
// EXPECT_DEATH and friends to accept a matcher argument.
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
#include "gtest/gtest-matchers.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a const std::string& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); }
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a const std::string& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const std::string&>::Matcher(const char* s) {
|
||||||
|
*this = Eq(std::string(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a std::string whose value is equal to
|
||||||
|
// s.
|
||||||
|
Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a std::string whose value is equal to
|
||||||
|
// s.
|
||||||
|
Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
// Constructs a matcher that matches a const StringView& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const internal::StringView&>::Matcher(const std::string& s) {
|
||||||
|
*this = Eq(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a const StringView& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const internal::StringView&>::Matcher(const char* s) {
|
||||||
|
*this = Eq(std::string(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a const StringView& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const internal::StringView&>::Matcher(internal::StringView s) {
|
||||||
|
*this = Eq(std::string(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a StringView whose value is equal to
|
||||||
|
// s.
|
||||||
|
Matcher<internal::StringView>::Matcher(const std::string& s) { *this = Eq(s); }
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a StringView whose value is equal to
|
||||||
|
// s.
|
||||||
|
Matcher<internal::StringView>::Matcher(const char* s) {
|
||||||
|
*this = Eq(std::string(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a StringView whose value is equal to
|
||||||
|
// s.
|
||||||
|
Matcher<internal::StringView>::Matcher(internal::StringView s) {
|
||||||
|
*this = Eq(std::string(s));
|
||||||
|
}
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
|
||||||
|
} // namespace testing
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,438 @@
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
// Google Test - The Google C++ Testing and Mocking Framework
|
||||||
|
//
|
||||||
|
// This file implements a universal value printer that can print a
|
||||||
|
// value of any type T:
|
||||||
|
//
|
||||||
|
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||||
|
//
|
||||||
|
// It uses the << operator when possible, and prints the bytes in the
|
||||||
|
// object otherwise. A user can override its behavior for a class
|
||||||
|
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
|
||||||
|
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
|
||||||
|
// defines Foo.
|
||||||
|
|
||||||
|
#include "gtest/gtest-printers.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <cctype>
|
||||||
|
#include <cwchar>
|
||||||
|
#include <ostream> // NOLINT
|
||||||
|
#include <string>
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
#include "src/gtest-internal-inl.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ::std::ostream;
|
||||||
|
|
||||||
|
// Prints a segment of bytes in the given object.
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
||||||
|
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
||||||
|
size_t count, ostream* os) {
|
||||||
|
char text[5] = "";
|
||||||
|
for (size_t i = 0; i != count; i++) {
|
||||||
|
const size_t j = start + i;
|
||||||
|
if (i != 0) {
|
||||||
|
// Organizes the bytes into groups of 2 for easy parsing by
|
||||||
|
// human.
|
||||||
|
if ((j % 2) == 0)
|
||||||
|
*os << ' ';
|
||||||
|
else
|
||||||
|
*os << '-';
|
||||||
|
}
|
||||||
|
GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
|
||||||
|
*os << text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints the bytes in the given value to the given ostream.
|
||||||
|
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
|
||||||
|
ostream* os) {
|
||||||
|
// Tells the user how big the object is.
|
||||||
|
*os << count << "-byte object <";
|
||||||
|
|
||||||
|
const size_t kThreshold = 132;
|
||||||
|
const size_t kChunkSize = 64;
|
||||||
|
// If the object size is bigger than kThreshold, we'll have to omit
|
||||||
|
// some details by printing only the first and the last kChunkSize
|
||||||
|
// bytes.
|
||||||
|
if (count < kThreshold) {
|
||||||
|
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
|
||||||
|
} else {
|
||||||
|
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
|
||||||
|
*os << " ... ";
|
||||||
|
// Rounds up to 2-byte boundary.
|
||||||
|
const size_t resume_pos = (count - kChunkSize + 1)/2*2;
|
||||||
|
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
|
||||||
|
}
|
||||||
|
*os << ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
|
||||||
|
// given object. The delegation simplifies the implementation, which
|
||||||
|
// uses the << operator and thus is easier done outside of the
|
||||||
|
// ::testing::internal namespace, which contains a << operator that
|
||||||
|
// sometimes conflicts with the one in STL.
|
||||||
|
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
|
||||||
|
ostream* os) {
|
||||||
|
PrintBytesInObjectToImpl(obj_bytes, count, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Depending on the value of a char (or wchar_t), we print it in one
|
||||||
|
// of three formats:
|
||||||
|
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
|
||||||
|
// - as a hexadecimal escape sequence (e.g. '\x7F'), or
|
||||||
|
// - as a special escape sequence (e.g. '\r', '\n').
|
||||||
|
enum CharFormat {
|
||||||
|
kAsIs,
|
||||||
|
kHexEscape,
|
||||||
|
kSpecialEscape
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns true if c is a printable ASCII character. We test the
|
||||||
|
// value of c directly instead of calling isprint(), which is buggy on
|
||||||
|
// Windows Mobile.
|
||||||
|
inline bool IsPrintableAscii(wchar_t c) {
|
||||||
|
return 0x20 <= c && c <= 0x7E;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a wide or narrow char c as a character literal without the
|
||||||
|
// quotes, escaping it when necessary; returns how c was formatted.
|
||||||
|
// The template argument UnsignedChar is the unsigned version of Char,
|
||||||
|
// which is the type of c.
|
||||||
|
template <typename UnsignedChar, typename Char>
|
||||||
|
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
|
||||||
|
wchar_t w_c = static_cast<wchar_t>(c);
|
||||||
|
switch (w_c) {
|
||||||
|
case L'\0':
|
||||||
|
*os << "\\0";
|
||||||
|
break;
|
||||||
|
case L'\'':
|
||||||
|
*os << "\\'";
|
||||||
|
break;
|
||||||
|
case L'\\':
|
||||||
|
*os << "\\\\";
|
||||||
|
break;
|
||||||
|
case L'\a':
|
||||||
|
*os << "\\a";
|
||||||
|
break;
|
||||||
|
case L'\b':
|
||||||
|
*os << "\\b";
|
||||||
|
break;
|
||||||
|
case L'\f':
|
||||||
|
*os << "\\f";
|
||||||
|
break;
|
||||||
|
case L'\n':
|
||||||
|
*os << "\\n";
|
||||||
|
break;
|
||||||
|
case L'\r':
|
||||||
|
*os << "\\r";
|
||||||
|
break;
|
||||||
|
case L'\t':
|
||||||
|
*os << "\\t";
|
||||||
|
break;
|
||||||
|
case L'\v':
|
||||||
|
*os << "\\v";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (IsPrintableAscii(w_c)) {
|
||||||
|
*os << static_cast<char>(c);
|
||||||
|
return kAsIs;
|
||||||
|
} else {
|
||||||
|
ostream::fmtflags flags = os->flags();
|
||||||
|
*os << "\\x" << std::hex << std::uppercase
|
||||||
|
<< static_cast<int>(static_cast<UnsignedChar>(c));
|
||||||
|
os->flags(flags);
|
||||||
|
return kHexEscape;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kSpecialEscape;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a wchar_t c as if it's part of a string literal, escaping it when
|
||||||
|
// necessary; returns how c was formatted.
|
||||||
|
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
|
||||||
|
switch (c) {
|
||||||
|
case L'\'':
|
||||||
|
*os << "'";
|
||||||
|
return kAsIs;
|
||||||
|
case L'"':
|
||||||
|
*os << "\\\"";
|
||||||
|
return kSpecialEscape;
|
||||||
|
default:
|
||||||
|
return PrintAsCharLiteralTo<wchar_t>(c, os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a char c as if it's part of a string literal, escaping it when
|
||||||
|
// necessary; returns how c was formatted.
|
||||||
|
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
|
||||||
|
return PrintAsStringLiteralTo(
|
||||||
|
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a wide or narrow character c and its code. '\0' is printed
|
||||||
|
// as "'\\0'", other unprintable characters are also properly escaped
|
||||||
|
// using the standard C++ escape sequence. The template argument
|
||||||
|
// UnsignedChar is the unsigned version of Char, which is the type of c.
|
||||||
|
template <typename UnsignedChar, typename Char>
|
||||||
|
void PrintCharAndCodeTo(Char c, ostream* os) {
|
||||||
|
// First, print c as a literal in the most readable form we can find.
|
||||||
|
*os << ((sizeof(c) > 1) ? "L'" : "'");
|
||||||
|
const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
|
||||||
|
*os << "'";
|
||||||
|
|
||||||
|
// To aid user debugging, we also print c's code in decimal, unless
|
||||||
|
// it's 0 (in which case c was printed as '\\0', making the code
|
||||||
|
// obvious).
|
||||||
|
if (c == 0)
|
||||||
|
return;
|
||||||
|
*os << " (" << static_cast<int>(c);
|
||||||
|
|
||||||
|
// For more convenience, we print c's code again in hexadecimal,
|
||||||
|
// unless c was already printed in the form '\x##' or the code is in
|
||||||
|
// [1, 9].
|
||||||
|
if (format == kHexEscape || (1 <= c && c <= 9)) {
|
||||||
|
// Do nothing.
|
||||||
|
} else {
|
||||||
|
*os << ", 0x" << String::FormatHexInt(static_cast<int>(c));
|
||||||
|
}
|
||||||
|
*os << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintTo(unsigned char c, ::std::ostream* os) {
|
||||||
|
PrintCharAndCodeTo<unsigned char>(c, os);
|
||||||
|
}
|
||||||
|
void PrintTo(signed char c, ::std::ostream* os) {
|
||||||
|
PrintCharAndCodeTo<unsigned char>(c, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||||
|
// code otherwise and also as its code. L'\0' is printed as "L'\\0'".
|
||||||
|
void PrintTo(wchar_t wc, ostream* os) {
|
||||||
|
PrintCharAndCodeTo<wchar_t>(wc, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints the given array of characters to the ostream. CharType must be either
|
||||||
|
// char or wchar_t.
|
||||||
|
// The array starts at begin, the length is len, it may include '\0' characters
|
||||||
|
// and may not be NUL-terminated.
|
||||||
|
template <typename CharType>
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
||||||
|
static CharFormat PrintCharsAsStringTo(
|
||||||
|
const CharType* begin, size_t len, ostream* os) {
|
||||||
|
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
|
||||||
|
*os << kQuoteBegin;
|
||||||
|
bool is_previous_hex = false;
|
||||||
|
CharFormat print_format = kAsIs;
|
||||||
|
for (size_t index = 0; index < len; ++index) {
|
||||||
|
const CharType cur = begin[index];
|
||||||
|
if (is_previous_hex && IsXDigit(cur)) {
|
||||||
|
// Previous character is of '\x..' form and this character can be
|
||||||
|
// interpreted as another hexadecimal digit in its number. Break string to
|
||||||
|
// disambiguate.
|
||||||
|
*os << "\" " << kQuoteBegin;
|
||||||
|
}
|
||||||
|
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
|
||||||
|
// Remember if any characters required hex escaping.
|
||||||
|
if (is_previous_hex) {
|
||||||
|
print_format = kHexEscape;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*os << "\"";
|
||||||
|
return print_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
||||||
|
// 'begin'. CharType must be either char or wchar_t.
|
||||||
|
template <typename CharType>
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
||||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
||||||
|
static void UniversalPrintCharArray(
|
||||||
|
const CharType* begin, size_t len, ostream* os) {
|
||||||
|
// The code
|
||||||
|
// const char kFoo[] = "foo";
|
||||||
|
// generates an array of 4, not 3, elements, with the last one being '\0'.
|
||||||
|
//
|
||||||
|
// Therefore when printing a char array, we don't print the last element if
|
||||||
|
// it's '\0', such that the output matches the string literal as it's
|
||||||
|
// written in the source code.
|
||||||
|
if (len > 0 && begin[len - 1] == '\0') {
|
||||||
|
PrintCharsAsStringTo(begin, len - 1, os);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If, however, the last element in the array is not '\0', e.g.
|
||||||
|
// const char kFoo[] = { 'f', 'o', 'o' };
|
||||||
|
// we must print the entire array. We also print a message to indicate
|
||||||
|
// that the array is not NUL-terminated.
|
||||||
|
PrintCharsAsStringTo(begin, len, os);
|
||||||
|
*os << " (no terminating NUL)";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
|
||||||
|
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
|
||||||
|
UniversalPrintCharArray(begin, len, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a (const) wchar_t array of 'len' elements, starting at address
|
||||||
|
// 'begin'.
|
||||||
|
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
|
||||||
|
UniversalPrintCharArray(begin, len, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints the given C string to the ostream.
|
||||||
|
void PrintTo(const char* s, ostream* os) {
|
||||||
|
if (s == nullptr) {
|
||||||
|
*os << "NULL";
|
||||||
|
} else {
|
||||||
|
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
||||||
|
PrintCharsAsStringTo(s, strlen(s), os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MSVC compiler can be configured to define whar_t as a typedef
|
||||||
|
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||||
|
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||||
|
// possibly accessing more memory than intended and causing invalid
|
||||||
|
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
|
||||||
|
// wchar_t is implemented as a native type.
|
||||||
|
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||||
|
// Prints the given wide C string to the ostream.
|
||||||
|
void PrintTo(const wchar_t* s, ostream* os) {
|
||||||
|
if (s == nullptr) {
|
||||||
|
*os << "NULL";
|
||||||
|
} else {
|
||||||
|
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
||||||
|
PrintCharsAsStringTo(s, wcslen(s), os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // wchar_t is native
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool ContainsUnprintableControlCodes(const char* str, size_t length) {
|
||||||
|
const unsigned char *s = reinterpret_cast<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
|
||||||
|
|
||||||
|
void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||||
|
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
||||||
|
if (GTEST_FLAG(print_utf8)) {
|
||||||
|
ConditionalPrintAsText(s.data(), s.size(), os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_STD_WSTRING
|
||||||
|
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
||||||
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
|
}
|
||||||
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace testing
|
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
|
||||||
|
#include "gtest/gtest-test-part.h"
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
#include "src/gtest-internal-inl.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
using internal::GetUnitTestImpl;
|
||||||
|
|
||||||
|
// Gets the summary of the failure message by omitting the stack trace
|
||||||
|
// in it.
|
||||||
|
std::string TestPartResult::ExtractSummary(const char* message) {
|
||||||
|
const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
|
||||||
|
return stack_trace == nullptr ? message : std::string(message, stack_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints a TestPartResult object.
|
||||||
|
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
|
||||||
|
return os << internal::FormatFileLocation(result.file_name(),
|
||||||
|
result.line_number())
|
||||||
|
<< " "
|
||||||
|
<< (result.type() == TestPartResult::kSuccess
|
||||||
|
? "Success"
|
||||||
|
: result.type() == TestPartResult::kSkip
|
||||||
|
? "Skipped"
|
||||||
|
: result.type() == TestPartResult::kFatalFailure
|
||||||
|
? "Fatal failure"
|
||||||
|
: "Non-fatal failure")
|
||||||
|
<< ":\n"
|
||||||
|
<< result.message() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Appends a TestPartResult to the array.
|
||||||
|
void TestPartResultArray::Append(const TestPartResult& result) {
|
||||||
|
array_.push_back(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the TestPartResult at the given index (0-based).
|
||||||
|
const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
|
||||||
|
if (index < 0 || index >= size()) {
|
||||||
|
printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
|
||||||
|
internal::posix::Abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_[static_cast<size_t>(index)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the number of TestPartResult objects in the array.
|
||||||
|
int TestPartResultArray::size() const {
|
||||||
|
return static_cast<int>(array_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
HasNewFatalFailureHelper::HasNewFatalFailureHelper()
|
||||||
|
: has_new_fatal_failure_(false),
|
||||||
|
original_reporter_(GetUnitTestImpl()->
|
||||||
|
GetTestPartResultReporterForCurrentThread()) {
|
||||||
|
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
|
||||||
|
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
|
||||||
|
original_reporter_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HasNewFatalFailureHelper::ReportTestPartResult(
|
||||||
|
const TestPartResult& result) {
|
||||||
|
if (result.fatally_failed())
|
||||||
|
has_new_fatal_failure_ = true;
|
||||||
|
original_reporter_->ReportTestPartResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace testing
|
|
@ -0,0 +1,121 @@
|
||||||
|
// Copyright 2008 Google Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
#include "gtest/gtest-typed-test.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
#if GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
|
// Skips to the first non-space char in str. Returns an empty string if str
|
||||||
|
// contains only whitespace characters.
|
||||||
|
static const char* SkipSpaces(const char* str) {
|
||||||
|
while (IsSpace(*str))
|
||||||
|
str++;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SplitIntoTestNames(const char* src) {
|
||||||
|
std::vector<std::string> name_vec;
|
||||||
|
src = SkipSpaces(src);
|
||||||
|
for (; src != nullptr; src = SkipComma(src)) {
|
||||||
|
name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src)));
|
||||||
|
}
|
||||||
|
return name_vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies that registered_tests match the test names in
|
||||||
|
// registered_tests_; returns registered_tests if successful, or
|
||||||
|
// aborts the program otherwise.
|
||||||
|
const char* TypedTestSuitePState::VerifyRegisteredTestNames(
|
||||||
|
const char* test_suite_name, const char* file, int line,
|
||||||
|
const char* registered_tests) {
|
||||||
|
RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line));
|
||||||
|
|
||||||
|
typedef RegisteredTestsMap::const_iterator RegisteredTestIter;
|
||||||
|
registered_ = true;
|
||||||
|
|
||||||
|
std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests);
|
||||||
|
|
||||||
|
Message errors;
|
||||||
|
|
||||||
|
std::set<std::string> tests;
|
||||||
|
for (std::vector<std::string>::const_iterator name_it = name_vec.begin();
|
||||||
|
name_it != name_vec.end(); ++name_it) {
|
||||||
|
const std::string& name = *name_it;
|
||||||
|
if (tests.count(name) != 0) {
|
||||||
|
errors << "Test " << name << " is listed more than once.\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (RegisteredTestIter it = registered_tests_.begin();
|
||||||
|
it != registered_tests_.end();
|
||||||
|
++it) {
|
||||||
|
if (name == it->first) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
tests.insert(name);
|
||||||
|
} else {
|
||||||
|
errors << "No test named " << name
|
||||||
|
<< " can be found in this test suite.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RegisteredTestIter it = registered_tests_.begin();
|
||||||
|
it != registered_tests_.end();
|
||||||
|
++it) {
|
||||||
|
if (tests.count(it->first) == 0) {
|
||||||
|
errors << "You forgot to list test " << it->first << ".\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& errors_str = errors.GetString();
|
||||||
|
if (errors_str != "") {
|
||||||
|
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
|
||||||
|
errors_str.c_str());
|
||||||
|
fflush(stderr);
|
||||||
|
posix::Abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return registered_tests;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright 2006, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
|
||||||
|
#if GTEST_OS_ESP8266
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void setup() {
|
||||||
|
testing::InitGoogleTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() { RUN_ALL_TESTS(); }
|
||||||
|
|
||||||
|
#if GTEST_OS_ESP8266
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
GTEST_API_ int main(int argc, char **argv) {
|
||||||
|
printf("Running main() from %s\n", __FILE__);
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -43,6 +43,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "frontend-common", "src\fron
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxhash", "dep\xxhash\xxhash.vcxproj", "{09553C96-9F39-49BF-8AE6-7ACBD07C410C}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxhash", "dep\xxhash\xxhash.vcxproj", "{09553C96-9F39-49BF-8AE6-7ACBD07C410C}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "googletest", "dep\googletest\googletest.vcxproj", "{49953E1B-2EF7-46A4-B88B-1BF9E099093B}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
|
@ -359,6 +361,22 @@ Global
|
||||||
{09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64
|
{09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64
|
||||||
{09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32
|
{09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32
|
||||||
{09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32
|
{09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugFast|x64.ActiveCfg = DebugFast|x64
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugFast|x64.Build.0 = DebugFast|x64
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugFast|x86.ActiveCfg = DebugFast|Win32
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugFast|x86.Build.0 = DebugFast|Win32
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Release|x64.Build.0 = Release|x64
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseLTCG|x64.ActiveCfg = ReleaseLTCG|x64
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -378,6 +396,7 @@ Global
|
||||||
{97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D} = {BA490C0E-497D-4634-A21E-E65012006385}
|
{97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D} = {BA490C0E-497D-4634-A21E-E65012006385}
|
||||||
{DD944834-7899-4C1C-A4C1-064B5009D239} = {BA490C0E-497D-4634-A21E-E65012006385}
|
{DD944834-7899-4C1C-A4C1-064B5009D239} = {BA490C0E-497D-4634-A21E-E65012006385}
|
||||||
{09553C96-9F39-49BF-8AE6-7ACBD07C410C} = {BA490C0E-497D-4634-A21E-E65012006385}
|
{09553C96-9F39-49BF-8AE6-7ACBD07C410C} = {BA490C0E-497D-4634-A21E-E65012006385}
|
||||||
|
{49953E1B-2EF7-46A4-B88B-1BF9E099093B} = {BA490C0E-497D-4634-A21E-E65012006385}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {26E40B32-7C1D-48D0-95F4-1A500E054028}
|
SolutionGuid = {26E40B32-7C1D-48D0-95F4-1A500E054028}
|
||||||
|
|
Loading…
Reference in New Issue