summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am7
-rw-r--r--scons/SConscript19
-rw-r--r--scons/SConscript.common18
-rw-r--r--scons/SConstruct2
-rwxr-xr-xscripts/generate_gtest_def.py169
-rw-r--r--src/gtest.def123
-rw-r--r--test/gtest_dll_test_.cc498
7 files changed, 834 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index d147d13..7ca3916 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,6 +17,7 @@ EXTRA_DIST = \
scons/SConstruct.common \
scripts/fuse_gtest_files.py \
scripts/gen_gtest_pred_impl.py \
+ scripts/generate_gtest_def.py \
scripts/test/Makefile
# gtest source files that we don't compile directly.
@@ -27,7 +28,8 @@ EXTRA_DIST += \
src/gtest-internal-inl.h \
src/gtest-port.cc \
src/gtest-test-part.cc \
- src/gtest-typed-test.cc
+ src/gtest-typed-test.cc \
+ src/gtest.def
# Sample files that we don't compile.
EXTRA_DIST += \
@@ -86,7 +88,8 @@ EXTRA_DIST += \
test/gtest_uninitialized_test_.cc \
test/gtest_xml_outfile1_test_.cc \
test/gtest_xml_outfile2_test_.cc \
- test/gtest_xml_output_unittest_.cc
+ test/gtest_xml_output_unittest_.cc \
+ test/gtest_dll_test_.cc
# Python tests that we don't run.
EXTRA_DIST += \
diff --git a/scons/SConscript b/scons/SConscript
index 25220ee..a2c31dc 100644
--- a/scons/SConscript
+++ b/scons/SConscript
@@ -292,6 +292,25 @@ if BUILD_TESTS:
GtestBinary(env_without_rtti, 'gtest_no_rtti_test', gtest_main_no_rtti,
['../test/gtest_unittest.cc'])
+ # Tests that gtest works when built as a DLL on Windows.
+ # We don't need to actually run this test.
+ # Note: this is not supported under VC 7.1.
+ if env['PLATFORM'] == 'win32' and env.get('GTEST_BUILD_DLL_TEST', None):
+ test_env = EnvCreator.Create(env, EnvCreator.DllBuild)
+ dll_env = test_env.Clone()
+ dll_env.Append(LINKFLAGS=['-DEF:../src/gtest.def'])
+
+ gtest_dll = dll_env.SharedLibrary(
+ target='gtest_dll',
+ source=[dll_env.SharedObject('gtest_all_dll',
+ '../src/gtest-all.cc'),
+ dll_env.SharedObject('gtest_main_dll',
+ '../src/gtest_main.cc')])
+ # TODO(vladl@google.com): Get rid of the .data[1] hack. Find a proper
+ # way to depend on a shared library without knowing its path in advance.
+ test_env.Program('gtest_dll_test_',
+ ['../test/gtest_dll_test_.cc', gtest_dll.data[1]])
+
############################################################
# Sample targets.
diff --git a/scons/SConscript.common b/scons/SConscript.common
index 7fda32e..7943e77 100644
--- a/scons/SConscript.common
+++ b/scons/SConscript.common
@@ -132,6 +132,24 @@ class EnvCreator:
env.Append(CPPDEFINES='GTEST_HAS_RTTI=0')
NoRtti = classmethod(NoRtti)
+ def DllBuild(cls, env):
+ """Enables building gtets as a DLL."""
+
+ env['OBJ_SUFFIX'] = '_dll'
+ # -MT(d) instructs MSVC to link to the static version of the C++
+ # runtime library; -MD(d) tells it to link to the DLL version.
+ flags = env['CCFLAGS']
+ if '-MTd' in flags:
+ flags.remove('-MTd')
+ flags.append('-MDd')
+ elif '-MT' in flags:
+ flags.remove('-MT')
+ flags.append('-MD')
+
+ # Disables the "non dll-interface class 'stdext::exception' used as
+ # base for dll-interface class" warning triggered by the STL code.
+ env.Append(CCFLAGS=['/wd4275'])
+ DllBuild = classmethod(DllBuild)
sconscript_exports = {'EnvCreator': EnvCreator}
Return('sconscript_exports')
diff --git a/scons/SConstruct b/scons/SConstruct
index c749d6a..f4f8237 100644
--- a/scons/SConstruct
+++ b/scons/SConstruct
@@ -56,6 +56,8 @@ win_base = sconstruct_helper.MakeWinBaseEnvironment()
# setting for our users.
if win_base.get('MSVS_VERSION', None) == '7.1':
sconstruct_helper.EnableExceptions(win_base)
+else:
+ win_base['GTEST_BUILD_DLL_TEST'] = True
sconstruct_helper.MakeWinDebugEnvironment(win_base, 'win-dbg')
sconstruct_helper.MakeWinOptimizedEnvironment(win_base, 'win-opt')
diff --git a/scripts/generate_gtest_def.py b/scripts/generate_gtest_def.py
new file mode 100755
index 0000000..9de7038
--- /dev/null
+++ b/scripts/generate_gtest_def.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Google Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Generates the gtest.def file to build Google Test as a DLL on Windows.
+
+SYNOPSIS
+ Put diagnostic messages from building gtest_dll_test_.exe into
+ BUILD_RESULTS_FILE and invoke
+
+ generate_gtest_def.py <BUILD_RESULTS_FILE
+
+ Reads output of VC++ linker and re-generates the src/gtest.def file
+ required for building gtest as a DLL.
+
+ Use this script if you modify Google Test's source code and Visual
+ Studio linker starts complaining about unresolved external symbols.
+ You may have to repeate the build/re-generate cycle several times
+ because VC++ limits the number of unresolved external symbols it can
+ report at a time.
+
+EXAMPLES
+ scons\scons.py | scripts\generate_gtest_def.py
+
+This tool is experimental. Please report any problems to
+googletestframework@googlegroups.com. You can read
+http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide for more
+information.
+"""
+
+__author__ = 'vladl@google.com (Vlad Losev)'
+
+import os
+import re
+import sets
+import sys
+
+# We assume that this file is in the scripts/ directory in the Google
+# Test root directory.
+GTEST_DEF_PATH = os.path.join(os.path.dirname(__file__), '../src/gtest.def')
+
+# Locates the header of the EXPORTS section.
+EXPORTS_SECTION_REGEX = re.compile(r'^EXPORTS\s*$', re.IGNORECASE)
+
+# Determines if a line looks like an export definition in the EXPORTS
+# section of a module definition file.
+EXPORT_REGEX = re.compile(r'^\s+(\S+)')
+
+# Determines if a given line contains an error message about unresolved
+# linker symbol.
+IS_UNRESOLVED_SYMBOL_REGEX = re.compile(r'\bunresolved external symbol\b')
+
+# Fetches the symbol name from a line that contains an unresolved linker
+# symbol message.
+UNRESOLVED_SYMBOL_REGEX = re.compile(r'^.*?"[^"]+" \((\S+)\)')
+
+
+def ReadDefExports(stream):
+ """Reads contents of a def file and returns a list of exported symbols."""
+
+ is_export = False
+ exports = sets.Set()
+ for line in stream:
+ if EXPORTS_SECTION_REGEX.match(line):
+ is_export = True
+ elif EXPORT_REGEX.match(line):
+ if is_export:
+ exports.add(EXPORT_REGEX.match(line).group(1))
+ else:
+ is_export = False
+
+ return exports
+
+
+def ReadUnresolvedExternals(stream):
+ """Reads linker output and returns list of unresolved linker symbols."""
+
+ unresolved = sets.Set()
+
+ for line in stream:
+ if IS_UNRESOLVED_SYMBOL_REGEX.search(line):
+ unresolved.add(UNRESOLVED_SYMBOL_REGEX.match(line).group(1))
+
+ return unresolved
+
+
+def AdjustExports(exports, unresolved):
+ """Adjusts exports list based on the list of unresolved symbols."""
+
+ if unresolved & exports:
+ # There are symbols that are listed as exported but are also reported
+ # unresolved. This is most likely because they have been removed from
+ # Google Test but their mentions in gtest.def constitute references. We
+ # need to remove such symbols from the EXPORTS section. Also, their
+ # presence means that the Google Test DLL has failed to link and
+ # consequently linking of the test .exe was not attempted, meaning that
+ # at this time, there will be no unresolved externals that need to be
+ # added to the exports list.
+ exports -= unresolved
+ else:
+ # Finding unresolved exports means that the Google Test DLL had link
+ # errors and the build script did not build gtest_dll_test_.exe. The user
+ # has to build the test once again and run this script on the diagnostic
+ # output of the build.
+ exports |= unresolved
+
+ return exports
+
+
+def WriteGtestDefFile(stream, exports):
+ """Writes contents of gtest.def given a list of exported symbols."""
+
+ stream.write('; This file is auto-generated. DO NOT EDIT DIRECTLY.\n'
+ '; For more information, see scripts/generate_gtest_def.py.\n'
+ '\nLIBRARY\n'
+ '\nEXPORTS\n')
+ for symbol in sorted(exports):
+ stream.write(' %s\n' % symbol)
+
+
+def main():
+ unresolved = ReadUnresolvedExternals(sys.stdin)
+ if unresolved:
+ try:
+ gtest_def = open(GTEST_DEF_PATH, 'r')
+ exports = ReadDefExports(gtest_def)
+ gtest_def.close()
+ except IOError:
+ exports = sets.Set()
+
+ exports = AdjustExports(exports, unresolved)
+ WriteGtestDefFile(open(GTEST_DEF_PATH, 'w'), exports)
+ sys.stderr.write('Updated test/gtest.def. Please clean the .dll file\n'
+ 'produced by your Google Test DLL build, run the build\n'
+ 'again and pass its diagnostic output to this script\n'
+ 'unless the build succeeds.\n')
+ else:
+ sys.stderr.write('The build diagnostic output indicates no unresolved\n'
+ 'externals. test/gtest.def is likely up to date and\n'
+ 'has not been updated.\n')
+
+if __name__ == '__main__':
+ main()
diff --git a/src/gtest.def b/src/gtest.def
new file mode 100644
index 0000000..a5583df
--- /dev/null
+++ b/src/gtest.def
@@ -0,0 +1,123 @@
+; This file is auto-generated. DO NOT EDIT DIRECTLY.
+; For more information, see scripts/generate_gtest_def.py.
+
+LIBRARY
+
+EXPORTS
+ ??0AssertHelper@internal@testing@@QAE@W4Type@TestPartResult@2@PBDH1@Z
+ ??0AssertionResult@testing@@QAE@ABV01@@Z
+ ??0ExitedWithCode@testing@@QAE@H@Z
+ ??0GTestLog@internal@testing@@QAE@W4GTestLogSeverity@12@PBDH@Z
+ ??0HasNewFatalFailureHelper@internal@testing@@QAE@XZ
+ ??0ScopedFakeTestPartResultReporter@testing@@QAE@W4InterceptMode@01@PAVTestPartResultArray@1@@Z
+ ??0ScopedTrace@internal@testing@@QAE@PBDHABVMessage@2@@Z
+ ??0SingleFailureChecker@internal@testing@@QAE@PBVTestPartResultArray@2@W4Type@TestPartResult@2@PBD@Z
+ ??0Test@testing@@IAE@XZ
+ ??0TestPartResultArray@testing@@QAE@XZ
+ ??1AssertHelper@internal@testing@@QAE@XZ
+ ??1GTestLog@internal@testing@@QAE@XZ
+ ??1HasNewFatalFailureHelper@internal@testing@@UAE@XZ
+ ??1RE@internal@testing@@QAE@XZ
+ ??1ScopedFakeTestPartResultReporter@testing@@UAE@XZ
+ ??1ScopedTrace@internal@testing@@QAE@XZ
+ ??1SingleFailureChecker@internal@testing@@QAE@XZ
+ ??1Test@testing@@UAE@XZ
+ ??1TestPartResultArray@testing@@QAE@XZ
+ ??4AssertHelper@internal@testing@@QBEXABVMessage@2@@Z
+ ??6Message@testing@@QAEAAV01@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z
+ ??7AssertionResult@testing@@QBE?AV01@XZ
+ ??RExitedWithCode@testing@@QBE_NH@Z
+ ?AddEnvironment@UnitTest@testing@@AAEPAVEnvironment@2@PAV32@@Z
+ ?AlwaysTrue@internal@testing@@YA_NXZ
+ ?Append@TestEventListeners@testing@@QAEXPAVTestEventListener@2@@Z
+ ?AssertionFailure@testing@@YA?AVAssertionResult@1@ABVMessage@1@@Z
+ ?AssertionFailure@testing@@YA?AVAssertionResult@1@XZ
+ ?AssertionSuccess@testing@@YA?AVAssertionResult@1@XZ
+ ?CmpHelperSTRCASEEQ@internal@testing@@YA?AVAssertionResult@2@PBD000@Z
+ ?CmpHelperSTRCASENE@internal@testing@@YA?AVAssertionResult@2@PBD000@Z
+ ?CmpHelperSTREQ@internal@testing@@YA?AVAssertionResult@2@PBD000@Z
+ ?CmpHelperSTREQ@internal@testing@@YA?AVAssertionResult@2@PBD0PB_W1@Z
+ ?CmpHelperSTRNE@internal@testing@@YA?AVAssertionResult@2@PBD000@Z
+ ?CmpHelperSTRNE@internal@testing@@YA?AVAssertionResult@2@PBD0PB_W1@Z
+ ?Compare@String@internal@testing@@QBEHABV123@@Z
+ ?Create@DeathTest@internal@testing@@SA_NPBDPBVRE@23@0HPAPAV123@@Z
+ ?DoubleLE@testing@@YA?AVAssertionResult@1@PBD0NN@Z
+ ?DoubleNearPredFormat@internal@testing@@YA?AVAssertionResult@2@PBD00NNN@Z
+ ?EqFailure@internal@testing@@YA?AVAssertionResult@2@PBD0ABVString@12@1_N@Z
+ ?ExitedUnsuccessfully@internal@testing@@YA_NH@Z
+ ?FLAGS_gtest_also_run_disabled_tests@testing@@3_NA
+ ?FLAGS_gtest_break_on_failure@testing@@3_NA
+ ?FLAGS_gtest_catch_exceptions@testing@@3_NA
+ ?FLAGS_gtest_color@testing@@3VString@internal@1@A
+ ?FLAGS_gtest_filter@testing@@3VString@internal@1@A
+ ?FLAGS_gtest_output@testing@@3VString@internal@1@A
+ ?FLAGS_gtest_print_time@testing@@3_NA
+ ?FLAGS_gtest_random_seed@testing@@3HA
+ ?FLAGS_gtest_repeat@testing@@3HA
+ ?FLAGS_gtest_shuffle@testing@@3_NA
+ ?FLAGS_gtest_stack_trace_depth@testing@@3HA
+ ?FLAGS_gtest_throw_on_failure@testing@@3_NA
+ ?Failed@TestResult@testing@@QBE_NXZ
+ ?Failed@UnitTest@testing@@QBE_NXZ
+ ?FloatLE@testing@@YA?AVAssertionResult@1@PBD0MM@Z
+ ?Format@String@internal@testing@@SA?AV123@PBDZZ
+ ?FormatForFailureMessage@internal@testing@@YA?AVString@12@D@Z
+ ?GetBoolAssertionFailureMessage@internal@testing@@YA?AVString@12@ABVAssertionResult@2@PBD11@Z
+ ?GetInstance@UnitTest@testing@@SAPAV12@XZ
+ ?GetTestCase@UnitTest@testing@@QBEPBVTestCase@2@H@Z
+ ?GetTestInfo@TestCase@testing@@QBEPBVTestInfo@2@H@Z
+ ?GetTestPartResult@TestResult@testing@@QBEABVTestPartResult@2@H@Z
+ ?GetTestProperty@TestResult@testing@@QBEABVTestProperty@2@H@Z
+ ?GetTestTypeId@internal@testing@@YAPBXXZ
+ ?HasFatalFailure@Test@testing@@SA_NXZ
+ ?HasFatalFailure@TestResult@testing@@QBE_NXZ
+ ?HasNonfatalFailure@Test@testing@@SA_NXZ
+ ?HasNonfatalFailure@TestResult@testing@@QBE_NXZ
+ ?Init@RE@internal@testing@@AAEXPBD@Z
+ ?InitGoogleTest@testing@@YAXPAHPAPAD@Z
+ ?IsHRESULTFailure@internal@testing@@YA?AVAssertionResult@2@PBDJ@Z
+ ?IsHRESULTSuccess@internal@testing@@YA?AVAssertionResult@2@PBDJ@Z
+ ?IsTrue@internal@testing@@YA_N_N@Z
+ ?LastMessage@DeathTest@internal@testing@@SAPBDXZ
+ ?MakeAndRegisterTestInfo@internal@testing@@YAPAVTestInfo@2@PBD000PBXP6AXXZ2PAVTestFactoryBase@12@@Z
+ ?Passed@UnitTest@testing@@QBE_NXZ
+ ?RecordProperty@Test@testing@@SAXPBD0@Z
+ ?Release@TestEventListeners@testing@@QAEPAVTestEventListener@2@PAV32@@Z
+ ?ReportInvalidTestCaseType@internal@testing@@YAXPBD0H@Z
+ ?Run@UnitTest@testing@@QAEHXZ
+ ?SetUp@Test@testing@@MAEXXZ
+ ?ShowCStringQuoted@String@internal@testing@@SA?AV123@PBD@Z
+ ?ShowWideCStringQuoted@String@internal@testing@@SA?AV123@PB_W@Z
+ ?StrStreamToString@internal@testing@@YA?AVString@12@PAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
+ ?TearDown@Test@testing@@MAEXXZ
+ ?VerifyRegisteredTestNames@TypedTestCasePState@internal@testing@@QAEPBDPBDH0@Z
+ ?comment@TestInfo@testing@@QBEPBDXZ
+ ?current_test_case@UnitTest@testing@@QBEPBVTestCase@2@XZ
+ ?current_test_info@UnitTest@testing@@QBEPBVTestInfo@2@XZ
+ ?disabled_test_count@TestCase@testing@@QBEHXZ
+ ?disabled_test_count@UnitTest@testing@@QBEHXZ
+ ?elapsed_time@UnitTest@testing@@QBE_JXZ
+ ?failed_test_case_count@UnitTest@testing@@QBEHXZ
+ ?failed_test_count@TestCase@testing@@QBEHXZ
+ ?failed_test_count@UnitTest@testing@@QBEHXZ
+ ?g_linked_ptr_mutex@internal@testing@@3VMutex@12@A
+ ?listeners@UnitTest@testing@@QAEAAVTestEventListeners@2@XZ
+ ?name@TestInfo@testing@@QBEPBDXZ
+ ?original_working_dir@UnitTest@testing@@QBEPBDXZ
+ ?parameterized_test_registry@UnitTest@testing@@QAEAAVParameterizedTestCaseRegistry@internal@2@XZ
+ ?random_seed@UnitTest@testing@@QBEHXZ
+ ?result@TestInfo@testing@@QBEPBVTestResult@2@XZ
+ ?should_run@TestInfo@testing@@QBE_NXZ
+ ?successful_test_case_count@UnitTest@testing@@QBEHXZ
+ ?successful_test_count@TestCase@testing@@QBEHXZ
+ ?successful_test_count@UnitTest@testing@@QBEHXZ
+ ?test_case_comment@TestInfo@testing@@QBEPBDXZ
+ ?test_case_name@TestInfo@testing@@QBEPBDXZ
+ ?test_case_to_run_count@UnitTest@testing@@QBEHXZ
+ ?test_property_count@TestResult@testing@@QBEHXZ
+ ?test_to_run_count@TestCase@testing@@QBEHXZ
+ ?test_to_run_count@UnitTest@testing@@QBEHXZ
+ ?total_part_count@TestResult@testing@@QBEHXZ
+ ?total_test_case_count@UnitTest@testing@@QBEHXZ
+ ?total_test_count@TestCase@testing@@QBEHXZ
+ ?total_test_count@UnitTest@testing@@QBEHXZ
diff --git a/test/gtest_dll_test_.cc b/test/gtest_dll_test_.cc
new file mode 100644
index 0000000..c99358a
--- /dev/null
+++ b/test/gtest_dll_test_.cc
@@ -0,0 +1,498 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vladl@google.com (Vlad Losev)
+//
+// Tests for Google Test itself. This verifies that Google Test can be
+// linked into an executable successfully when built as a DLL on Windows.
+// The test is not meant to check the success of test assertions employed in
+// it. It only checks that constructs in them can be successfully linked.
+//
+// If you add new features to Google Test's documented interface, you need to
+// add tests exercising them to this file.
+//
+// If you start having 'unresolved external symbol' linker errors in this file
+// after the changes you have made, re-generate src/gtest.def by running
+// scripts/generate_gtest_def.py.
+
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+#include <windows.h>
+#include <vector>
+
+using ::std::vector;
+using ::std::tr1::tuple;
+
+
+using ::testing::AddGlobalTestEnvironment;
+using ::testing::AssertionFailure;
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+using ::testing::DoubleLE;
+using ::testing::EmptyTestEventListener;
+using ::testing::Environment;
+using ::testing::ExitedWithCode;
+using ::testing::FloatLE;
+using ::testing::GTEST_FLAG(also_run_disabled_tests);
+using ::testing::GTEST_FLAG(break_on_failure);
+using ::testing::GTEST_FLAG(catch_exceptions);
+using ::testing::GTEST_FLAG(color);
+using ::testing::GTEST_FLAG(filter);
+using ::testing::GTEST_FLAG(output);
+using ::testing::GTEST_FLAG(print_time);
+using ::testing::GTEST_FLAG(random_seed);
+using ::testing::GTEST_FLAG(repeat);
+using ::testing::GTEST_FLAG(shuffle);
+using ::testing::GTEST_FLAG(stack_trace_depth);
+using ::testing::GTEST_FLAG(throw_on_failure);
+using ::testing::InitGoogleTest;
+using ::testing::Message;
+using ::testing::Test;
+using ::testing::TestCase;
+using ::testing::TestEventListener;
+using ::testing::TestEventListeners;
+using ::testing::TestInfo;
+using ::testing::TestPartResult;
+using ::testing::TestProperty;
+using ::testing::TestResult;
+using ::testing::UnitTest;
+using ::testing::internal::AlwaysTrue;
+using ::testing::internal::AlwaysFalse;
+
+#if GTEST_HAS_PARAM_TEST
+using ::testing::Bool;
+using ::testing::Combine;
+using ::testing::TestWithParam;
+using ::testing::Values;
+using ::testing::ValuesIn;
+#endif // GTEST_HAS_PARAM_TEST
+
+#if GTEST_HAS_TYPED_TEST
+using ::testing::Types;
+#endif // GTEST_HAS_TYPED_TEST
+
+// Tests linking of TEST constructs.
+TEST(TestMacroTest, LinksSuccessfully) {
+}
+
+// Tests linking of TEST_F constructs.
+class FixtureTest : public Test {
+};
+
+TEST_F(FixtureTest, LinksSuccessfully) {
+}
+
+// Tests linking of value parameterized tests.
+#if GTEST_HAS_PARAM_TEST
+class IntParamTest : public TestWithParam<int> {};
+
+TEST_P(IntParamTest, LinksSuccessfully) {}
+
+const int c_array[] = {1, 2};
+INSTANTIATE_TEST_CASE_P(ValuesInCArrayTest, IntParamTest, ValuesIn(c_array));
+
+INSTANTIATE_TEST_CASE_P(ValuesInIteratorPairTest, IntParamTest,
+ ValuesIn(c_array, c_array + 2));
+
+vector<int> stl_vector(c_array, c_array + 2);
+INSTANTIATE_TEST_CASE_P(ValuesInStlVectorTest, IntParamTest,
+ ValuesIn(stl_vector));
+
+class BoolParamTest : public TestWithParam<bool> {};
+
+INSTANTIATE_TEST_CASE_P(BoolTest, BoolParamTest, Bool());
+
+INSTANTIATE_TEST_CASE_P(ValuesTest, IntParamTest, Values(1, 2));
+
+#if GTEST_HAS_COMBINE
+class CombineTest : public TestWithParam<tuple<int, bool> > {};
+
+INSTANTIATE_TEST_CASE_P(CombineTest, CombineTest, Combine(Values(1), Bool()));
+#endif // GTEST_HAS_COMBINE
+#endif // GTEST_HAS_PARAM_TEST
+
+// Tests linking of typed tests.
+#if GTEST_HAS_TYPED_TEST
+template <typename T> class TypedTest : public Test {};
+
+TYPED_TEST_CASE(TypedTest, Types<int>);
+
+TYPED_TEST(TypedTest, LinksSuccessfully) {}
+#endif // GTEST_HAS_TYPED_TEST
+
+// Tests linking of type-parameterized tests.
+#if GTEST_HAS_TYPED_TEST_P
+template <typename T> class TypeParameterizedTest : public Test {};
+
+TYPED_TEST_CASE_P(TypeParameterizedTest);
+
+TYPED_TEST_P(TypeParameterizedTest, LinksSuccessfully) {}
+
+REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTest, LinksSuccessfully);
+
+INSTANTIATE_TYPED_TEST_CASE_P(Char, TypeParameterizedTest, Types<char>);
+#endif // GTEST_HAS_TYPED_TEST_P
+
+// Tests linking of explicit success or failure.
+TEST(ExplicitSuccessFailureTest, ExplicitSuccessAndFailure) {
+ if (AlwaysTrue())
+ SUCCEED() << "This is a success statement";
+ if (AlwaysFalse()) {
+ ADD_FAILURE() << "This is a non-fatal failure assertion";
+ FAIL() << "This is a fatal failure assertion";
+ }
+}
+
+// Tests linking of Boolean assertions.
+AssertionResult IsEven(int n) {
+ if (n % 2 == 0)
+ return AssertionSuccess() << n << " is even";
+ else
+ return AssertionFailure() << n << " is odd";
+}
+
+TEST(BooleanAssertionTest, LinksSuccessfully) {
+ EXPECT_TRUE(true) << "true is true";
+ EXPECT_FALSE(false) << "false is not true";
+ ASSERT_TRUE(true);
+ ASSERT_FALSE(false);
+ EXPECT_TRUE(IsEven(2));
+ EXPECT_FALSE(IsEven(3));
+}
+
+// Tests linking of predicate assertions.
+bool IsOdd(int n) { return n % 2 != 0; }
+
+bool Ge(int val1, int val2) { return val1 >= val2; }
+
+TEST(PredicateAssertionTest, LinksSuccessfully) {
+ EXPECT_PRED1(IsOdd, 1);
+ EXPECT_PRED2(Ge, 2, 1);
+}
+
+AssertionResult AddToFive(const char* val1_expr,
+ const char* val2_expr,
+ int val1,
+ int val2) {
+ if (val1 + val2 == 5)
+ return AssertionSuccess();
+
+ return AssertionFailure() << val1_expr << " and " << val2_expr
+ << " (" << val1 << " and " << val2 << ") "
+ << "do not add up to five, as their sum is "
+ << val1 + val2;
+}
+
+TEST(PredicateFormatterAssertionTest, LinksSuccessfully) {
+ EXPECT_PRED_FORMAT2(AddToFive, 1 + 2, 2);
+}
+
+
+// Tests linking of comparison assertions.
+TEST(ComparisonAssertionTest, LinksSuccessfully) {
+ EXPECT_EQ(1, 1);
+ EXPECT_NE(1, 2);
+ EXPECT_LT(1, 2);
+ EXPECT_LE(1, 1);
+ EXPECT_GT(2, 1);
+ EXPECT_GE(2, 1);
+
+ EXPECT_EQ('\n', '\n');
+ EXPECT_NE('\n', '\r');
+ EXPECT_LT('\n', 'a');
+ EXPECT_LE('\n', 'b');
+ EXPECT_GT('a', '\t');
+ EXPECT_GE('b', '\t');
+}
+
+TEST(StringComparisonAssertionTest, LinksSuccessfully) {
+ EXPECT_STREQ("test", "test");
+ EXPECT_STRNE("test", "prod");
+
+ char test_str[5] = "test";
+ char prod_str[5] = "prod";
+
+ EXPECT_STREQ(test_str, test_str);
+ EXPECT_STRNE(test_str, prod_str);
+
+ EXPECT_STRCASEEQ("test", "TEST");
+ EXPECT_STRCASENE("test", "prod");
+
+ wchar_t test_wstr[5] = L"test";
+ wchar_t prod_wstr[5] = L"prod";
+
+ EXPECT_STREQ(L"test", L"test");
+ EXPECT_STRNE(L"test", L"prod");
+
+ EXPECT_STREQ(test_wstr, test_wstr);
+ EXPECT_STRNE(test_wstr, prod_wstr);
+
+#if GTEST_HAS_STD_STRING
+ EXPECT_EQ("test", ::std::string("test"));
+ EXPECT_NE("test", ::std::string("prod"));
+
+ EXPECT_EQ(::std::string("test"), "test");
+ EXPECT_NE(::std::string("prod"), "test");
+
+ EXPECT_EQ(test_str, ::std::string("test"));
+ EXPECT_NE(test_str, ::std::string("prod"));
+
+ EXPECT_EQ(::std::string("test"), test_str);
+ EXPECT_NE(::std::string("prod"), test_str);
+
+ EXPECT_EQ(::std::string("test"), ::std::string("test"));
+ EXPECT_NE(::std::string("test"), ::std::string("prod"));
+#endif // GTEST_HAS_STD_STRING
+
+#if GTEST_HAS_STD_WSTRING
+ EXPECT_EQ(L"test", ::std::wstring(L"test"));
+ EXPECT_NE(L"test", ::std::wstring(L"prod"));
+
+ EXPECT_EQ(::std::wstring(L"test"), L"test");
+ EXPECT_NE(::std::wstring(L"prod"), L"test");
+
+ EXPECT_EQ(test_wstr, ::std::wstring(L"test"));
+ EXPECT_NE(test_wstr, ::std::wstring(L"prod"));
+
+ EXPECT_EQ(::std::wstring(L"test"), test_wstr);
+ EXPECT_NE(::std::wstring(L"prod"), test_wstr);
+
+ EXPECT_EQ(::std::wstring(L"test"), ::std::wstring(L"test"));
+ EXPECT_NE(::std::wstring(L"test"), ::std::wstring(L"prod"));
+#endif // GTEST_HAS_STD_WSTRING
+}
+
+// Tests linking of floating point assertions.
+TEST(FloatingPointComparisonAssertionTest, LinksSuccessfully) {
+ EXPECT_FLOAT_EQ(0.0f, 0.0f);
+ EXPECT_DOUBLE_EQ(0.0, 0.0);
+ EXPECT_NEAR(0.0, 0.1, 0.2);
+ EXPECT_PRED_FORMAT2(::testing::FloatLE, 0.0f, 0.01f);
+ EXPECT_PRED_FORMAT2(::testing::DoubleLE, 0.0, 0.001);
+}
+
+// Tests linking of HRESULT assertions.
+TEST(HresultAssertionTest, LinksSuccessfully) {
+ EXPECT_HRESULT_SUCCEEDED(S_OK);
+ EXPECT_HRESULT_FAILED(E_FAIL);
+}
+
+#if GTEST_HAS_EXCEPTIONS
+// Tests linking of exception assertions.
+TEST(ExceptionAssertionTest, LinksSuccessfully) {
+ EXPECT_THROW(throw 1, int);
+ EXPECT_ANY_THROW(throw 1);
+ EXPECT_NO_THROW(int x = 1);
+}
+#endif // GTEST_HAS_EXCEPTIONS
+
+// Tests linking of death test assertions.
+TEST(DeathTestAssertionDeathTest, LinksSuccessfully) {
+ EXPECT_DEATH_IF_SUPPORTED(exit(1), "");
+
+#if GTEST_HAS_DEATH_TEST
+ EXPECT_EXIT(exit(1), ExitedWithCode(1), "");
+#endif // GTEST_HAS_DEATH_TEST
+}
+
+// Tests linking of SCOPED_TRACE.
+void Sub() { EXPECT_EQ(1, 1); }
+
+TEST(ScopedTraceTest, LinksSuccessfully) {
+ SCOPED_TRACE("X");
+ Sub();
+}
+
+// Tests linking of failure absence assertions.
+TEST(NoFailureAssertionTest, LinksSuccessfully) {
+ EXPECT_NO_FATAL_FAILURE(IsEven(2));
+}
+
+// Tests linking of HasFatalFailure.
+TEST(HasFatalFailureTest, LinksSuccessfully) {
+ EXPECT_FALSE(HasFatalFailure());
+ EXPECT_FALSE(HasNonfatalFailure());
+ EXPECT_FALSE(HasFailure());
+}
+
+// Tests linking of RecordProperty.
+TEST(RecordPropertyTest, LinksSuccessfully) {
+ RecordProperty("DummyPropery", "DummyValue");
+}
+
+// Tests linking of environments.
+class MyEnvironment : public Environment {};
+
+Environment* const environment = AddGlobalTestEnvironment(new MyEnvironment);
+
+// Tests linking of flags.
+TEST(FlagTest, LinksSuccessfully) {
+ Message message;
+
+ message << GTEST_FLAG(filter);
+ message << GTEST_FLAG(also_run_disabled_tests);
+ message << GTEST_FLAG(repeat);
+ message << GTEST_FLAG(shuffle);
+ message << GTEST_FLAG(random_seed);
+ message << GTEST_FLAG(color);
+ message << GTEST_FLAG(print_time);
+ message << GTEST_FLAG(output);
+ message << GTEST_FLAG(break_on_failure);
+ message << GTEST_FLAG(throw_on_failure);
+ message << GTEST_FLAG(catch_exceptions);
+ message << GTEST_FLAG(stack_trace_depth);
+}
+
+// Tests linking of failure catching assertions.
+void FunctionWithFailure() { FAIL(); }
+
+TEST(FailureCatchingAssertionTest, LinksCorrectly) {
+ EXPECT_FATAL_FAILURE(FunctionWithFailure(), "");
+ EXPECT_NONFATAL_FAILURE(ADD_FAILURE(), "");
+ EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FunctionWithFailure(), "");
+ EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(ADD_FAILURE(), "");
+}
+
+// Tests linking of the reflection API.
+TEST(ReflectionApiTest, LinksCorrectly) {
+ // UnitTest API.
+ UnitTest* unit_test = UnitTest::GetInstance();
+
+ unit_test->original_working_dir();
+ EXPECT_TRUE(unit_test->current_test_case() != NULL);
+ EXPECT_TRUE(unit_test->current_test_info() != NULL);
+ EXPECT_NE(0, unit_test->random_seed());
+ EXPECT_GE(unit_test->successful_test_case_count(), 0);
+ EXPECT_EQ(0, unit_test->failed_test_case_count());
+ EXPECT_GE(unit_test->total_test_case_count(), 0);
+ EXPECT_GT(unit_test->test_case_to_run_count(), 0);
+ EXPECT_GE(unit_test->successful_test_count(), 0);
+ EXPECT_EQ(0, unit_test->failed_test_count());
+ EXPECT_EQ(0, unit_test->disabled_test_count());
+ EXPECT_GT(unit_test->total_test_count(), 0);
+ EXPECT_GT(unit_test->test_to_run_count(), 0);
+ EXPECT_GE(unit_test->elapsed_time(), 0);
+ EXPECT_TRUE(unit_test->Passed());
+ EXPECT_FALSE(unit_test->Failed());
+ EXPECT_TRUE(unit_test->GetTestCase(0) != NULL);
+
+ // TestCase API.
+ const TestCase*const test_case = unit_test->current_test_case();
+
+ EXPECT_STRNE("", test_case->name());
+ const char* const test_case_comment = test_case->comment();
+ EXPECT_TRUE(test_case->should_run());
+ EXPECT_GE(test_case->successful_test_count(), 0);
+ EXPECT_EQ(0, test_case->failed_test_count());
+ EXPECT_EQ(0, test_case->disabled_test_count());
+ EXPECT_GT(test_case->test_to_run_count(), 0);
+ EXPECT_GT(test_case->total_test_count(), 0);
+ EXPECT_TRUE(test_case->Passed());
+ EXPECT_FALSE(test_case->Failed());
+ EXPECT_GE(test_case->elapsed_time(), 0);
+ EXPECT_TRUE(test_case->GetTestInfo(0) != NULL);
+
+ // TestInfo API.
+ const TestInfo* const test_info = unit_test->current_test_info();
+
+ EXPECT_STRNE("", test_info->test_case_name());
+ EXPECT_STRNE("", test_info->name());
+ EXPECT_STREQ(test_case_comment, test_info->test_case_comment());
+ const char* const comment = test_info->comment();
+ EXPECT_TRUE(comment == NULL || strlen(comment) >= 0);
+ EXPECT_TRUE(test_info->should_run());
+ EXPECT_TRUE(test_info->result() != NULL);
+
+ // TestResult API.
+ const TestResult* const test_result = test_info->result();
+
+ SUCCEED() << "This generates a successful test part instance for API testing";
+ RecordProperty("Test Name", "Test Value");
+ EXPECT_EQ(1, test_result->total_part_count());
+ EXPECT_EQ(1, test_result->test_property_count());
+ EXPECT_TRUE(test_result->Passed());
+ EXPECT_FALSE(test_result->Failed());
+ EXPECT_FALSE(test_result->HasFatalFailure());
+ EXPECT_FALSE(test_result->HasNonfatalFailure());
+ EXPECT_GE(test_result->elapsed_time(), 0);
+ const TestPartResult& test_part_result = test_result->GetTestPartResult(0);
+ const TestProperty& test_property = test_result->GetTestProperty(0);
+
+ // TestPartResult API.
+ EXPECT_EQ(TestPartResult::kSuccess, test_part_result.type());
+ EXPECT_STRNE("", test_part_result.file_name());
+ EXPECT_GT(test_part_result.line_number(), 0);
+ EXPECT_STRNE("", test_part_result.summary());
+ EXPECT_STRNE("", test_part_result.message());
+ EXPECT_TRUE(test_part_result.passed());
+ EXPECT_FALSE(test_part_result.failed());
+ EXPECT_FALSE(test_part_result.nonfatally_failed());
+ EXPECT_FALSE(test_part_result.fatally_failed());
+
+ // TestProperty API.
+ EXPECT_STREQ("Test Name", test_property.key());
+ EXPECT_STREQ("Test Value", test_property.value());
+}
+
+// Tests linking of the event listener API.
+class MyListener : public TestEventListener {
+ virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+ virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
+ int /*iteration*/) {}
+ virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
+ virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+ virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
+ virtual void OnTestStart(const TestInfo& /*test_info*/) {}
+ virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
+ virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
+ virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
+ virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
+ virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+ virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+ int /*iteration*/) {}
+ virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+};
+
+class MyOtherListener : public EmptyTestEventListener {};
+
+int main(int argc, char **argv) {
+ testing::InitGoogleTest(&argc, argv);
+
+ TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
+ TestEventListener* listener = new MyListener;
+
+ listeners.Append(listener);
+ listeners.Release(listener);
+ listeners.Append(new MyOtherListener);
+ listener = listeners.default_result_printer();
+ listener = listeners.default_xml_generator();
+
+ RUN_ALL_TESTS();
+ return 0;
+}