Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export Test - Do Not Merge #3055

Closed
wants to merge 11 commits into from
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ install:

# install Bazel
if ($env:build_system -eq "bazel") {
appveyor DownloadFile https://github.com/bazelbuild/bazel/releases/download/0.28.1/bazel-0.28.1-windows-x86_64.exe -FileName bazel.exe
appveyor DownloadFile https://github.com/bazelbuild/bazel/releases/download/3.6.0/bazel-3.6.0-windows-x86_64.exe -FileName bazel.exe
}

if ($env:build_system -eq "cmake") {
Expand Down
2 changes: 1 addition & 1 deletion googlemock/docs/cheat_sheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ which must be a permanent callback.
| :----------------------------------- | :------------------------------------ |
| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. |
| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a matcher `IsDivisibleBy(n)` to match a number divisible by `n`. |
| `MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. |
| `MATCHER_P2(IsBetween, a, b, absl::StrCat(negation ? "isn't" : "is", " between ", PrintToString(a), " and ", PrintToString(b))) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. |
<!-- mdformat on -->

**Notes:**
Expand Down
16 changes: 16 additions & 0 deletions googlemock/docs/cook_book.md
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,22 @@ using ::testing::Not;
NULL));
```

Matchers are function objects, and parametrized matchers can be composed just
like any other function. However because their types can be long and rarely
provide meaningful information, it can be easier to express them with C++14
generic lambdas to avoid specifying types. For example,

```cpp
using ::testing::Contains;
using ::testing::Property;

inline constexpr auto HasFoo = [](const auto& f) {
return Property(&MyClass::foo, Contains(f));
};
...
EXPECT_THAT(x, HasFoo("blah"));
```

### Casting Matchers {#SafeMatcherCast}

gMock matchers are statically typed, meaning that the compiler can catch your
Expand Down
2 changes: 1 addition & 1 deletion googlemock/docs/pump_manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Func(a1 + a2 + a3); // If n is 3.
We support the following meta programming constructs:

| `$var id = exp` | Defines a named constant value. `$id` is |
: : valid util the end of the current meta :
: : valid until the end of the current meta :
: : lexical block. :
| :------------------------------- | :--------------------------------------- |
| `$range id exp..exp` | Sets the range of an iteration variable, |
Expand Down
129 changes: 74 additions & 55 deletions googlemock/scripts/fuse_gmock_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
# 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.
"""fuse_gmock_files.py v0.1.0.

"""fuse_gmock_files.py v0.1.0
Fuses Google Mock and Google Test source code into two .h files and a .cc file.

SYNOPSIS
Expand All @@ -55,27 +55,31 @@
This tool is experimental. In particular, it assumes that there is no
conditional inclusion of Google Mock or Google Test headers. Please
report any problems to googlemock@googlegroups.com. You can read
https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md for more
https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md
for more
information.
"""

__author__ = 'wan@google.com (Zhanyong Wan)'
from __future__ import print_function

import os
import re
import sets
import sys

import fuse_gtest_files

__author__ = 'wan@google.com (Zhanyong Wan)'

# We assume that this file is in the scripts/ directory in the Google
# Mock root directory.
DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')

# We need to call into googletest/scripts/fuse_gtest_files.py.
sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, '../googletest/scripts'))
import fuse_gtest_files
gtest = fuse_gtest_files

# Regex for matching '#include "gmock/..."'.
# Regex for matching
# '#include "gmock/..."'.
INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')

# Where to find the source seed files.
Expand All @@ -98,6 +102,9 @@ def ValidateGMockRootDir(gmock_root):
"""Makes sure gmock_root points to a valid gmock root directory.

The function aborts the program on failure.

Args:
gmock_root: A string with the mock root directory.
"""

gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root))
Expand All @@ -109,6 +116,9 @@ def ValidateOutputDir(output_dir):
"""Makes sure output_dir points to a valid output directory.

The function aborts the program on failure.

Args:
output_dir: A string representing the output directory.
"""

gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT)
Expand All @@ -119,8 +129,8 @@ def ValidateOutputDir(output_dir):
def FuseGMockH(gmock_root, output_dir):
"""Scans folder gmock_root to generate gmock/gmock.h in output_dir."""

output_file = file(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
processed_files = sets.Set() # Holds all gmock headers we've processed.
output_file = open(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
processed_files = frozenset() # Holds all gmock headers we've processed.

def ProcessFile(gmock_header_path):
"""Processes the given gmock header file."""
Expand All @@ -132,25 +142,29 @@ def ProcessFile(gmock_header_path):
processed_files.add(gmock_header_path)

# Reads each line in the given gmock header.
for line in file(os.path.join(gmock_root, gmock_header_path), 'r'):
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
# It's '#include "gmock/..."' - let's process it recursively.
ProcessFile('include/' + m.group(1))
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)

with open(os.path.join(gmock_root, gmock_header_path), 'r') as fh:
for line in fh:
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
# It's '#include "gtest/foo.h"'. We translate it to
# "gtest/gtest.h", regardless of what foo is, since all
# gtest headers are fused into gtest/gtest.h.

# There is no need to #include gtest.h twice.
if not gtest.GTEST_H_SEED in processed_files:
processed_files.add(gtest.GTEST_H_SEED)
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
# '#include "gmock/..."'
# - let's process it recursively.
ProcessFile('include/' + m.group(1))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
# '#include "third_party/googletest/googletest/
# include/gtest/foo.h"'.
# We translate it to "gtest/gtest.h", regardless of what foo is,
# since all gtest headers are fused into gtest/gtest.h.

# There is no need to #include gtest.h twice.
if gtest.GTEST_H_SEED not in processed_files:
processed_files.add(gtest.GTEST_H_SEED)
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)

ProcessFile(GMOCK_H_SEED)
output_file.close()
Expand All @@ -159,7 +173,7 @@ def ProcessFile(gmock_header_path):
def FuseGMockAllCcToFile(gmock_root, output_file):
"""Scans folder gmock_root to fuse gmock-all.cc into output_file."""

processed_files = sets.Set()
processed_files = frozenset()

def ProcessFile(gmock_source_file):
"""Processes the given gmock source file."""
Expand All @@ -171,45 +185,50 @@ def ProcessFile(gmock_source_file):
processed_files.add(gmock_source_file)

# Reads each line in the given gmock source file.
for line in file(os.path.join(gmock_root, gmock_source_file), 'r'):
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
# It's '#include "gmock/foo.h"'. We treat it as '#include
# "gmock/gmock.h"', as all other gmock headers are being fused
# into gmock.h and cannot be #included directly.

# There is no need to #include "gmock/gmock.h" more than once.
if not GMOCK_H_SEED in processed_files:
processed_files.add(GMOCK_H_SEED)
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)

with open(os.path.join(gmock_root, gmock_source_file), 'r') as fh:
for line in fh:
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
# It's '#include "gtest/..."'.
# There is no need to #include gtest.h as it has been
# #included by gtest-all.cc.
pass
# '#include "gmock/foo.h"'.
# We treat it as '#include "gmock/gmock.h"', as all other gmock
# headers are being fused into gmock.h and cannot be
# included directly. No need to #include
# "third_party/googletest/googlemock/include/gmock/gmock.h"
# more than once.

if GMOCK_H_SEED not in processed_files:
processed_files.add(GMOCK_H_SEED)
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
else:
m = gtest.INCLUDE_SRC_FILE_REGEX.match(line)
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
# It's '#include "src/foo"' - let's process it recursively.
ProcessFile(m.group(1))
# '#include "gtest/..."'.
# There is no need to #include gtest.h as it has been
# #included by gtest-all.cc.

pass
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
m = gtest.INCLUDE_SRC_FILE_REGEX.match(line)
if m:
# It's '#include "src/foo"' - let's process it recursively.
ProcessFile(m.group(1))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)

ProcessFile(GMOCK_ALL_CC_SEED)


def FuseGMockGTestAllCc(gmock_root, output_dir):
"""Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir."""

output_file = file(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), 'w')
# First, fuse gtest-all.cc into gmock-gtest-all.cc.
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
# Next, append fused gmock-all.cc to gmock-gtest-all.cc.
FuseGMockAllCcToFile(gmock_root, output_file)
output_file.close()
with open(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT),
'w') as output_file:
# First, fuse gtest-all.cc into gmock-gtest-all.cc.
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
# Next, append fused gmock-all.cc to gmock-gtest-all.cc.
FuseGMockAllCcToFile(gmock_root, output_file)


def FuseGMock(gmock_root, output_dir):
Expand All @@ -232,7 +251,7 @@ def main():
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
FuseGMock(sys.argv[1], sys.argv[2])
else:
print __doc__
print(__doc__)
sys.exit(1)


Expand Down
57 changes: 25 additions & 32 deletions googletest/include/gtest/gtest-printers.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,51 +192,43 @@ struct PointerPrinter {
}
};

namespace internal_stream {
namespace internal_stream_operator_without_lexical_name_lookup {

struct Sentinel;
template <typename Char, typename CharTraits, typename T>
Sentinel* operator<<(::std::basic_ostream<Char, CharTraits>& os, const T& x);

// Check if the user has a user-defined operator<< for their type.
//
// We put this in its own namespace to inject a custom operator<< that allows us
// to probe the type's operator.
//
// Note that this operator<< takes a generic std::basic_ostream<Char,
// CharTraits> type instead of the more restricted std::ostream. If
// we define it to take an std::ostream instead, we'll get an
// "ambiguous overloads" compiler error when trying to print a type
// Foo that supports streaming to std::basic_ostream<Char,
// CharTraits>, as the compiler cannot tell whether
// operator<<(std::ostream&, const T&) or
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
// specific.
template <typename T>
constexpr bool UseStreamOperator() {
return !std::is_same<decltype(std::declval<std::ostream&>()
<< std::declval<const T&>()),
Sentinel*>::value;
}

} // namespace internal_stream
// The presence of an operator<< here will terminate lexical scope lookup
// straight away (even though it cannot be a match because of its argument
// types). Thus, the two operator<< calls in StreamPrinter will find only ADL
// candidates.
struct LookupBlocker {};
void operator<<(LookupBlocker, LookupBlocker);

struct StreamPrinter {
template <typename T, typename = typename std::enable_if<
internal_stream::UseStreamOperator<T>()>::type>
template <typename T,
// Don't accept member pointers here. We'd print them via implicit
// conversion to bool, which isn't useful.
typename = typename std::enable_if<
!std::is_member_pointer<T>::value>::type,
// Only accept types for which we can find a streaming operator via
// ADL (possibly involving implicit conversions).
typename = decltype(std::declval<std::ostream&>()
<< std::declval<const T&>())>
static void PrintValue(const T& value, ::std::ostream* os) {
// Call streaming operator found by ADL, possibly with implicit conversions
// of the arguments.
*os << value;
}
};

} // namespace internal_stream_operator_without_lexical_name_lookup

struct ProtobufPrinter {
// We print a protobuf using its ShortDebugString() when the string
// doesn't exceed this many characters; otherwise we print it using
// DebugString() for better readability.
static const size_t kProtobufOneLinerMaxLength = 50;

template <typename T, typename = typename std::enable_if<
internal::IsAProtocolMessage<T>::value>::type>
template <typename T,
typename = typename std::enable_if<
internal::HasDebugStringAndShortDebugString<T>::value>::type>
static void PrintValue(const T& value, ::std::ostream* os) {
std::string pretty_str = value.ShortDebugString();
if (pretty_str.length() > kProtobufOneLinerMaxLength) {
Expand Down Expand Up @@ -307,7 +299,8 @@ template <typename T>
void PrintWithFallback(const T& value, ::std::ostream* os) {
using Printer = typename FindFirstPrinter<
T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
StreamPrinter, ProtobufPrinter, ConvertibleToIntegerPrinter,
internal_stream_operator_without_lexical_name_lookup::StreamPrinter,
ProtobufPrinter, ConvertibleToIntegerPrinter,
ConvertibleToStringViewPrinter, FallbackPrinter>::type;
Printer::PrintValue(value, os);
}
Expand Down
Loading