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