From c78ae6196dc9c24380b5cf86f8fd75a4d3edc704 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 28 Apr 2009 00:28:09 +0000 Subject: [PATCH] Ports gtest to C++Builder, by Josh Kelley. --- Makefile.am | 9 + codegear/gtest.cbproj | 138 +++++++ codegear/gtest.groupproj | 54 +++ codegear/gtest_all.cc | 38 ++ codegear/gtest_link.cc | 40 +++ codegear/gtest_main.cbproj | 82 +++++ codegear/gtest_unittest.cbproj | 88 +++++ include/gtest/internal/gtest-internal.h | 28 +- include/gtest/internal/gtest-port.h | 30 +- src/gtest-filepath.cc | 25 +- src/gtest-port.cc | 4 +- src/gtest.cc | 21 +- test/gtest_unittest.cc | 456 +++++++++++++++--------- 13 files changed, 810 insertions(+), 203 deletions(-) create mode 100644 codegear/gtest.cbproj create mode 100644 codegear/gtest.groupproj create mode 100644 codegear/gtest_all.cc create mode 100644 codegear/gtest_link.cc create mode 100644 codegear/gtest_main.cbproj create mode 100644 codegear/gtest_unittest.cbproj diff --git a/Makefile.am b/Makefile.am index c83fb70b..b030cd83 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,6 +51,15 @@ EXTRA_DIST += \ xcode/Samples/FrameworkSample/widget.h \ xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj +# C++Builder project files +EXTRA_DIST += \ + codegear/gtest_all.cc \ + codegear/gtest_link.cc \ + codegear/gtest.cbproj \ + codegear/gtest_main.cbproj \ + codegear/gtest_unittest.cbproj \ + codegear/gtest.groupproj + # TODO(wan@google.com): integrate scripts/gen_gtest_pred_impl.py into # the build system such that a user can specify the maximum predicate # arity here and have the script automatically generate the diff --git a/codegear/gtest.cbproj b/codegear/gtest.cbproj new file mode 100644 index 00000000..95c3054b --- /dev/null +++ b/codegear/gtest.cbproj @@ -0,0 +1,138 @@ + + + + {bca37a72-5b07-46cf-b44e-89f8e06451a2} + Release + + + true + + + true + true + Base + + + true + true + Base + + + true + lib + JPHNE + NO_STRICT + true + true + CppStaticLibrary + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. + rtl.lib;vcl.lib + 32 + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppStaticLibrary + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + + + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 + + + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + 0 + + + 1 + + + 2 + + + 9 + + + 10 + + + 11 + + + 12 + + + 14 + + + 13 + + + 15 + + + 16 + + + 17 + + + 18 + + + Cfg_1 + + + Cfg_2 + + + \ No newline at end of file diff --git a/codegear/gtest.groupproj b/codegear/gtest.groupproj new file mode 100644 index 00000000..8b650f85 --- /dev/null +++ b/codegear/gtest.groupproj @@ -0,0 +1,54 @@ + + + {c1d923e0-6cba-4332-9b6f-3420acbf5091} + + + + + + + + + Default.Personality + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/codegear/gtest_all.cc b/codegear/gtest_all.cc new file mode 100644 index 00000000..121b2d80 --- /dev/null +++ b/codegear/gtest_all.cc @@ -0,0 +1,38 @@ +// 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: Josh Kelley (joshkel@gmail.com) +// +// Google C++ Testing Framework (Google Test) +// +// C++Builder's IDE cannot build a static library from files with hyphens +// in their name. See http://qc.codegear.com/wc/qcmain.aspx?d=70977 . +// This file serves as a workaround. + +#include "src/gtest-all.cc" diff --git a/codegear/gtest_link.cc b/codegear/gtest_link.cc new file mode 100644 index 00000000..918eccd1 --- /dev/null +++ b/codegear/gtest_link.cc @@ -0,0 +1,40 @@ +// 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: Josh Kelley (joshkel@gmail.com) +// +// Google C++ Testing Framework (Google Test) +// +// Links gtest.lib and gtest_main.lib into the current project in C++Builder. +// This means that these libraries can't be renamed, but it's the only way to +// ensure that Debug versus Release test builds are linked against the +// appropriate Debug or Release build of the libraries. + +#pragma link "gtest.lib" +#pragma link "gtest_main.lib" diff --git a/codegear/gtest_main.cbproj b/codegear/gtest_main.cbproj new file mode 100644 index 00000000..d76ce139 --- /dev/null +++ b/codegear/gtest_main.cbproj @@ -0,0 +1,82 @@ + + + + {bca37a72-5b07-46cf-b44e-89f8e06451a2} + Release + + + true + + + true + true + Base + + + true + true + Base + + + true + lib + JPHNE + NO_STRICT + true + true + CppStaticLibrary + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. + rtl.lib;vcl.lib + 32 + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppStaticLibrary + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 + + + + + 0 + + + Cfg_1 + + + Cfg_2 + + + diff --git a/codegear/gtest_unittest.cbproj b/codegear/gtest_unittest.cbproj new file mode 100644 index 00000000..d3823c90 --- /dev/null +++ b/codegear/gtest_unittest.cbproj @@ -0,0 +1,88 @@ + + + + {eea63393-5ac5-4b9c-8909-d75fef2daa41} + Release + + + true + + + true + true + Base + + + true + true + Base + + + true + exe + JPHNE + NO_STRICT + true + true + ..\test + true + CppConsoleApplication + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;.. + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test + true + + + false + false + _DEBUG;$(Defines) + true + true + false + true + None + DEBUG + true + Debug + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + true + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppConsoleApplication + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + + + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;$(OUTPUTDIR);..\test2NO_STRICTSTRICT + + + + + 0 + + + 1 + + + Cfg_1 + + + Cfg_2 + + + \ No newline at end of file diff --git a/include/gtest/internal/gtest-internal.h b/include/gtest/internal/gtest-internal.h index f61d502f..d596b3a6 100644 --- a/include/gtest/internal/gtest-internal.h +++ b/include/gtest/internal/gtest-internal.h @@ -383,7 +383,7 @@ class FloatingPoint { // around may change its bits, although the new value is guaranteed // to be also a NAN. Therefore, don't expect this constructor to // preserve the bits in x when x is a NAN. - explicit FloatingPoint(const RawType& x) : value_(x) {} + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } // Static methods @@ -392,8 +392,8 @@ class FloatingPoint { // This function is needed to test the AlmostEquals() method. static RawType ReinterpretBits(const Bits bits) { FloatingPoint fp(0); - fp.bits_ = bits; - return fp.value_; + fp.u_.bits_ = bits; + return fp.u_.value_; } // Returns the floating-point number that represent positive infinity. @@ -404,16 +404,16 @@ class FloatingPoint { // Non-static methods // Returns the bits that represents this number. - const Bits &bits() const { return bits_; } + const Bits &bits() const { return u_.bits_; } // Returns the exponent bits of this number. - Bits exponent_bits() const { return kExponentBitMask & bits_; } + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } // Returns the fraction bits of this number. - Bits fraction_bits() const { return kFractionBitMask & bits_; } + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } // Returns the sign bit of this number. - Bits sign_bit() const { return kSignBitMask & bits_; } + Bits sign_bit() const { return kSignBitMask & u_.bits_; } // Returns true iff this is NAN (not a number). bool is_nan() const { @@ -433,10 +433,17 @@ class FloatingPoint { // a NAN must return false. if (is_nan() || rhs.is_nan()) return false; - return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps; + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; } private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + // Converts an integer from the sign-and-magnitude representation to // the biased representation. More precisely, let N be 2 to the // power of (kBitCount - 1), an integer x is represented by the @@ -471,10 +478,7 @@ class FloatingPoint { return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); } - union { - RawType value_; // The raw floating-point number. - Bits bits_; // The bits that represent the number. - }; + FloatingPointUnion u_; }; // Typedefs the instances of the FloatingPoint template class that we diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h index 3e178fac..a82eec82 100644 --- a/include/gtest/internal/gtest-port.h +++ b/include/gtest/internal/gtest-port.h @@ -220,13 +220,15 @@ // Defines GTEST_HAS_EXCEPTIONS to 1 if exceptions are enabled, or 0 // otherwise. -#ifdef _MSC_VER // Compiled by MSVC? +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. -#ifndef _HAS_EXCEPTIONS // MSVC uses this macro to enable exceptions. +#ifndef _HAS_EXCEPTIONS #define _HAS_EXCEPTIONS 1 #endif // _HAS_EXCEPTIONS #define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS -#else // The compiler is not MSVC. +#else // The compiler is not MSVC or C++Builder. // gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. For // other compilers, we assume exceptions are disabled to be // conservative. @@ -235,7 +237,7 @@ #else #define GTEST_HAS_EXCEPTIONS 0 #endif // defined(__GNUC__) && __EXCEPTIONS -#endif // _MSC_VER +#endif // defined(_MSC_VER) || defined(__BORLANDC__) // Determines whether ::std::string and ::string are available. @@ -756,13 +758,22 @@ namespace posix { typedef struct _stat StatStruct; -inline int FileNo(FILE* file) { return _fileno(file); } +#ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +#else inline int IsATTY(int fd) { return _isatty(fd); } -inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); } inline char* StrDup(const char* src) { return _strdup(src); } +#endif // __BORLANDC__ + +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int RmDir(const char* dir) { return _rmdir(dir); } inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; @@ -778,7 +789,7 @@ inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); } -inline char* StrDup(const char* src) { return ::strdup(src); } +inline char* StrDup(const char* src) { return strdup(src); } inline int RmDir(const char* dir) { return rmdir(dir); } inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } @@ -815,6 +826,11 @@ inline const char* StrError(int errnum) { return strerror(errnum); } inline const char* GetEnv(const char* name) { #ifdef _WIN32_WCE // We are on Windows CE, which has no environment variables. return NULL; +#elif defined(__BORLANDC__) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; #else return getenv(name); #endif diff --git a/src/gtest-filepath.cc b/src/gtest-filepath.cc index 3180d0d5..f966352b 100644 --- a/src/gtest-filepath.cc +++ b/src/gtest-filepath.cc @@ -88,10 +88,10 @@ FilePath FilePath::GetCurrentDir() { // something reasonable. return FilePath(kCurrentDirectoryString); #elif GTEST_OS_WINDOWS - char cwd[GTEST_PATH_MAX_ + 1] = {}; + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else - char cwd[GTEST_PATH_MAX_ + 1] = {}; + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #endif } @@ -127,8 +127,13 @@ FilePath FilePath::RemoveDirectoryName() const { // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveFileName() const { const char* const last_sep = strrchr(c_str(), kPathSeparator); - return FilePath(last_sep ? String(c_str(), last_sep + 1 - c_str()) - : String(kCurrentDirectoryString)); + String dir; + if (last_sep) { + dir = String(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); } // Helper functions for naming files in a directory for xml output. @@ -141,11 +146,13 @@ FilePath FilePath::MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension) { - const FilePath file_name( - (number == 0) ? - String::Format("%s.%s", base_name.c_str(), extension) : - String::Format("%s_%d.%s", base_name.c_str(), number, extension)); - return ConcatPaths(directory, file_name); + String file; + if (number == 0) { + file = String::Format("%s.%s", base_name.c_str(), extension); + } else { + file = String::Format("%s_%d.%s", base_name.c_str(), number, extension); + } + return ConcatPaths(directory, FilePath(file)); } // Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". diff --git a/src/gtest-port.cc b/src/gtest-port.cc index e5c793f8..7f6db79f 100644 --- a/src/gtest-port.cc +++ b/src/gtest-port.cc @@ -68,8 +68,8 @@ namespace testing { namespace internal { -#ifdef _MSC_VER -// MSVC does not provide a definition of STDERR_FILENO. +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. const int kStdErrFileno = 2; #else const int kStdErrFileno = STDERR_FILENO; diff --git a/src/gtest.cc b/src/gtest.cc index a7118055..48807671 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -735,10 +735,11 @@ String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { } static TimeInMillis GetTimeInMillis() { -#ifdef _WIN32_WCE // We are on Windows CE +#if defined(_WIN32_WCE) || defined(__BORLANDC__) // Difference between 1970-01-01 and 1601-01-01 in miliseconds. // http://analogous.blogspot.com/2005/04/epoch.html - const TimeInMillis kJavaEpochToWinFileTimeDelta = 11644473600000UL; + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; const DWORD kTenthMicrosInMilliSecond = 10000; SYSTEMTIME now_systime; @@ -3221,13 +3222,18 @@ UnitTest * UnitTest::GetInstance() { // different implementation in this case to bypass the compiler bug. // This implementation makes the compiler happy, at the cost of // leaking the UnitTest object. -#if _MSC_VER == 1310 && !defined(_DEBUG) // MSVC 7.1 and optimized build. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) static UnitTest* const instance = new UnitTest; return instance; #else static UnitTest instance; return &instance; -#endif // _MSC_VER==1310 && !defined(_DEBUG) +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) } // Registers and returns a global test environment. When a test @@ -3259,7 +3265,7 @@ Environment* UnitTest::AddEnvironment(Environment* env) { class GoogleTestFailureException : public ::std::runtime_error { public: explicit GoogleTestFailureException(const TestPartResult& failure) - : runtime_error(PrintTestPartResultToString(failure).c_str()) {} + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} }; #endif @@ -3350,17 +3356,20 @@ int UnitTest::Run() { SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); #endif // _WIN32_WCE +#if defined(_MSC_VER) || defined(__MINGW32__) // Death test children can be terminated with _abort(). On Windows, // _abort() can show a dialog with a warning message. This forces the // abort message to go to stderr instead. _set_error_mode(_OUT_TO_STDERR); +#endif +#if _MSC_VER >= 1400 // In the debug version, Visual Studio pops up a separate dialog // offering a choice to debug the aborted program. We need to suppress // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement // executed. Google Test will notify the user of any unexpected // failure via stderr. -#if _MSC_VER >= 1400 + // // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. // Users of prior VC versions shall suffer the agony and pain of // clicking through the countless debug dialogs. diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 0786725b..8becca15 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -65,6 +65,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #undef GTEST_IMPLEMENTATION_ #include +#include #if GTEST_HAS_PTHREAD #include @@ -79,6 +80,10 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #endif // GTEST_OS_LINUX +#ifdef __BORLANDC__ +#include +#endif + namespace testing { namespace internal { const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); @@ -207,16 +212,26 @@ TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { #if !GTEST_OS_SYMBIAN // NULL testing does not work with Symbian compilers. +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +#pragma option push -w-ccc -w-rch +#endif + // Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null // pointer literal. TEST(NullLiteralTest, IsTrueForNullLiterals) { EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(NULL)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(false)); +#ifndef __BORLANDC__ + // Some compilers may fail to detect some null pointer literals; + // as long as users of the framework don't use such literals, this + // is harmless. + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(true && false)); +#endif } // Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null @@ -228,6 +243,11 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) { EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast(NULL))); } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + #endif // !GTEST_OS_SYMBIAN // // Tests CodePointToUtf8(). @@ -681,13 +701,18 @@ TEST(StringTest, EndsWithCaseInsensitive) { EXPECT_FALSE(String("").EndsWithCaseInsensitive("foo")); } +// C++Builder's preprocessor is buggy; it fails to expand macros that +// appear in macro parameters after wide char literals. Provide an alias +// for NULL as a workaround. +static const wchar_t* const kNull = NULL; + // Tests String::CaseInsensitiveWideCStringEquals TEST(StringTest, CaseInsensitiveWideCStringEquals) { EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(NULL, NULL)); - EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(NULL, L"")); - EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", NULL)); - EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(NULL, L"foobar")); - EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", NULL)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", kNull)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"foobar")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", kNull)); EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar")); EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR")); EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); @@ -790,6 +815,17 @@ TEST(TestPropertyTest, ReplaceStringValue) { EXPECT_STREQ("2", property.value()); } +// AddFatalFailure() and AddNonfatalFailure() must be stand-alone +// functions (i.e. their definitions cannot be inlined at the call +// sites), or C++Builder won't compile the code. +static void AddFatalFailure() { + FAIL() << "Expected fatal failure."; +} + +static void AddNonfatalFailure() { + ADD_FAILURE() << "Expected non-fatal failure."; +} + class ScopedFakeTestPartResultReporterTest : public Test { protected: enum FailureMode { @@ -798,9 +834,9 @@ class ScopedFakeTestPartResultReporterTest : public Test { }; static void AddFailure(FailureMode failure) { if (failure == FATAL_FAILURE) { - FAIL() << "Expected fatal failure."; + AddFatalFailure(); } else { - ADD_FAILURE() << "Expected non-fatal failure."; + AddNonfatalFailure(); } } }; @@ -875,21 +911,28 @@ TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, #endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD -// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. +// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they +// work even if the failure is generated in a called function rather than +// the current context. typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest; TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { - EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); + EXPECT_FATAL_FAILURE(AddFatalFailure(), "Expected fatal failure."); } TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { // We have another test below to verify that the macro catches fatal // failures generated on another thread. - EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFatalFailure(), "Expected fatal failure."); } +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true" +#pragma option push -w-ccc +#endif + // Tests that EXPECT_FATAL_FAILURE() can be used in a non-void // function even when the statement in it contains ASSERT_*. @@ -913,6 +956,11 @@ void DoesNotAbortHelper(bool* aborted) { *aborted = false; } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + TEST_F(ExpectFatalFailureTest, DoesNotAbort) { bool aborted = true; DoesNotAbortHelper(&aborted); @@ -927,14 +975,17 @@ static int global_var = 0; #define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { +#ifndef __BORLANDC__ + // ICE's in C++Builder 2007. EXPECT_FATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; - AddFailure(FATAL_FAILURE); + AddFatalFailure(); }, ""); +#endif EXPECT_FATAL_FAILURE_ON_ALL_THREADS({ GTEST_USE_UNPROTECTED_COMMA_; - AddFailure(FATAL_FAILURE); + AddFatalFailure(); }, ""); } @@ -943,14 +994,14 @@ TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest; TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { - EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), "Expected non-fatal failure."); } TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { // We have another test below to verify that the macro catches // non-fatal failures generated on another thread. - EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddNonfatalFailure(), "Expected non-fatal failure."); } @@ -960,12 +1011,12 @@ TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { EXPECT_NONFATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; - AddFailure(NONFATAL_FAILURE); + AddNonfatalFailure(); }, ""); EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS({ GTEST_USE_UNPROTECTED_COMMA_; - AddFailure(NONFATAL_FAILURE); + AddNonfatalFailure(); }, ""); } @@ -1271,6 +1322,22 @@ static void SetEnv(const char* name, const char* value) { #ifdef _WIN32_WCE // Environment variables are not supported on Windows CE. return; +#elif defined(__BORLANDC__) + // C++Builder's putenv only stores a pointer to its parameter; we have to + // ensure that the string remains valid as long as it might be needed. + // We use an std::map to do so. + static std::map added_env; + + // Because putenv stores a pointer to the string buffer, we can't delete the + // previous string (if present) until after it's replaced. + String *prev_env = NULL; + if (added_env.find(name) != added_env.end()) { + prev_env = added_env[name]; + } + added_env[name] = new String((Message() << name << "=" << value).GetString()); + putenv(added_env[name]->c_str()); + delete prev_env; + #elif GTEST_OS_WINDOWS // If we are on Windows proper. _putenv((Message() << name << "=" << value).GetString().c_str()); #else @@ -1380,7 +1447,8 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value)); EXPECT_EQ(456, value); - EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", "abc", &value)); + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", + "abc", &value)); EXPECT_EQ(-789, value); } @@ -1802,8 +1870,9 @@ bool GreaterThan(T1 x1, T2 x2) { // Tests that overloaded functions can be used in *_PRED* as long as // their types are explicitly specified. TEST(PredicateAssertionTest, AcceptsOverloadedFunction) { - EXPECT_PRED1(static_cast(IsPositive), 5); // NOLINT - ASSERT_PRED1(static_cast(IsPositive), 6.0); // NOLINT + // C++Builder requires C-style casts rather than static_cast. + EXPECT_PRED1((bool (*)(int))(IsPositive), 5); // NOLINT + ASSERT_PRED1((bool (*)(double))(IsPositive), 6.0); // NOLINT } // Tests that template functions can be used in *_PRED* as long as @@ -1987,8 +2056,8 @@ TEST(IsSubstringTest, ReturnsCorrectResultForCString) { // Tests that IsSubstring() returns the correct result when the input // argument type is const wchar_t*. TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) { - EXPECT_FALSE(IsSubstring("", "", NULL, L"a")); - EXPECT_FALSE(IsSubstring("", "", L"b", NULL)); + EXPECT_FALSE(IsSubstring("", "", kNull, L"a")); + EXPECT_FALSE(IsSubstring("", "", L"b", kNull)); EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack")); EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); @@ -2107,6 +2176,24 @@ TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { template class FloatingPointTest : public Test { protected: + + // Pre-calculated numbers to be used by the tests. + struct TestValues { + RawType close_to_positive_zero; + RawType close_to_negative_zero; + RawType further_from_negative_zero; + + RawType close_to_one; + RawType further_from_one; + + RawType infinity; + RawType close_to_infinity; + RawType further_from_infinity; + + RawType nan1; + RawType nan2; + }; + typedef typename testing::internal::FloatingPoint Floating; typedef typename Floating::Bits Bits; @@ -2117,85 +2204,52 @@ class FloatingPointTest : public Test { const Bits zero_bits = Floating(0).bits(); // Makes some numbers close to 0.0. - close_to_positive_zero_ = Floating::ReinterpretBits(zero_bits + max_ulps/2); - close_to_negative_zero_ = -Floating::ReinterpretBits( + values_.close_to_positive_zero = Floating::ReinterpretBits( + zero_bits + max_ulps/2); + values_.close_to_negative_zero = -Floating::ReinterpretBits( zero_bits + max_ulps - max_ulps/2); - further_from_negative_zero_ = -Floating::ReinterpretBits( + values_.further_from_negative_zero = -Floating::ReinterpretBits( zero_bits + max_ulps + 1 - max_ulps/2); // The bits that represent 1.0. const Bits one_bits = Floating(1).bits(); // Makes some numbers close to 1.0. - close_to_one_ = Floating::ReinterpretBits(one_bits + max_ulps); - further_from_one_ = Floating::ReinterpretBits(one_bits + max_ulps + 1); + values_.close_to_one = Floating::ReinterpretBits(one_bits + max_ulps); + values_.further_from_one = Floating::ReinterpretBits( + one_bits + max_ulps + 1); // +infinity. - infinity_ = Floating::Infinity(); + values_.infinity = Floating::Infinity(); // The bits that represent +infinity. - const Bits infinity_bits = Floating(infinity_).bits(); + const Bits infinity_bits = Floating(values_.infinity).bits(); // Makes some numbers close to infinity. - close_to_infinity_ = Floating::ReinterpretBits(infinity_bits - max_ulps); - further_from_infinity_ = Floating::ReinterpretBits( + values_.close_to_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps); + values_.further_from_infinity = Floating::ReinterpretBits( infinity_bits - max_ulps - 1); - // Makes some NAN's. - nan1_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 1); - nan2_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 200); + // Makes some NAN's. Sets the most significant bit of the fraction so that + // our NaN's are quiet; trying to process a signaling NaN would raise an + // exception if our environment enables floating point exceptions. + values_.nan1 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 1); + values_.nan2 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 200); } void TestSize() { EXPECT_EQ(sizeof(RawType), sizeof(Bits)); } - // Pre-calculated numbers to be used by the tests. - - static RawType close_to_positive_zero_; - static RawType close_to_negative_zero_; - static RawType further_from_negative_zero_; - - static RawType close_to_one_; - static RawType further_from_one_; - - static RawType infinity_; - static RawType close_to_infinity_; - static RawType further_from_infinity_; - - static RawType nan1_; - static RawType nan2_; + static TestValues values_; }; template -RawType FloatingPointTest::close_to_positive_zero_; - -template -RawType FloatingPointTest::close_to_negative_zero_; - -template -RawType FloatingPointTest::further_from_negative_zero_; - -template -RawType FloatingPointTest::close_to_one_; - -template -RawType FloatingPointTest::further_from_one_; - -template -RawType FloatingPointTest::infinity_; - -template -RawType FloatingPointTest::close_to_infinity_; - -template -RawType FloatingPointTest::further_from_infinity_; - -template -RawType FloatingPointTest::nan1_; - -template -RawType FloatingPointTest::nan2_; +typename FloatingPointTest::TestValues + FloatingPointTest::values_; // Instantiates FloatingPointTest for testing *_FLOAT_EQ. typedef FloatingPointTest FloatTest; @@ -2220,20 +2274,26 @@ TEST_F(FloatTest, Zeros) { // overflow occurs when comparing numbers whose absolute value is very // small. TEST_F(FloatTest, AlmostZeros) { - EXPECT_FLOAT_EQ(0.0, close_to_positive_zero_); - EXPECT_FLOAT_EQ(-0.0, close_to_negative_zero_); - EXPECT_FLOAT_EQ(close_to_positive_zero_, close_to_negative_zero_); + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + static const FloatTest::TestValues& v(this->values_); + + EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero); + EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero); + EXPECT_FLOAT_EQ(v.close_to_positive_zero, v.close_to_negative_zero); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_FLOAT_EQ(close_to_positive_zero_, further_from_negative_zero_); - }, "further_from_negative_zero_"); + ASSERT_FLOAT_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); } // Tests comparing numbers close to each other. TEST_F(FloatTest, SmallDiff) { - EXPECT_FLOAT_EQ(1.0, close_to_one_); - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, further_from_one_), - "further_from_one_"); + EXPECT_FLOAT_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); } // Tests comparing numbers far apart. @@ -2247,17 +2307,17 @@ TEST_F(FloatTest, LargeDiff) { // This ensures that no overflow occurs when comparing numbers whose // absolute value is very large. TEST_F(FloatTest, Infinity) { - EXPECT_FLOAT_EQ(infinity_, close_to_infinity_); - EXPECT_FLOAT_EQ(-infinity_, -close_to_infinity_); + EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity); #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, -infinity_), - "-infinity_"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); - // This is interesting as the representations of infinity_ and nan1_ + // This is interesting as the representations of infinity and nan1 // are only 1 DLP apart. - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, nan1_), - "nan1_"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, values_.nan1), + "values_.nan1"); #endif // !GTEST_OS_SYMBIAN } @@ -2265,15 +2325,21 @@ TEST_F(FloatTest, Infinity) { TEST_F(FloatTest, NaN) { #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(nan1_, nan1_), - "nan1_"); - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(nan1_, nan2_), - "nan2_"); - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, nan1_), - "nan1_"); - EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(nan1_, infinity_), - "infinity_"); + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + static const FloatTest::TestValues& v(this->values_); + + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2), + "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1), + "v.nan1"); + + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity), + "v.infinity"); #endif // !GTEST_OS_SYMBIAN } @@ -2281,16 +2347,16 @@ TEST_F(FloatTest, NaN) { TEST_F(FloatTest, Reflexive) { EXPECT_FLOAT_EQ(0.0, 0.0); EXPECT_FLOAT_EQ(1.0, 1.0); - ASSERT_FLOAT_EQ(infinity_, infinity_); + ASSERT_FLOAT_EQ(values_.infinity, values_.infinity); } // Tests that *_FLOAT_EQ are commutative. TEST_F(FloatTest, Commutative) { - // We already tested EXPECT_FLOAT_EQ(1.0, close_to_one_). - EXPECT_FLOAT_EQ(close_to_one_, 1.0); + // We already tested EXPECT_FLOAT_EQ(1.0, values_.close_to_one). + EXPECT_FLOAT_EQ(values_.close_to_one, 1.0); - // We already tested EXPECT_FLOAT_EQ(1.0, further_from_one_). - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(further_from_one_, 1.0), + // We already tested EXPECT_FLOAT_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.further_from_one, 1.0), "1.0"); } @@ -2322,7 +2388,7 @@ TEST_F(FloatTest, FloatLESucceeds) { ASSERT_PRED_FORMAT2(FloatLE, 1.0f, 1.0f); // val1 == val2, // or when val1 is greater than, but almost equals to, val2. - EXPECT_PRED_FORMAT2(FloatLE, close_to_positive_zero_, 0.0f); + EXPECT_PRED_FORMAT2(FloatLE, values_.close_to_positive_zero, 0.0f); } // Tests the cases where FloatLE() should fail. @@ -2333,23 +2399,23 @@ TEST_F(FloatTest, FloatLEFails) { // or by a small yet non-negligible margin, EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(FloatLE, further_from_one_, 1.0f); - }, "(further_from_one_) <= (1.0f)"); + EXPECT_PRED_FORMAT2(FloatLE, values_.further_from_one, 1.0f); + }, "(values_.further_from_one) <= (1.0f)"); -#if !GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) // Nokia's STLport crashes if we try to output infinity or NaN. - // or when either val1 or val2 is NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(FloatLE, nan1_, infinity_); - }, "(nan1_) <= (infinity_)"); + EXPECT_PRED_FORMAT2(FloatLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(FloatLE, -infinity_, nan1_); - }, "(-infinity_) <= (nan1_)"); - + EXPECT_PRED_FORMAT2(FloatLE, -values_.infinity, values_.nan1); + }, "(-values_.infinity) <= (values_.nan1)"); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_PRED_FORMAT2(FloatLE, nan1_, nan1_); - }, "(nan1_) <= (nan1_)"); -#endif // !GTEST_OS_SYMBIAN + ASSERT_PRED_FORMAT2(FloatLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) } // Instantiates FloatingPointTest for testing *_DOUBLE_EQ. @@ -2375,20 +2441,26 @@ TEST_F(DoubleTest, Zeros) { // overflow occurs when comparing numbers whose absolute value is very // small. TEST_F(DoubleTest, AlmostZeros) { - EXPECT_DOUBLE_EQ(0.0, close_to_positive_zero_); - EXPECT_DOUBLE_EQ(-0.0, close_to_negative_zero_); - EXPECT_DOUBLE_EQ(close_to_positive_zero_, close_to_negative_zero_); + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + static const DoubleTest::TestValues& v(this->values_); + + EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero); + EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero); + EXPECT_DOUBLE_EQ(v.close_to_positive_zero, v.close_to_negative_zero); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_DOUBLE_EQ(close_to_positive_zero_, further_from_negative_zero_); - }, "further_from_negative_zero_"); + ASSERT_DOUBLE_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); } // Tests comparing numbers close to each other. TEST_F(DoubleTest, SmallDiff) { - EXPECT_DOUBLE_EQ(1.0, close_to_one_); - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, further_from_one_), - "further_from_one_"); + EXPECT_DOUBLE_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); } // Tests comparing numbers far apart. @@ -2402,29 +2474,35 @@ TEST_F(DoubleTest, LargeDiff) { // This ensures that no overflow occurs when comparing numbers whose // absolute value is very large. TEST_F(DoubleTest, Infinity) { - EXPECT_DOUBLE_EQ(infinity_, close_to_infinity_); - EXPECT_DOUBLE_EQ(-infinity_, -close_to_infinity_); + EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity); #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, -infinity_), - "-infinity_"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); // This is interesting as the representations of infinity_ and nan1_ // are only 1 DLP apart. - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, nan1_), - "nan1_"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, values_.nan1), + "values_.nan1"); #endif // !GTEST_OS_SYMBIAN } // Tests that comparing with NAN always returns false. TEST_F(DoubleTest, NaN) { #if !GTEST_OS_SYMBIAN + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + static const DoubleTest::TestValues& v(this->values_); + // Nokia's STLport crashes if we try to output infinity or NaN. - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan1_), - "nan1_"); - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan2_), "nan2_"); - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, nan1_), "nan1_"); - EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(nan1_, infinity_), "infinity_"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity), + "v.infinity"); #endif // !GTEST_OS_SYMBIAN } @@ -2434,17 +2512,18 @@ TEST_F(DoubleTest, Reflexive) { EXPECT_DOUBLE_EQ(1.0, 1.0); #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. - ASSERT_DOUBLE_EQ(infinity_, infinity_); + ASSERT_DOUBLE_EQ(values_.infinity, values_.infinity); #endif // !GTEST_OS_SYMBIAN } // Tests that *_DOUBLE_EQ are commutative. TEST_F(DoubleTest, Commutative) { - // We already tested EXPECT_DOUBLE_EQ(1.0, close_to_one_). - EXPECT_DOUBLE_EQ(close_to_one_, 1.0); + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.close_to_one). + EXPECT_DOUBLE_EQ(values_.close_to_one, 1.0); - // We already tested EXPECT_DOUBLE_EQ(1.0, further_from_one_). - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(further_from_one_, 1.0), "1.0"); + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.further_from_one, 1.0), + "1.0"); } // Tests EXPECT_NEAR. @@ -2475,7 +2554,7 @@ TEST_F(DoubleTest, DoubleLESucceeds) { ASSERT_PRED_FORMAT2(DoubleLE, 1.0, 1.0); // val1 == val2, // or when val1 is greater than, but almost equals to, val2. - EXPECT_PRED_FORMAT2(DoubleLE, close_to_positive_zero_, 0.0); + EXPECT_PRED_FORMAT2(DoubleLE, values_.close_to_positive_zero, 0.0); } // Tests the cases where DoubleLE() should fail. @@ -2486,22 +2565,23 @@ TEST_F(DoubleTest, DoubleLEFails) { // or by a small yet non-negligible margin, EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(DoubleLE, further_from_one_, 1.0); - }, "(further_from_one_) <= (1.0)"); + EXPECT_PRED_FORMAT2(DoubleLE, values_.further_from_one, 1.0); + }, "(values_.further_from_one) <= (1.0)"); -#if !GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) // Nokia's STLport crashes if we try to output infinity or NaN. - // or when either val1 or val2 is NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(DoubleLE, nan1_, infinity_); - }, "(nan1_) <= (infinity_)"); + EXPECT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(DoubleLE, -infinity_, nan1_); - }, " (-infinity_) <= (nan1_)"); + EXPECT_PRED_FORMAT2(DoubleLE, -values_.infinity, values_.nan1); + }, " (-values_.infinity) <= (values_.nan1)"); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_PRED_FORMAT2(DoubleLE, nan1_, nan1_); - }, "(nan1_) <= (nan1_)"); -#endif // !GTEST_OS_SYMBIAN + ASSERT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) } @@ -2621,6 +2701,20 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes); // Tests that assertion macros evaluate their arguments exactly once. class SingleEvaluationTest : public Test { + public: + // This helper function is needed by the FailedASSERT_STREQ test + // below. It's public to work around C++Builder's bug with scoping local + // classes. + static void CompareAndIncrementCharPtrs() { + ASSERT_STREQ(p1_++, p2_++); + } + + // This helper function is needed by the FailedASSERT_NE test below. It's + // public to work around C++Builder's bug with scoping local classes. + static void CompareAndIncrementInts() { + ASSERT_NE(a_++, b_++); + } + protected: SingleEvaluationTest() { p1_ = s1_; @@ -2629,17 +2723,6 @@ class SingleEvaluationTest : public Test { b_ = 0; } - // This helper function is needed by the FailedASSERT_STREQ test - // below. - static void CompareAndIncrementCharPtrs() { - ASSERT_STREQ(p1_++, p2_++); - } - - // This helper function is needed by the FailedASSERT_NE test below. - static void CompareAndIncrementInts() { - ASSERT_NE(a_++, b_++); - } - static const char* const s1_; static const char* const s2_; static const char* p1_; @@ -2659,7 +2742,7 @@ int SingleEvaluationTest::b_; // Tests that when ASSERT_STREQ fails, it evaluates its arguments // exactly once. TEST_F(SingleEvaluationTest, FailedASSERT_STREQ) { - EXPECT_FATAL_FAILURE(CompareAndIncrementCharPtrs(), + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementCharPtrs(), "p2_++"); EXPECT_EQ(s1_ + 1, p1_); EXPECT_EQ(s2_ + 1, p2_); @@ -2682,7 +2765,8 @@ TEST_F(SingleEvaluationTest, ASSERT_STR) { // Tests that when ASSERT_NE fails, it evaluates its arguments exactly // once. TEST_F(SingleEvaluationTest, FailedASSERT_NE) { - EXPECT_FATAL_FAILURE(CompareAndIncrementInts(), "(a_++) != (b_++)"); + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementInts(), + "(a_++) != (b_++)"); EXPECT_EQ(1, a_); EXPECT_EQ(1, b_); } @@ -2924,6 +3008,11 @@ TEST(AssertionTest, AppendUserMessage) { AppendUserMessage(foo, msg).c_str()); } +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +#pragma option push -w-ccc -w-rch +#endif + // Tests ASSERT_TRUE. TEST(AssertionTest, ASSERT_TRUE) { ASSERT_TRUE(2 > 1); // NOLINT @@ -2940,6 +3029,11 @@ TEST(AssertionTest, ASSERT_FALSE) { "Expected: false"); } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + // Tests using ASSERT_EQ on double values. The purpose is to make // sure that the specialization we did for integer and anonymous enums // isn't used for double arguments. @@ -3035,14 +3129,16 @@ TEST(AssertionTest, ASSERT_GT) { void ThrowNothing() {} - // Tests ASSERT_THROW. TEST(AssertionTest, ASSERT_THROW) { ASSERT_THROW(ThrowAnInteger(), int); +#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 || defined(_DEBUG) + // ICE's in C++Builder 2007 (Release build). EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowAnInteger(), bool), "Expected: ThrowAnInteger() throws an exception of type bool.\n" " Actual: it throws a different type."); +#endif EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowNothing(), bool), "Expected: ThrowNothing() throws an exception of type bool.\n" @@ -3248,9 +3344,12 @@ TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { ASSERT_HRESULT_FAILED(E_UNEXPECTED); +#ifndef __BORLANDC__ + // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), "Expected: (OkHRESULTSuccess()) fails.\n" " Actual: 0x00000000"); +#endif EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), "Expected: (FalseHRESULTSuccess()) fails.\n" " Actual: 0x00000001"); @@ -3267,9 +3366,12 @@ TEST(HRESULTAssertionTest, Streaming) { EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", "expected failure"); +#ifndef __BORLANDC__ + // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE( ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", "expected failure"); +#endif EXPECT_NONFATAL_FAILURE( EXPECT_HRESULT_FAILED(S_OK) << "expected failure", @@ -3282,6 +3384,11 @@ TEST(HRESULTAssertionTest, Streaming) { #endif // GTEST_OS_WINDOWS +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +#pragma option push -w-ccc -w-rch +#endif + // Tests that the assertion macros behave like single statements. TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { if (false) @@ -3476,6 +3583,11 @@ TEST(ExpectTest, EXPECT_FALSE) { "2 < 3"); } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + // Tests EXPECT_EQ. TEST(ExpectTest, EXPECT_EQ) { EXPECT_EQ(5, 2 + 3); @@ -5197,6 +5309,11 @@ TEST(StreamingAssertionsTest, Unconditional) { "expected failure"); } +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +#pragma option push -w-ccc -w-rch +#endif + TEST(StreamingAssertionsTest, Truth) { EXPECT_TRUE(true) << "unexpected failure"; ASSERT_TRUE(true) << "unexpected failure"; @@ -5215,6 +5332,11 @@ TEST(StreamingAssertionsTest, Truth2) { "expected failure"); } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + TEST(StreamingAssertionsTest, IntegerEquals) { EXPECT_EQ(1, 1) << "unexpected failure"; ASSERT_EQ(1, 1) << "unexpected failure";