1f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Copyright 2007, Google Inc. 2f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// All rights reserved. 3f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// 4f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Redistribution and use in source and binary forms, with or without 5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// modification, are permitted provided that the following conditions are 6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// met: 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// * Redistributions of source code must retain the above copyright 9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// notice, this list of conditions and the following disclaimer. 10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// * Redistributions in binary form must reproduce the above 11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// copyright notice, this list of conditions and the following disclaimer 12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// in the documentation and/or other materials provided with the 13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// distribution. 14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// * Neither the name of Google Inc. nor the names of its 15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// contributors may be used to endorse or promote products derived from 16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// this software without specific prior written permission. 17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// 18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// 30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Author: wan@google.com (Zhanyong Wan) 31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Google Mock - a framework for writing C++ mock classes. 33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// 34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// This file defines some utilities useful for implementing Google 35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Mock. They are subject to change without notice, so please DO NOT 36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// USE THEM IN USER CODE. 37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gmock/internal/gmock-internal-utils.h" 39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <ctype.h> 41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <ostream> // NOLINT 42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <string> 43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gmock/gmock.h" 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gmock/internal/gmock-port.h" 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gtest/gtest.h" 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace testing { 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace internal { 49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Converts an identifier name to a space-separated list of lower-case 51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is 52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// treated as one word. For example, both "FooBar123" and 53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// "foo_bar_123" are converted to "foo bar 123". 54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochGTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) { 55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch string result; 56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch char prev_char = '\0'; 57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { 58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // We don't care about the current locale as the input is 59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // guaranteed to be a valid C++ identifier name. 60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const bool starts_new_word = IsUpper(*p) || 61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (!IsAlpha(prev_char) && IsLower(*p)) || 62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (!IsDigit(prev_char) && IsDigit(*p)); 63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsAlNum(*p)) { 65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (starts_new_word && result != "") 66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch result += ' '; 67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch result += ToLower(*p); 68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return result; 71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// This class reports Google Mock failures as Google Test failures. A 74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// user can define another class in a similar fashion if he intends to 75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// use Google Mock with a testing framework other than Google Test. 76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass GoogleTestFailureReporter : public FailureReporterInterface { 77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public: 78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual void ReportFailure(FailureType type, const char* file, int line, 79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const string& message) { 80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AssertHelper(type == kFatal ? 81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TestPartResult::kFatalFailure : 82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TestPartResult::kNonFatalFailure, 83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch file, 84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch line, 85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch message.c_str()) = Message(); 86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (type == kFatal) { 87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch posix::Abort(); 88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Returns the global failure reporter. Will create a 93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// GoogleTestFailureReporter and return it the first time called. 94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochGTEST_API_ FailureReporterInterface* GetFailureReporter() { 95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Points to the global failure reporter used by Google Mock. gcc 96f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // guarantees that the following use of failure_reporter is 97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // thread-safe. We may need to add additional synchronization to 98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // protect failure_reporter if we port Google Mock to other 99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // compilers. 100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static FailureReporterInterface* const failure_reporter = 101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch new GoogleTestFailureReporter(); 102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return failure_reporter; 103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Protects global resources (stdout in particular) used by Log(). 106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstatic GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex); 107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Returns true iff a log with the given severity is visible according 109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// to the --gmock_verbose flag. 110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochGTEST_API_ bool LogIsVisible(LogSeverity severity) { 111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (GMOCK_FLAG(verbose) == kInfoVerbosity) { 112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Always show the log if --gmock_verbose=info. 113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (GMOCK_FLAG(verbose) == kErrorVerbosity) { 115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Always hide it if --gmock_verbose=error. 116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // If --gmock_verbose is neither "info" nor "error", we treat it 119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // as "warning" (its default value). 120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return severity == kWarning; 121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Prints the given message to stdout iff 'severity' >= the level 125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// specified by the --gmock_verbose flag. If stack_frames_to_skip >= 126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// 0, also prints the stack trace excluding the top 127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// stack_frames_to_skip frames. In opt mode, any positive 128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// stack_frames_to_skip is treated as 0, since we don't know which 129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// function calls will be inlined by the compiler and need to be 130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// conservative. 131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochGTEST_API_ void Log(LogSeverity severity, 132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const string& message, 133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int stack_frames_to_skip) { 134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!LogIsVisible(severity)) 135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Ensures that logs from different threads don't interleave. 138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MutexLock l(&g_log_mutex); 139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a 141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // macro. 142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (severity == kWarning) { 144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Prints a GMOCK WARNING marker to make the warnings easily searchable. 145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::cout << "\nGMOCK WARNING:"; 146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Pre-pends a new-line to message if it doesn't start with one. 148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (message.empty() || message[0] != '\n') { 149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::cout << "\n"; 150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::cout << message; 152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (stack_frames_to_skip >= 0) { 153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#ifdef NDEBUG 154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // In opt mode, we have to be conservative and skip no stack frame. 155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const int actual_to_skip = 0; 156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#else 157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // In dbg mode, we can do what the caller tell us to do (plus one 158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // for skipping this function's stack frame). 159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const int actual_to_skip = stack_frames_to_skip + 1; 160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#endif // NDEBUG 161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Appends a new-line to message if it doesn't end with one. 163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!message.empty() && *message.rbegin() != '\n') { 164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::cout << "\n"; 165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::cout << "Stack trace:\n" 167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch << ::testing::internal::GetCurrentOsStackTraceExceptTop( 168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ::testing::UnitTest::GetInstance(), actual_to_skip); 169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::cout << ::std::flush; 171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace internal 174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace testing 175