mirror of
https://git.mirrors.martin98.com/https://github.com/google/googletest.git
synced 2025-08-12 00:08:59 +08:00
Googletest export
Introduce GMOCK_FLAG_GET and GMOCK_FLAG_SET macros. PiperOrigin-RevId: 396649214
This commit is contained in:
parent
159c9ad23e
commit
6202251f09
@ -63,13 +63,13 @@
|
|||||||
#include "gmock/gmock-nice-strict.h"
|
#include "gmock/gmock-nice-strict.h"
|
||||||
#include "gmock/internal/gmock-internal-utils.h"
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
// Declares Google Mock flags that we want a user to use programmatically.
|
// Declares Google Mock flags that we want a user to use programmatically.
|
||||||
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
||||||
GMOCK_DECLARE_string_(verbose);
|
GMOCK_DECLARE_string_(verbose);
|
||||||
GMOCK_DECLARE_int32_(default_mock_behavior);
|
GMOCK_DECLARE_int32_(default_mock_behavior);
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
// Initializes Google Mock. This must be called before running the
|
// Initializes Google Mock. This must be called before running the
|
||||||
// tests. In particular, it parses the command line for the flags
|
// tests. In particular, it parses the command line for the flags
|
||||||
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
||||||
|
@ -14,3 +14,5 @@ The following macros can be defined:
|
|||||||
* `GMOCK_DEFINE_bool_(name, default_val, doc)`
|
* `GMOCK_DEFINE_bool_(name, default_val, doc)`
|
||||||
* `GMOCK_DEFINE_int32_(name, default_val, doc)`
|
* `GMOCK_DEFINE_int32_(name, default_val, doc)`
|
||||||
* `GMOCK_DEFINE_string_(name, default_val, doc)`
|
* `GMOCK_DEFINE_string_(name, default_val, doc)`
|
||||||
|
* `GMOCK_FLAG_GET(flag_name)`
|
||||||
|
* `GMOCK_FLAG_SET(flag_name, value)`
|
||||||
|
@ -67,19 +67,37 @@
|
|||||||
#if !defined(GMOCK_DECLARE_bool_)
|
#if !defined(GMOCK_DECLARE_bool_)
|
||||||
|
|
||||||
// Macros for declaring flags.
|
// Macros for declaring flags.
|
||||||
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
#define GMOCK_DECLARE_bool_(name) \
|
||||||
# define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name)
|
namespace testing { \
|
||||||
# define GMOCK_DECLARE_string_(name) \
|
GTEST_API_ extern bool GMOCK_FLAG(name); \
|
||||||
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
}
|
||||||
|
#define GMOCK_DECLARE_int32_(name) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ extern int32_t GMOCK_FLAG(name); \
|
||||||
|
}
|
||||||
|
#define GMOCK_DECLARE_string_(name) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ extern ::std::string GMOCK_FLAG(name); \
|
||||||
|
}
|
||||||
|
|
||||||
// Macros for defining flags.
|
// Macros for defining flags.
|
||||||
# define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
|
namespace testing { \
|
||||||
# define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \
|
||||||
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val)
|
}
|
||||||
# define GMOCK_DEFINE_string_(name, default_val, doc) \
|
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||||
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
namespace testing { \
|
||||||
|
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \
|
||||||
|
}
|
||||||
|
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \
|
||||||
|
}
|
||||||
#endif // !defined(GMOCK_DECLARE_bool_)
|
#endif // !defined(GMOCK_DECLARE_bool_)
|
||||||
|
|
||||||
|
#if !defined(GMOCK_FLAG_GET)
|
||||||
|
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
|
||||||
|
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
|
||||||
|
#endif // !defined(GMOCK_FLAG_GET)
|
||||||
|
|
||||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
# Please Note:
|
|
||||||
|
|
||||||
Files in this directory are no longer supported by the maintainers. They
|
|
||||||
represent mostly historical artifacts and supported by the community only. There
|
|
||||||
is no guarantee whatsoever that these scripts still work.
|
|
@ -1,256 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2009, Google Inc.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are
|
|
||||||
# met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above
|
|
||||||
# copyright notice, this list of conditions and the following disclaimer
|
|
||||||
# in the documentation and/or other materials provided with the
|
|
||||||
# distribution.
|
|
||||||
# * Neither the name of Google Inc. nor the names of its
|
|
||||||
# contributors may be used to endorse or promote products derived from
|
|
||||||
# this software without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
"""fuse_gmock_files.py v0.1.0.
|
|
||||||
|
|
||||||
Fuses Google Mock and Google Test source code into two .h files and a .cc file.
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR
|
|
||||||
|
|
||||||
Scans GMOCK_ROOT_DIR for Google Mock and Google Test source
|
|
||||||
code, assuming Google Test is in the GMOCK_ROOT_DIR/../googletest
|
|
||||||
directory, and generates three files:
|
|
||||||
OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and
|
|
||||||
OUTPUT_DIR/gmock-gtest-all.cc. Then you can build your tests
|
|
||||||
by adding OUTPUT_DIR to the include search path and linking
|
|
||||||
with OUTPUT_DIR/gmock-gtest-all.cc. These three files contain
|
|
||||||
everything you need to use Google Mock. Hence you can
|
|
||||||
"install" Google Mock by copying them to wherever you want.
|
|
||||||
|
|
||||||
GMOCK_ROOT_DIR can be omitted and defaults to the parent
|
|
||||||
directory of the directory holding this script.
|
|
||||||
|
|
||||||
EXAMPLES
|
|
||||||
./fuse_gmock_files.py fused_gmock
|
|
||||||
./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock
|
|
||||||
|
|
||||||
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/docs/gmock_cook_book.md
|
|
||||||
for more
|
|
||||||
information.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
__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 as gtest # pylint:disable=g-import-not-at-top
|
|
||||||
|
|
||||||
# Regex for matching
|
|
||||||
# '#include "gmock/..."'.
|
|
||||||
INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')
|
|
||||||
|
|
||||||
# Where to find the source seed files.
|
|
||||||
GMOCK_H_SEED = 'include/gmock/gmock.h'
|
|
||||||
GMOCK_ALL_CC_SEED = 'src/gmock-all.cc'
|
|
||||||
|
|
||||||
# Where to put the generated files.
|
|
||||||
GTEST_H_OUTPUT = 'gtest/gtest.h'
|
|
||||||
GMOCK_H_OUTPUT = 'gmock/gmock.h'
|
|
||||||
GMOCK_GTEST_ALL_CC_OUTPUT = 'gmock-gtest-all.cc'
|
|
||||||
|
|
||||||
|
|
||||||
def GetGTestRootDir(gmock_root):
|
|
||||||
"""Returns the root directory of Google Test."""
|
|
||||||
|
|
||||||
return os.path.join(gmock_root, '../googletest')
|
|
||||||
|
|
||||||
|
|
||||||
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))
|
|
||||||
gtest.VerifyFileExists(gmock_root, GMOCK_H_SEED)
|
|
||||||
gtest.VerifyFileExists(gmock_root, GMOCK_ALL_CC_SEED)
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
gtest.VerifyOutputFile(output_dir, GMOCK_H_OUTPUT)
|
|
||||||
gtest.VerifyOutputFile(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT)
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGMockH(gmock_root, output_dir):
|
|
||||||
"""Scans folder gmock_root to generate gmock/gmock.h in output_dir."""
|
|
||||||
|
|
||||||
output_file = open(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
|
|
||||||
processed_files = set() # Holds all gmock headers we've processed.
|
|
||||||
|
|
||||||
def ProcessFile(gmock_header_path):
|
|
||||||
"""Processes the given gmock header file."""
|
|
||||||
|
|
||||||
# We don't process the same header twice.
|
|
||||||
if gmock_header_path in processed_files:
|
|
||||||
return
|
|
||||||
|
|
||||||
processed_files.add(gmock_header_path)
|
|
||||||
|
|
||||||
# Reads each line in the given gmock header.
|
|
||||||
|
|
||||||
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:
|
|
||||||
# '#include "gmock/..."'
|
|
||||||
# - let's process it recursively.
|
|
||||||
ProcessFile('include/' + m.group(1))
|
|
||||||
else:
|
|
||||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
# '#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()
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGMockAllCcToFile(gmock_root, output_file):
|
|
||||||
"""Scans folder gmock_root to fuse gmock-all.cc into output_file."""
|
|
||||||
|
|
||||||
processed_files = set()
|
|
||||||
|
|
||||||
def ProcessFile(gmock_source_file):
|
|
||||||
"""Processes the given gmock source file."""
|
|
||||||
|
|
||||||
# We don't process the same #included file twice.
|
|
||||||
if gmock_source_file in processed_files:
|
|
||||||
return
|
|
||||||
|
|
||||||
processed_files.add(gmock_source_file)
|
|
||||||
|
|
||||||
# Reads each line in the given gmock source file.
|
|
||||||
|
|
||||||
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:
|
|
||||||
# '#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 "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_GTEST_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
# '#include "gtest/..."'
|
|
||||||
# There is no need to #include gtest.h as it has been
|
|
||||||
# #included by gtest-all.cc.
|
|
||||||
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
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."""
|
|
||||||
|
|
||||||
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):
|
|
||||||
"""Fuses gtest.h, gmock.h, and gmock-gtest-all.h."""
|
|
||||||
|
|
||||||
ValidateGMockRootDir(gmock_root)
|
|
||||||
ValidateOutputDir(output_dir)
|
|
||||||
|
|
||||||
gtest.FuseGTestH(GetGTestRootDir(gmock_root), output_dir)
|
|
||||||
FuseGMockH(gmock_root, output_dir)
|
|
||||||
FuseGMockGTestAllCc(gmock_root, output_dir)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
argc = len(sys.argv)
|
|
||||||
if argc == 2:
|
|
||||||
# fuse_gmock_files.py OUTPUT_DIR
|
|
||||||
FuseGMock(DEFAULT_GMOCK_ROOT_DIR, sys.argv[1])
|
|
||||||
elif argc == 3:
|
|
||||||
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
|
|
||||||
FuseGMock(sys.argv[1], sys.argv[2])
|
|
||||||
else:
|
|
||||||
print(__doc__)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,203 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [2007] Neal Norwitz
|
|
||||||
Portions Copyright [2007] Google Inc.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
The Google Mock class generator is an application that is part of cppclean.
|
|
||||||
For more information about cppclean, visit http://code.google.com/p/cppclean/
|
|
||||||
|
|
||||||
The mock generator requires Python 2.3.5 or later. If you don't have Python
|
|
||||||
installed on your system, you will also need to install it. You can download
|
|
||||||
Python from: http://www.python.org/download/releases/
|
|
||||||
|
|
||||||
To use the Google Mock class generator, you need to call it
|
|
||||||
on the command line passing the header file and class for which you want
|
|
||||||
to generate a Google Mock class.
|
|
||||||
|
|
||||||
Make sure to install the scripts somewhere in your path. Then you can
|
|
||||||
run the program.
|
|
||||||
|
|
||||||
gmock_gen.py header-file.h [ClassName]...
|
|
||||||
|
|
||||||
If no ClassNames are specified, all classes in the file are emitted.
|
|
||||||
|
|
||||||
To change the indentation from the default of 2, set INDENT in
|
|
||||||
the environment. For example to use an indent of 4 spaces:
|
|
||||||
|
|
||||||
INDENT=4 gmock_gen.py header-file.h ClassName
|
|
||||||
|
|
||||||
This version was made from SVN revision 281 in the cppclean repository.
|
|
||||||
|
|
||||||
Known Limitations
|
|
||||||
-----------------
|
|
||||||
Not all code will be generated properly. For example, when mocking templated
|
|
||||||
classes, the template information is lost. You will need to add the template
|
|
||||||
information manually.
|
|
||||||
|
|
||||||
Not all permutations of using multiple pointers/references will be rendered
|
|
||||||
properly. These will also have to be fixed manually.
|
|
@ -1,115 +0,0 @@
|
|||||||
Goal:
|
|
||||||
-----
|
|
||||||
CppClean attempts to find problems in C++ source that slow development
|
|
||||||
in large code bases, for example various forms of unused code.
|
|
||||||
Unused code can be unused functions, methods, data members, types, etc
|
|
||||||
to unnecessary #include directives. Unnecessary #includes can cause
|
|
||||||
considerable extra compiles increasing the edit-compile-run cycle.
|
|
||||||
|
|
||||||
The project home page is: http://code.google.com/p/cppclean/
|
|
||||||
|
|
||||||
|
|
||||||
Features:
|
|
||||||
---------
|
|
||||||
* Find and print C++ language constructs: classes, methods, functions, etc.
|
|
||||||
* Find classes with virtual methods, no virtual destructor, and no bases
|
|
||||||
* Find global/static data that are potential problems when using threads
|
|
||||||
* Unnecessary forward class declarations
|
|
||||||
* Unnecessary function declarations
|
|
||||||
* Undeclared function definitions
|
|
||||||
* (planned) Find unnecessary header files #included
|
|
||||||
- No direct reference to anything in the header
|
|
||||||
- Header is unnecessary if classes were forward declared instead
|
|
||||||
* (planned) Source files that reference headers not directly #included,
|
|
||||||
ie, files that rely on a transitive #include from another header
|
|
||||||
* (planned) Unused members (private, protected, & public) methods and data
|
|
||||||
* (planned) Store AST in a SQL database so relationships can be queried
|
|
||||||
|
|
||||||
AST is Abstract Syntax Tree, a representation of parsed source code.
|
|
||||||
http://en.wikipedia.org/wiki/Abstract_syntax_tree
|
|
||||||
|
|
||||||
|
|
||||||
System Requirements:
|
|
||||||
--------------------
|
|
||||||
* Python 2.4 or later (2.3 probably works too)
|
|
||||||
* Works on Windows (untested), Mac OS X, and Unix
|
|
||||||
|
|
||||||
|
|
||||||
How to Run:
|
|
||||||
-----------
|
|
||||||
For all examples, it is assumed that cppclean resides in a directory called
|
|
||||||
/cppclean.
|
|
||||||
|
|
||||||
To print warnings for classes with virtual methods, no virtual destructor and
|
|
||||||
no base classes:
|
|
||||||
|
|
||||||
/cppclean/run.sh nonvirtual_dtors.py file1.h file2.h file3.cc ...
|
|
||||||
|
|
||||||
To print all the functions defined in header file(s):
|
|
||||||
|
|
||||||
/cppclean/run.sh functions.py file1.h file2.h ...
|
|
||||||
|
|
||||||
All the commands take multiple files on the command line. Other programs
|
|
||||||
include: find_warnings, headers, methods, and types. Some other programs
|
|
||||||
are available, but used primarily for debugging.
|
|
||||||
|
|
||||||
run.sh is a simple wrapper that sets PYTHONPATH to /cppclean and then
|
|
||||||
runs the program in /cppclean/cpp/PROGRAM.py. There is currently
|
|
||||||
no equivalent for Windows. Contributions for a run.bat file
|
|
||||||
would be greatly appreciated.
|
|
||||||
|
|
||||||
|
|
||||||
How to Configure:
|
|
||||||
-----------------
|
|
||||||
You can add a siteheaders.py file in /cppclean/cpp to configure where
|
|
||||||
to look for other headers (typically -I options passed to a compiler).
|
|
||||||
Currently two values are supported: _TRANSITIVE and GetIncludeDirs.
|
|
||||||
_TRANSITIVE should be set to a boolean value (True or False) indicating
|
|
||||||
whether to transitively process all header files. The default is False.
|
|
||||||
|
|
||||||
GetIncludeDirs is a function that takes a single argument and returns
|
|
||||||
a sequence of directories to include. This can be a generator or
|
|
||||||
return a static list.
|
|
||||||
|
|
||||||
def GetIncludeDirs(filename):
|
|
||||||
return ['/some/path/with/other/headers']
|
|
||||||
|
|
||||||
# Here is a more complicated example.
|
|
||||||
def GetIncludeDirs(filename):
|
|
||||||
yield '/path1'
|
|
||||||
yield os.path.join('/path2', os.path.dirname(filename))
|
|
||||||
yield '/path3'
|
|
||||||
|
|
||||||
|
|
||||||
How to Test:
|
|
||||||
------------
|
|
||||||
For all examples, it is assumed that cppclean resides in a directory called
|
|
||||||
/cppclean. The tests require
|
|
||||||
|
|
||||||
cd /cppclean
|
|
||||||
make test
|
|
||||||
# To generate expected results after a change:
|
|
||||||
make expected
|
|
||||||
|
|
||||||
|
|
||||||
Current Status:
|
|
||||||
---------------
|
|
||||||
The parser works pretty well for header files, parsing about 99% of Google's
|
|
||||||
header files. Anything which inspects structure of C++ source files should
|
|
||||||
work reasonably well. Function bodies are not transformed to an AST,
|
|
||||||
but left as tokens. Much work is still needed on finding unused header files
|
|
||||||
and storing an AST in a database.
|
|
||||||
|
|
||||||
|
|
||||||
Non-goals:
|
|
||||||
----------
|
|
||||||
* Parsing all valid C++ source
|
|
||||||
* Handling invalid C++ source gracefully
|
|
||||||
* Compiling to machine code (or anything beyond an AST)
|
|
||||||
|
|
||||||
|
|
||||||
Contact:
|
|
||||||
--------
|
|
||||||
If you used cppclean, I would love to hear about your experiences
|
|
||||||
cppclean@googlegroups.com. Even if you don't use cppclean, I'd like to
|
|
||||||
hear from you. :-) (You can contact me directly at: nnorwitz@gmail.com)
|
|
File diff suppressed because it is too large
Load Diff
@ -1,247 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Generate Google Mock classes from base classes.
|
|
||||||
|
|
||||||
This program will read in a C++ source file and output the Google Mock
|
|
||||||
classes for the specified classes. If no class is specified, all
|
|
||||||
classes in the source file are emitted.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
gmock_class.py header-file.h [ClassName]...
|
|
||||||
|
|
||||||
Output is sent to stdout.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from cpp import ast
|
|
||||||
from cpp import utils
|
|
||||||
|
|
||||||
# Preserve compatibility with Python 2.3.
|
|
||||||
try:
|
|
||||||
_dummy = set
|
|
||||||
except NameError:
|
|
||||||
import sets
|
|
||||||
|
|
||||||
set = sets.Set
|
|
||||||
|
|
||||||
_VERSION = (1, 0, 1) # The version of this script.
|
|
||||||
# How many spaces to indent. Can set me with the INDENT environment variable.
|
|
||||||
_INDENT = 2
|
|
||||||
|
|
||||||
|
|
||||||
def _RenderType(ast_type):
|
|
||||||
"""Renders the potentially recursively templated type into a string.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ast_type: The AST of the type.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Rendered string of the type.
|
|
||||||
"""
|
|
||||||
# Add modifiers like 'const'.
|
|
||||||
modifiers = ''
|
|
||||||
if ast_type.modifiers:
|
|
||||||
modifiers = ' '.join(ast_type.modifiers) + ' '
|
|
||||||
return_type = modifiers + ast_type.name
|
|
||||||
if ast_type.templated_types:
|
|
||||||
# Collect template args.
|
|
||||||
template_args = []
|
|
||||||
for arg in ast_type.templated_types:
|
|
||||||
rendered_arg = _RenderType(arg)
|
|
||||||
template_args.append(rendered_arg)
|
|
||||||
return_type += '<' + ', '.join(template_args) + '>'
|
|
||||||
if ast_type.pointer:
|
|
||||||
return_type += '*'
|
|
||||||
if ast_type.reference:
|
|
||||||
return_type += '&'
|
|
||||||
return return_type
|
|
||||||
|
|
||||||
|
|
||||||
def _GenerateArg(source):
|
|
||||||
"""Strips out comments, default arguments, and redundant spaces from a single argument.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
source: A string for a single argument.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Rendered string of the argument.
|
|
||||||
"""
|
|
||||||
# Remove end of line comments before eliminating newlines.
|
|
||||||
arg = re.sub(r'//.*', '', source)
|
|
||||||
|
|
||||||
# Remove c-style comments.
|
|
||||||
arg = re.sub(r'/\*.*\*/', '', arg)
|
|
||||||
|
|
||||||
# Remove default arguments.
|
|
||||||
arg = re.sub(r'=.*', '', arg)
|
|
||||||
|
|
||||||
# Collapse spaces and newlines into a single space.
|
|
||||||
arg = re.sub(r'\s+', ' ', arg)
|
|
||||||
return arg.strip()
|
|
||||||
|
|
||||||
|
|
||||||
def _EscapeForMacro(s):
|
|
||||||
"""Escapes a string for use as an argument to a C++ macro."""
|
|
||||||
paren_count = 0
|
|
||||||
for c in s:
|
|
||||||
if c == '(':
|
|
||||||
paren_count += 1
|
|
||||||
elif c == ')':
|
|
||||||
paren_count -= 1
|
|
||||||
elif c == ',' and paren_count == 0:
|
|
||||||
return '(' + s + ')'
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def _GenerateMethods(output_lines, source, class_node):
|
|
||||||
function_type = (
|
|
||||||
ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | ast.FUNCTION_OVERRIDE)
|
|
||||||
ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR
|
|
||||||
indent = ' ' * _INDENT
|
|
||||||
|
|
||||||
for node in class_node.body:
|
|
||||||
# We only care about virtual functions.
|
|
||||||
if (isinstance(node, ast.Function) and node.modifiers & function_type and
|
|
||||||
not node.modifiers & ctor_or_dtor):
|
|
||||||
# Pick out all the elements we need from the original function.
|
|
||||||
modifiers = 'override'
|
|
||||||
if node.modifiers & ast.FUNCTION_CONST:
|
|
||||||
modifiers = 'const, ' + modifiers
|
|
||||||
|
|
||||||
return_type = 'void'
|
|
||||||
if node.return_type:
|
|
||||||
return_type = _EscapeForMacro(_RenderType(node.return_type))
|
|
||||||
|
|
||||||
args = []
|
|
||||||
for p in node.parameters:
|
|
||||||
arg = _GenerateArg(source[p.start:p.end])
|
|
||||||
if arg != 'void':
|
|
||||||
args.append(_EscapeForMacro(arg))
|
|
||||||
|
|
||||||
# Create the mock method definition.
|
|
||||||
output_lines.extend([
|
|
||||||
'%sMOCK_METHOD(%s, %s, (%s), (%s));' %
|
|
||||||
(indent, return_type, node.name, ', '.join(args), modifiers)
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
def _GenerateMocks(filename, source, ast_list, desired_class_names):
|
|
||||||
processed_class_names = set()
|
|
||||||
lines = []
|
|
||||||
for node in ast_list:
|
|
||||||
if (isinstance(node, ast.Class) and node.body and
|
|
||||||
# desired_class_names being None means that all classes are selected.
|
|
||||||
(not desired_class_names or node.name in desired_class_names)):
|
|
||||||
class_name = node.name
|
|
||||||
parent_name = class_name
|
|
||||||
processed_class_names.add(class_name)
|
|
||||||
class_node = node
|
|
||||||
# Add namespace before the class.
|
|
||||||
if class_node.namespace:
|
|
||||||
lines.extend(['namespace %s {' % n for n in class_node.namespace]) # }
|
|
||||||
lines.append('')
|
|
||||||
|
|
||||||
# Add template args for templated classes.
|
|
||||||
if class_node.templated_types:
|
|
||||||
# TODO(paulchang): Handle non-type template arguments (e.g.
|
|
||||||
# template<typename T, int N>).
|
|
||||||
|
|
||||||
# class_node.templated_types is an OrderedDict from strings to a tuples.
|
|
||||||
# The key is the name of the template, and the value is
|
|
||||||
# (type_name, default). Both type_name and default could be None.
|
|
||||||
template_args = class_node.templated_types.keys()
|
|
||||||
template_decls = ['typename ' + arg for arg in template_args]
|
|
||||||
lines.append('template <' + ', '.join(template_decls) + '>')
|
|
||||||
parent_name += '<' + ', '.join(template_args) + '>'
|
|
||||||
|
|
||||||
# Add the class prolog.
|
|
||||||
lines.append('class Mock%s : public %s {' # }
|
|
||||||
% (class_name, parent_name))
|
|
||||||
lines.append('%spublic:' % (' ' * (_INDENT // 2)))
|
|
||||||
|
|
||||||
# Add all the methods.
|
|
||||||
_GenerateMethods(lines, source, class_node)
|
|
||||||
|
|
||||||
# Close the class.
|
|
||||||
if lines:
|
|
||||||
# If there are no virtual methods, no need for a public label.
|
|
||||||
if len(lines) == 2:
|
|
||||||
del lines[-1]
|
|
||||||
|
|
||||||
# Only close the class if there really is a class.
|
|
||||||
lines.append('};')
|
|
||||||
lines.append('') # Add an extra newline.
|
|
||||||
|
|
||||||
# Close the namespace.
|
|
||||||
if class_node.namespace:
|
|
||||||
for i in range(len(class_node.namespace) - 1, -1, -1):
|
|
||||||
lines.append('} // namespace %s' % class_node.namespace[i])
|
|
||||||
lines.append('') # Add an extra newline.
|
|
||||||
|
|
||||||
if desired_class_names:
|
|
||||||
missing_class_name_list = list(desired_class_names - processed_class_names)
|
|
||||||
if missing_class_name_list:
|
|
||||||
missing_class_name_list.sort()
|
|
||||||
sys.stderr.write('Class(es) not found in %s: %s\n' %
|
|
||||||
(filename, ', '.join(missing_class_name_list)))
|
|
||||||
elif not processed_class_names:
|
|
||||||
sys.stderr.write('No class found in %s\n' % filename)
|
|
||||||
|
|
||||||
return lines
|
|
||||||
|
|
||||||
|
|
||||||
def main(argv=sys.argv):
|
|
||||||
if len(argv) < 2:
|
|
||||||
sys.stderr.write('Google Mock Class Generator v%s\n\n' %
|
|
||||||
'.'.join(map(str, _VERSION)))
|
|
||||||
sys.stderr.write(__doc__)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
global _INDENT
|
|
||||||
try:
|
|
||||||
_INDENT = int(os.environ['INDENT'])
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT'))
|
|
||||||
|
|
||||||
filename = argv[1]
|
|
||||||
desired_class_names = None # None means all classes in the source file.
|
|
||||||
if len(argv) >= 3:
|
|
||||||
desired_class_names = set(argv[2:])
|
|
||||||
source = utils.ReadFile(filename)
|
|
||||||
if source is None:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
builder = ast.BuilderFromSource(source, filename)
|
|
||||||
try:
|
|
||||||
entire_ast = filter(None, builder.Generate())
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
# An error message was already printed since we couldn't parse.
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
lines = _GenerateMocks(filename, source, entire_ast, desired_class_names)
|
|
||||||
sys.stdout.write('\n'.join(lines))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main(sys.argv)
|
|
@ -1,570 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2009 Neal Norwitz All Rights Reserved.
|
|
||||||
# Portions Copyright 2009 Google Inc. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Tests for gmock.scripts.generator.cpp.gmock_class."""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
# Allow the cpp imports below to work when run as a standalone script.
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
|
|
||||||
from cpp import ast
|
|
||||||
from cpp import gmock_class
|
|
||||||
|
|
||||||
|
|
||||||
class TestCase(unittest.TestCase):
|
|
||||||
"""Helper class that adds assert methods."""
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def StripLeadingWhitespace(lines):
|
|
||||||
"""Strip leading whitespace in each line in 'lines'."""
|
|
||||||
return '\n'.join([s.lstrip() for s in lines.split('\n')])
|
|
||||||
|
|
||||||
def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines):
|
|
||||||
"""Specialized assert that ignores the indent level."""
|
|
||||||
self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines))
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateMethodsTest(TestCase):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def GenerateMethodSource(cpp_source):
|
|
||||||
"""Convert C++ source to Google Mock output source lines."""
|
|
||||||
method_source_lines = []
|
|
||||||
# <test> is a pseudo-filename, it is not read or written.
|
|
||||||
builder = ast.BuilderFromSource(cpp_source, '<test>')
|
|
||||||
ast_list = list(builder.Generate())
|
|
||||||
gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0])
|
|
||||||
return '\n'.join(method_source_lines)
|
|
||||||
|
|
||||||
def testSimpleMethod(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual int Bar();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testSimpleConstructorsAndDestructor(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
Foo();
|
|
||||||
Foo(int x);
|
|
||||||
Foo(const Foo& f);
|
|
||||||
Foo(Foo&& f);
|
|
||||||
~Foo();
|
|
||||||
virtual int Bar() = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
# The constructors and destructor should be ignored.
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testVirtualDestructor(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual ~Foo();
|
|
||||||
virtual int Bar() = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
# The destructor should be ignored.
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testExplicitlyDefaultedConstructorsAndDestructor(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
Foo() = default;
|
|
||||||
Foo(const Foo& f) = default;
|
|
||||||
Foo(Foo&& f) = default;
|
|
||||||
~Foo() = default;
|
|
||||||
virtual int Bar() = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
# The constructors and destructor should be ignored.
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testExplicitlyDeletedConstructorsAndDestructor(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
Foo() = delete;
|
|
||||||
Foo(const Foo& f) = delete;
|
|
||||||
Foo(Foo&& f) = delete;
|
|
||||||
~Foo() = delete;
|
|
||||||
virtual int Bar() = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
# The constructors and destructor should be ignored.
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testSimpleOverrideMethod(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
int Bar() override;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testSimpleConstMethod(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(bool flag) const;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (bool flag), (const, override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testExplicitVoid(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual int Bar(void);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testStrangeNewlineInParameter(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int
|
|
||||||
a) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testDefaultParameters(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int a, char c = 'x') = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testMultipleDefaultParameters(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(
|
|
||||||
int a = 42,
|
|
||||||
char c = 'x',
|
|
||||||
const int* const p = nullptr,
|
|
||||||
const std::string& s = "42",
|
|
||||||
char tab[] = {'4','2'},
|
|
||||||
int const *& rp = aDefaultPointer) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, '
|
|
||||||
'(int a, char c, const int* const p, const std::string& s, char tab[], int const *& rp), '
|
|
||||||
'(override));', self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testMultipleSingleLineDefaultParameters(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int a = 42, int b = 43, int c = 44) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a, int b, int c), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testConstDefaultParameter(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual bool Bar(const int test_arg = 42) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(bool, Bar, (const int test_arg), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testConstRefDefaultParameter(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual bool Bar(const std::string& test_arg = "42" ) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(bool, Bar, (const std::string& test_arg), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testRemovesCommentsWhenDefaultsArePresent(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int a = 42 /* a comment */,
|
|
||||||
char /* other comment */ c= 'x') = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testDoubleSlashCommentsInParameterListAreRemoved(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int a, // inline comments should be elided.
|
|
||||||
int b // inline comments should be elided.
|
|
||||||
) const = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a, int b), (const, override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testCStyleCommentsInParameterListAreNotRemoved(self):
|
|
||||||
# NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these
|
|
||||||
# comments. Also note that C style comments after the last parameter
|
|
||||||
# are still elided.
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual const string& Bar(int /* keeper */, int b);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(const string&, Bar, (int, int b), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testArgsOfTemplateTypes(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual int Bar(const vector<int>& v, map<int, string>* output);
|
|
||||||
};"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (const vector<int>& v, (map<int, string>* output)), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testReturnTypeWithOneTemplateArg(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual vector<int>* Bar(int n);
|
|
||||||
};"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(vector<int>*, Bar, (int n), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testReturnTypeWithManyTemplateArgs(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual map<int, string> Bar();
|
|
||||||
};"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD((map<int, string>), Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testSimpleMethodInTemplatedClass(self):
|
|
||||||
source = """
|
|
||||||
template<class T>
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual int Bar();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testPointerArgWithoutNames(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
virtual int Bar(C*);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (C*), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testReferenceArgWithoutNames(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
virtual int Bar(C&);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (C&), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testArrayArgWithoutNames(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
virtual int Bar(C[]);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (C[]), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateMocksTest(TestCase):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def GenerateMocks(cpp_source):
|
|
||||||
"""Convert C++ source to complete Google Mock output source."""
|
|
||||||
# <test> is a pseudo-filename, it is not read or written.
|
|
||||||
filename = '<test>'
|
|
||||||
builder = ast.BuilderFromSource(cpp_source, filename)
|
|
||||||
ast_list = list(builder.Generate())
|
|
||||||
lines = gmock_class._GenerateMocks(filename, cpp_source, ast_list, None)
|
|
||||||
return '\n'.join(lines)
|
|
||||||
|
|
||||||
def testNamespaces(self):
|
|
||||||
source = """
|
|
||||||
namespace Foo {
|
|
||||||
namespace Bar { class Forward; }
|
|
||||||
namespace Baz::Qux {
|
|
||||||
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Baz::Qux
|
|
||||||
} // namespace Foo
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
namespace Foo {
|
|
||||||
namespace Baz::Qux {
|
|
||||||
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Baz::Qux
|
|
||||||
} // namespace Foo
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testClassWithStorageSpecifierMacro(self):
|
|
||||||
source = """
|
|
||||||
class STORAGE_SPECIFIER Test {
|
|
||||||
public:
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplatedForwardDeclaration(self):
|
|
||||||
source = """
|
|
||||||
template <class T> class Forward; // Forward declaration should be ignored.
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplatedClass(self):
|
|
||||||
source = """
|
|
||||||
template <typename S, typename T>
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
template <typename S, typename T>
|
|
||||||
class MockTest : public Test<S, T> {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplateInATemplateTypedef(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
typedef std::vector<std::list<int>> FooType;
|
|
||||||
virtual void Bar(const FooType& test_arg);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplatedClassWithTemplatedArguments(self):
|
|
||||||
source = """
|
|
||||||
template <typename S, typename T, typename U, typename V, typename W>
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual U Foo(T some_arg);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
template <typename S, typename T, typename U, typename V, typename W>
|
|
||||||
class MockTest : public Test<S, T, U, V, W> {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(U, Foo, (T some_arg), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplateInATemplateTypedefWithComma(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
typedef std::function<void(
|
|
||||||
const vector<std::list<int>>&, int> FooType;
|
|
||||||
virtual void Bar(const FooType& test_arg);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testParenthesizedCommaInArg(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual void Bar(std::function<void(int, int)> f);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Bar, (std::function<void(int, int)> f), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testEnumType(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
enum Bar {
|
|
||||||
BAZ, QUX, QUUX, QUUUX
|
|
||||||
};
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testEnumClassType(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
enum class Bar {
|
|
||||||
BAZ, QUX, QUUX, QUUUX
|
|
||||||
};
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testStdFunction(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
Test(std::function<int(std::string)> foo) : foo_(foo) {}
|
|
||||||
|
|
||||||
virtual std::function<int(std::string)> foo();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::function<int(std::string)> foo_;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(std::function<int (std::string)>, foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.main()
|
|
@ -1,56 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2007 Neal Norwitz
|
|
||||||
# Portions Copyright 2007 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""C++ keywords and helper utilities for determining keywords."""
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Python 3.x
|
|
||||||
import builtins
|
|
||||||
except ImportError:
|
|
||||||
# Python 2.x
|
|
||||||
import __builtin__ as builtins
|
|
||||||
|
|
||||||
|
|
||||||
if not hasattr(builtins, 'set'):
|
|
||||||
# Nominal support for Python 2.3.
|
|
||||||
from sets import Set as set
|
|
||||||
|
|
||||||
|
|
||||||
TYPES = set('bool char int long short double float void wchar_t unsigned signed'.split())
|
|
||||||
TYPE_MODIFIERS = set('auto register const inline extern static virtual volatile mutable'.split())
|
|
||||||
ACCESS = set('public protected private friend'.split())
|
|
||||||
|
|
||||||
CASTS = set('static_cast const_cast dynamic_cast reinterpret_cast'.split())
|
|
||||||
|
|
||||||
OTHERS = set('true false asm class namespace using explicit this operator sizeof'.split())
|
|
||||||
OTHER_TYPES = set('new delete typedef struct union enum typeid typename template'.split())
|
|
||||||
|
|
||||||
CONTROL = set('case switch default if else return goto'.split())
|
|
||||||
EXCEPTION = set('try catch throw'.split())
|
|
||||||
LOOP = set('while do for break continue'.split())
|
|
||||||
|
|
||||||
ALL = TYPES | TYPE_MODIFIERS | ACCESS | CASTS | OTHERS | OTHER_TYPES | CONTROL | EXCEPTION | LOOP
|
|
||||||
|
|
||||||
|
|
||||||
def IsKeyword(token):
|
|
||||||
return token in ALL
|
|
||||||
|
|
||||||
def IsBuiltinType(token):
|
|
||||||
if token in ('virtual', 'inline'):
|
|
||||||
# These only apply to methods, they can't be types by themselves.
|
|
||||||
return False
|
|
||||||
return token in TYPES or token in TYPE_MODIFIERS
|
|
@ -1,284 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2007 Neal Norwitz
|
|
||||||
# Portions Copyright 2007 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Tokenize C++ source code."""
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Python 3.x
|
|
||||||
import builtins
|
|
||||||
except ImportError:
|
|
||||||
# Python 2.x
|
|
||||||
import __builtin__ as builtins
|
|
||||||
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from cpp import utils
|
|
||||||
|
|
||||||
|
|
||||||
if not hasattr(builtins, 'set'):
|
|
||||||
# Nominal support for Python 2.3.
|
|
||||||
from sets import Set as set
|
|
||||||
|
|
||||||
|
|
||||||
# Add $ as a valid identifier char since so much code uses it.
|
|
||||||
_letters = 'abcdefghijklmnopqrstuvwxyz'
|
|
||||||
VALID_IDENTIFIER_CHARS = set(_letters + _letters.upper() + '_0123456789$')
|
|
||||||
HEX_DIGITS = set('0123456789abcdefABCDEF')
|
|
||||||
INT_OR_FLOAT_DIGITS = set('01234567890eE-+')
|
|
||||||
|
|
||||||
|
|
||||||
# C++0x string preffixes.
|
|
||||||
_STR_PREFIXES = set(('R', 'u8', 'u8R', 'u', 'uR', 'U', 'UR', 'L', 'LR'))
|
|
||||||
|
|
||||||
|
|
||||||
# Token types.
|
|
||||||
UNKNOWN = 'UNKNOWN'
|
|
||||||
SYNTAX = 'SYNTAX'
|
|
||||||
CONSTANT = 'CONSTANT'
|
|
||||||
NAME = 'NAME'
|
|
||||||
PREPROCESSOR = 'PREPROCESSOR'
|
|
||||||
|
|
||||||
# Where the token originated from. This can be used for backtracking.
|
|
||||||
# It is always set to WHENCE_STREAM in this code.
|
|
||||||
WHENCE_STREAM, WHENCE_QUEUE = range(2)
|
|
||||||
|
|
||||||
|
|
||||||
class Token(object):
|
|
||||||
"""Data container to represent a C++ token.
|
|
||||||
|
|
||||||
Tokens can be identifiers, syntax char(s), constants, or
|
|
||||||
pre-processor directives.
|
|
||||||
|
|
||||||
start contains the index of the first char of the token in the source
|
|
||||||
end contains the index of the last char of the token in the source
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, token_type, name, start, end):
|
|
||||||
self.token_type = token_type
|
|
||||||
self.name = name
|
|
||||||
self.start = start
|
|
||||||
self.end = end
|
|
||||||
self.whence = WHENCE_STREAM
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
if not utils.DEBUG:
|
|
||||||
return 'Token(%r)' % self.name
|
|
||||||
return 'Token(%r, %s, %s)' % (self.name, self.start, self.end)
|
|
||||||
|
|
||||||
__repr__ = __str__
|
|
||||||
|
|
||||||
|
|
||||||
def _GetString(source, start, i):
|
|
||||||
i = source.find('"', i+1)
|
|
||||||
while source[i-1] == '\\':
|
|
||||||
# Count the trailing backslashes.
|
|
||||||
backslash_count = 1
|
|
||||||
j = i - 2
|
|
||||||
while source[j] == '\\':
|
|
||||||
backslash_count += 1
|
|
||||||
j -= 1
|
|
||||||
# When trailing backslashes are even, they escape each other.
|
|
||||||
if (backslash_count % 2) == 0:
|
|
||||||
break
|
|
||||||
i = source.find('"', i+1)
|
|
||||||
return i + 1
|
|
||||||
|
|
||||||
|
|
||||||
def _GetChar(source, start, i):
|
|
||||||
# NOTE(nnorwitz): may not be quite correct, should be good enough.
|
|
||||||
i = source.find("'", i+1)
|
|
||||||
while source[i-1] == '\\':
|
|
||||||
# Need to special case '\\'.
|
|
||||||
if (i - 2) > start and source[i-2] == '\\':
|
|
||||||
break
|
|
||||||
i = source.find("'", i+1)
|
|
||||||
# Try to handle unterminated single quotes (in a #if 0 block).
|
|
||||||
if i < 0:
|
|
||||||
i = start
|
|
||||||
return i + 1
|
|
||||||
|
|
||||||
|
|
||||||
def GetTokens(source):
|
|
||||||
"""Returns a sequence of Tokens.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
source: string of C++ source code.
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
Token that represents the next token in the source.
|
|
||||||
"""
|
|
||||||
# Cache various valid character sets for speed.
|
|
||||||
valid_identifier_chars = VALID_IDENTIFIER_CHARS
|
|
||||||
hex_digits = HEX_DIGITS
|
|
||||||
int_or_float_digits = INT_OR_FLOAT_DIGITS
|
|
||||||
int_or_float_digits2 = int_or_float_digits | set('.')
|
|
||||||
|
|
||||||
# Only ignore errors while in a #if 0 block.
|
|
||||||
ignore_errors = False
|
|
||||||
count_ifs = 0
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
end = len(source)
|
|
||||||
while i < end:
|
|
||||||
# Skip whitespace.
|
|
||||||
while i < end and source[i].isspace():
|
|
||||||
i += 1
|
|
||||||
if i >= end:
|
|
||||||
return
|
|
||||||
|
|
||||||
token_type = UNKNOWN
|
|
||||||
start = i
|
|
||||||
c = source[i]
|
|
||||||
if c.isalpha() or c == '_': # Find a string token.
|
|
||||||
token_type = NAME
|
|
||||||
while source[i] in valid_identifier_chars:
|
|
||||||
i += 1
|
|
||||||
# String and character constants can look like a name if
|
|
||||||
# they are something like L"".
|
|
||||||
if (source[i] == "'" and (i - start) == 1 and
|
|
||||||
source[start:i] in 'uUL'):
|
|
||||||
# u, U, and L are valid C++0x character preffixes.
|
|
||||||
token_type = CONSTANT
|
|
||||||
i = _GetChar(source, start, i)
|
|
||||||
elif source[i] == "'" and source[start:i] in _STR_PREFIXES:
|
|
||||||
token_type = CONSTANT
|
|
||||||
i = _GetString(source, start, i)
|
|
||||||
elif c == '/' and source[i+1] == '/': # Find // comments.
|
|
||||||
i = source.find('\n', i)
|
|
||||||
if i == -1: # Handle EOF.
|
|
||||||
i = end
|
|
||||||
continue
|
|
||||||
elif c == '/' and source[i+1] == '*': # Find /* comments. */
|
|
||||||
i = source.find('*/', i) + 2
|
|
||||||
continue
|
|
||||||
elif c in ':+-<>&|*=': # : or :: (plus other chars).
|
|
||||||
token_type = SYNTAX
|
|
||||||
i += 1
|
|
||||||
new_ch = source[i]
|
|
||||||
if new_ch == c and c != '>': # Treat ">>" as two tokens.
|
|
||||||
i += 1
|
|
||||||
elif c == '-' and new_ch == '>':
|
|
||||||
i += 1
|
|
||||||
elif new_ch == '=':
|
|
||||||
i += 1
|
|
||||||
elif c in '()[]{}~!?^%;/.,': # Handle single char tokens.
|
|
||||||
token_type = SYNTAX
|
|
||||||
i += 1
|
|
||||||
if c == '.' and source[i].isdigit():
|
|
||||||
token_type = CONSTANT
|
|
||||||
i += 1
|
|
||||||
while source[i] in int_or_float_digits:
|
|
||||||
i += 1
|
|
||||||
# Handle float suffixes.
|
|
||||||
for suffix in ('l', 'f'):
|
|
||||||
if suffix == source[i:i+1].lower():
|
|
||||||
i += 1
|
|
||||||
break
|
|
||||||
elif c.isdigit(): # Find integer.
|
|
||||||
token_type = CONSTANT
|
|
||||||
if c == '0' and source[i+1] in 'xX':
|
|
||||||
# Handle hex digits.
|
|
||||||
i += 2
|
|
||||||
while source[i] in hex_digits:
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
while source[i] in int_or_float_digits2:
|
|
||||||
i += 1
|
|
||||||
# Handle integer (and float) suffixes.
|
|
||||||
for suffix in ('ull', 'll', 'ul', 'l', 'f', 'u'):
|
|
||||||
size = len(suffix)
|
|
||||||
if suffix == source[i:i+size].lower():
|
|
||||||
i += size
|
|
||||||
break
|
|
||||||
elif c == '"': # Find string.
|
|
||||||
token_type = CONSTANT
|
|
||||||
i = _GetString(source, start, i)
|
|
||||||
elif c == "'": # Find char.
|
|
||||||
token_type = CONSTANT
|
|
||||||
i = _GetChar(source, start, i)
|
|
||||||
elif c == '#': # Find pre-processor command.
|
|
||||||
token_type = PREPROCESSOR
|
|
||||||
got_if = source[i:i+3] == '#if' and source[i+3:i+4].isspace()
|
|
||||||
if got_if:
|
|
||||||
count_ifs += 1
|
|
||||||
elif source[i:i+6] == '#endif':
|
|
||||||
count_ifs -= 1
|
|
||||||
if count_ifs == 0:
|
|
||||||
ignore_errors = False
|
|
||||||
|
|
||||||
# TODO(nnorwitz): handle preprocessor statements (\ continuations).
|
|
||||||
while 1:
|
|
||||||
i1 = source.find('\n', i)
|
|
||||||
i2 = source.find('//', i)
|
|
||||||
i3 = source.find('/*', i)
|
|
||||||
i4 = source.find('"', i)
|
|
||||||
# NOTE(nnorwitz): doesn't handle comments in #define macros.
|
|
||||||
# Get the first important symbol (newline, comment, EOF/end).
|
|
||||||
i = min([x for x in (i1, i2, i3, i4, end) if x != -1])
|
|
||||||
|
|
||||||
# Handle #include "dir//foo.h" properly.
|
|
||||||
if source[i] == '"':
|
|
||||||
i = source.find('"', i+1) + 1
|
|
||||||
assert i > 0
|
|
||||||
continue
|
|
||||||
# Keep going if end of the line and the line ends with \.
|
|
||||||
if not (i == i1 and source[i-1] == '\\'):
|
|
||||||
if got_if:
|
|
||||||
condition = source[start+4:i].lstrip()
|
|
||||||
if (condition.startswith('0') or
|
|
||||||
condition.startswith('(0)')):
|
|
||||||
ignore_errors = True
|
|
||||||
break
|
|
||||||
i += 1
|
|
||||||
elif c == '\\': # Handle \ in code.
|
|
||||||
# This is different from the pre-processor \ handling.
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
elif ignore_errors:
|
|
||||||
# The tokenizer seems to be in pretty good shape. This
|
|
||||||
# raise is conditionally disabled so that bogus code
|
|
||||||
# in an #if 0 block can be handled. Since we will ignore
|
|
||||||
# it anyways, this is probably fine. So disable the
|
|
||||||
# exception and return the bogus char.
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
sys.stderr.write('Got invalid token in %s @ %d token:%s: %r\n' %
|
|
||||||
('?', i, c, source[i-10:i+10]))
|
|
||||||
raise RuntimeError('unexpected token')
|
|
||||||
|
|
||||||
if i <= 0:
|
|
||||||
print('Invalid index, exiting now.')
|
|
||||||
return
|
|
||||||
yield Token(token_type, source[start:i], start, i)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
def main(argv):
|
|
||||||
"""Driver mostly for testing purposes."""
|
|
||||||
for filename in argv[1:]:
|
|
||||||
source = utils.ReadFile(filename)
|
|
||||||
if source is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for token in GetTokens(source):
|
|
||||||
print('%-12s: %s' % (token.token_type, token.name))
|
|
||||||
# print('\r%6.2f%%' % (100.0 * index / token.end),)
|
|
||||||
sys.stdout.write('\n')
|
|
||||||
|
|
||||||
|
|
||||||
main(sys.argv)
|
|
@ -1,37 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2007 Neal Norwitz
|
|
||||||
# Portions Copyright 2007 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Generic utilities for C++ parsing."""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Set to True to see the start/end token indices.
|
|
||||||
DEBUG = True
|
|
||||||
|
|
||||||
|
|
||||||
def ReadFile(filename, print_error=True):
|
|
||||||
"""Returns the contents of a file."""
|
|
||||||
try:
|
|
||||||
fp = open(filename)
|
|
||||||
try:
|
|
||||||
return fp.read()
|
|
||||||
finally:
|
|
||||||
fp.close()
|
|
||||||
except IOError:
|
|
||||||
if print_error:
|
|
||||||
print('Error reading %s: %s' % (filename, sys.exc_info()[1]))
|
|
||||||
return None
|
|
@ -1,30 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Driver for starting up Google Mock class generator."""
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# Add the directory of this script to the path so we can import gmock_class.
|
|
||||||
sys.path.append(os.path.dirname(__file__))
|
|
||||||
|
|
||||||
from cpp import gmock_class
|
|
||||||
# Fix the docstring in case they require the usage.
|
|
||||||
gmock_class.__doc__ = gmock_class.__doc__.replace('gmock_class.py', __file__)
|
|
||||||
gmock_class.main()
|
|
@ -132,10 +132,10 @@ static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
|
|||||||
// Returns true if and only if a log with the given severity is visible
|
// Returns true if and only if a log with the given severity is visible
|
||||||
// according to the --gmock_verbose flag.
|
// according to the --gmock_verbose flag.
|
||||||
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
||||||
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
|
if (GMOCK_FLAG_GET(verbose) == kInfoVerbosity) {
|
||||||
// Always show the log if --gmock_verbose=info.
|
// Always show the log if --gmock_verbose=info.
|
||||||
return true;
|
return true;
|
||||||
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
} else if (GMOCK_FLAG_GET(verbose) == kErrorVerbosity) {
|
||||||
// Always hide it if --gmock_verbose=error.
|
// Always hide it if --gmock_verbose=error.
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -283,7 +283,7 @@ GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
|||||||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
||||||
// Include a stack trace only if --gmock_verbose=info is specified.
|
// Include a stack trace only if --gmock_verbose=info is specified.
|
||||||
const int stack_frames_to_skip =
|
const int stack_frames_to_skip =
|
||||||
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1;
|
GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1;
|
||||||
switch (reaction) {
|
switch (reaction) {
|
||||||
case kAllow:
|
case kAllow:
|
||||||
Log(kInfo, msg, stack_frames_to_skip);
|
Log(kInfo, msg, stack_frames_to_skip);
|
||||||
@ -613,8 +613,7 @@ class MockObjectRegistry {
|
|||||||
// object alive. Therefore we report any living object as test
|
// object alive. Therefore we report any living object as test
|
||||||
// failure, unless the user explicitly asked us to ignore it.
|
// failure, unless the user explicitly asked us to ignore it.
|
||||||
~MockObjectRegistry() {
|
~MockObjectRegistry() {
|
||||||
if (!GMOCK_FLAG(catch_leaked_mocks))
|
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
int leaked_count = 0;
|
int leaked_count = 0;
|
||||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||||
@ -716,9 +715,10 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
|||||||
const void* mock_obj)
|
const void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
return (g_uninteresting_call_reaction.count(mock_obj) == 0)
|
||||||
internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
|
? internal::intToCallReaction(
|
||||||
g_uninteresting_call_reaction[mock_obj];
|
GMOCK_FLAG_GET(default_mock_behavior))
|
||||||
|
: g_uninteresting_call_reaction[mock_obj];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||||
|
@ -31,13 +31,11 @@
|
|||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||||
"true if and only if Google Mock should report leaked "
|
"true if and only if Google Mock should report leaked "
|
||||||
"mock objects as failures.");
|
"mock objects as failures.");
|
||||||
|
|
||||||
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
|
GMOCK_DEFINE_string_(verbose, testing::internal::kWarningVerbosity,
|
||||||
"Controls how verbose Google Mock's output is."
|
"Controls how verbose Google Mock's output is."
|
||||||
" Valid values:\n"
|
" Valid values:\n"
|
||||||
" info - prints all messages.\n"
|
" info - prints all messages.\n"
|
||||||
@ -51,6 +49,7 @@ GMOCK_DEFINE_int32_(default_mock_behavior, 1,
|
|||||||
" 1 - by default, mocks act as NaggyMocks.\n"
|
" 1 - by default, mocks act as NaggyMocks.\n"
|
||||||
" 2 - by default, mocks act as StrictMocks.");
|
" 2 - by default, mocks act as StrictMocks.");
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Parses a string as a command line flag. The string should have the
|
// Parses a string as a command line flag. The string should have the
|
||||||
@ -59,18 +58,18 @@ namespace internal {
|
|||||||
//
|
//
|
||||||
// Returns the value of the flag, or NULL if the parsing failed.
|
// Returns the value of the flag, or NULL if the parsing failed.
|
||||||
static const char* ParseGoogleMockFlagValue(const char* str,
|
static const char* ParseGoogleMockFlagValue(const char* str,
|
||||||
const char* flag,
|
const char* flag_name,
|
||||||
bool def_optional) {
|
bool def_optional) {
|
||||||
// str and flag must not be NULL.
|
// str and flag must not be NULL.
|
||||||
if (str == nullptr || flag == nullptr) return nullptr;
|
if (str == nullptr || flag_name == nullptr) return nullptr;
|
||||||
|
|
||||||
// The flag must start with "--gmock_".
|
// The flag must start with "--gmock_".
|
||||||
const std::string flag_str = std::string("--gmock_") + flag;
|
const std::string flag_name_str = std::string("--gmock_") + flag_name;
|
||||||
const size_t flag_len = flag_str.length();
|
const size_t flag_name_len = flag_name_str.length();
|
||||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
|
if (strncmp(str, flag_name_str.c_str(), flag_name_len) != 0) return nullptr;
|
||||||
|
|
||||||
// Skips the flag name.
|
// Skips the flag name.
|
||||||
const char* flag_end = str + flag_len;
|
const char* flag_end = str + flag_name_len;
|
||||||
|
|
||||||
// When def_optional is true, it's OK to not have a "=value" part.
|
// When def_optional is true, it's OK to not have a "=value" part.
|
||||||
if (def_optional && (flag_end[0] == '\0')) {
|
if (def_optional && (flag_end[0] == '\0')) {
|
||||||
@ -91,10 +90,10 @@ static const char* ParseGoogleMockFlagValue(const char* str,
|
|||||||
//
|
//
|
||||||
// On success, stores the value of the flag in *value, and returns
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// true. On failure, returns false without changing *value.
|
||||||
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||||
bool* value) {
|
bool* value) {
|
||||||
// Gets the value of the flag as a string.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
|
||||||
|
|
||||||
// Aborts if the parsing failed.
|
// Aborts if the parsing failed.
|
||||||
if (value_str == nullptr) return false;
|
if (value_str == nullptr) return false;
|
||||||
@ -110,10 +109,10 @@ static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
|||||||
// On success, stores the value of the flag in *value, and returns
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// true. On failure, returns false without changing *value.
|
||||||
template <typename String>
|
template <typename String>
|
||||||
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||||
String* value) {
|
String* value) {
|
||||||
// Gets the value of the flag as a string.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
|
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, false);
|
||||||
|
|
||||||
// Aborts if the parsing failed.
|
// Aborts if the parsing failed.
|
||||||
if (value_str == nullptr) return false;
|
if (value_str == nullptr) return false;
|
||||||
@ -123,17 +122,17 @@ static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
|
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||||
int32_t* value) {
|
int32_t* value) {
|
||||||
// Gets the value of the flag as a string.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
|
||||||
|
|
||||||
// Aborts if the parsing failed.
|
// Aborts if the parsing failed.
|
||||||
if (value_str == nullptr) return false;
|
if (value_str == nullptr) return false;
|
||||||
|
|
||||||
// Sets *value to the value of the flag.
|
// Sets *value to the value of the flag.
|
||||||
return ParseInt32(Message() << "The value of flag --" << flag,
|
return ParseInt32(Message() << "The value of flag --" << flag_name, value_str,
|
||||||
value_str, value);
|
value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The internal implementation of InitGoogleMock().
|
// The internal implementation of InitGoogleMock().
|
||||||
@ -152,11 +151,22 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
|
|||||||
const char* const arg = arg_string.c_str();
|
const char* const arg = arg_string.c_str();
|
||||||
|
|
||||||
// Do we see a Google Mock flag?
|
// Do we see a Google Mock flag?
|
||||||
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
|
bool found_gmock_flag = false;
|
||||||
&GMOCK_FLAG(catch_leaked_mocks)) ||
|
|
||||||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
|
#define GMOCK_INTERNAL_PARSE_FLAG(flag_name) \
|
||||||
ParseGoogleMockIntFlag(arg, "default_mock_behavior",
|
if (!found_gmock_flag) { \
|
||||||
&GMOCK_FLAG(default_mock_behavior))) {
|
auto value = GMOCK_FLAG_GET(flag_name); \
|
||||||
|
if (ParseGoogleMockFlag(arg, #flag_name, &value)) { \
|
||||||
|
GMOCK_FLAG_SET(flag_name, value); \
|
||||||
|
found_gmock_flag = true; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
GMOCK_INTERNAL_PARSE_FLAG(catch_leaked_mocks)
|
||||||
|
GMOCK_INTERNAL_PARSE_FLAG(verbose)
|
||||||
|
GMOCK_INTERNAL_PARSE_FLAG(default_mock_behavior)
|
||||||
|
|
||||||
|
if (found_gmock_flag) {
|
||||||
// Yes. Shift the remainder of the argv list left by one. Note
|
// Yes. Shift the remainder of the argv list left by one. Note
|
||||||
// that argv has (*argc + 1) elements, the last one always being
|
// that argv has (*argc + 1) elements, the last one always being
|
||||||
// NULL. The following loop moves the trailing NULL element as
|
// NULL. The following loop moves the trailing NULL element as
|
||||||
|
@ -361,27 +361,27 @@ TEST(ExpectTest, FailsNonfatallyOnFalse) {
|
|||||||
|
|
||||||
class LogIsVisibleTest : public ::testing::Test {
|
class LogIsVisibleTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override { original_verbose_ = GMOCK_FLAG(verbose); }
|
void SetUp() override { original_verbose_ = GMOCK_FLAG_GET(verbose); }
|
||||||
|
|
||||||
void TearDown() override { GMOCK_FLAG(verbose) = original_verbose_; }
|
void TearDown() override { GMOCK_FLAG_SET(verbose, original_verbose_); }
|
||||||
|
|
||||||
std::string original_verbose_;
|
std::string original_verbose_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
|
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
|
||||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||||
EXPECT_TRUE(LogIsVisible(kInfo));
|
EXPECT_TRUE(LogIsVisible(kInfo));
|
||||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
|
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
|
||||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||||
EXPECT_FALSE(LogIsVisible(kWarning));
|
EXPECT_FALSE(LogIsVisible(kWarning));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
||||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||||
}
|
}
|
||||||
@ -395,7 +395,7 @@ TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
|||||||
void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
||||||
bool should_print) {
|
bool should_print) {
|
||||||
const std::string old_flag = GMOCK_FLAG(verbose);
|
const std::string old_flag = GMOCK_FLAG(verbose);
|
||||||
GMOCK_FLAG(verbose) = verbosity;
|
GMOCK_FLAG_SET(verbose, verbosity);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
Log(severity, "Test log.\n", 0);
|
Log(severity, "Test log.\n", 0);
|
||||||
if (should_print) {
|
if (should_print) {
|
||||||
@ -407,18 +407,18 @@ void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
|||||||
} else {
|
} else {
|
||||||
EXPECT_STREQ("", GetCapturedStdout().c_str());
|
EXPECT_STREQ("", GetCapturedStdout().c_str());
|
||||||
}
|
}
|
||||||
GMOCK_FLAG(verbose) = old_flag;
|
GMOCK_FLAG_SET(verbose, old_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that when the stack_frames_to_skip parameter is negative,
|
// Tests that when the stack_frames_to_skip parameter is negative,
|
||||||
// Log() doesn't include the stack trace in the output.
|
// Log() doesn't include the stack trace in the output.
|
||||||
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
|
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
Log(kInfo, "Test log.\n", -1);
|
Log(kInfo, "Test log.\n", -1);
|
||||||
EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str());
|
EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str());
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface {
|
struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface {
|
||||||
@ -500,10 +500,10 @@ TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
|
|||||||
// and log severity.
|
// and log severity.
|
||||||
std::string GrabOutput(void(*logger)(), const char* verbosity) {
|
std::string GrabOutput(void(*logger)(), const char* verbosity) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||||
GMOCK_FLAG(verbose) = verbosity;
|
GMOCK_FLAG_SET(verbose, verbosity);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
logger();
|
logger();
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
return GetCapturedStdout();
|
return GetCapturedStdout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ class Mock {
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace gmock_nice_strict_test {
|
namespace gmock_nice_strict_test {
|
||||||
|
|
||||||
using testing::GMOCK_FLAG(verbose);
|
|
||||||
using testing::HasSubstr;
|
using testing::HasSubstr;
|
||||||
using testing::NaggyMock;
|
using testing::NaggyMock;
|
||||||
using testing::NiceMock;
|
using testing::NiceMock;
|
||||||
@ -140,8 +139,8 @@ class MockBaz {
|
|||||||
|
|
||||||
// Tests that a raw mock generates warnings for uninteresting calls.
|
// Tests that a raw mock generates warnings for uninteresting calls.
|
||||||
TEST(RawMockTest, WarningForUninterestingCall) {
|
TEST(RawMockTest, WarningForUninterestingCall) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
MockFoo raw_foo;
|
MockFoo raw_foo;
|
||||||
|
|
||||||
@ -151,14 +150,14 @@ TEST(RawMockTest, WarningForUninterestingCall) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that a raw mock generates warnings for uninteresting calls
|
// Tests that a raw mock generates warnings for uninteresting calls
|
||||||
// that delete the mock object.
|
// that delete the mock object.
|
||||||
TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
MockFoo* const raw_foo = new MockFoo;
|
MockFoo* const raw_foo = new MockFoo;
|
||||||
|
|
||||||
@ -170,7 +169,7 @@ TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that a raw mock generates informational logs for
|
// Tests that a raw mock generates informational logs for
|
||||||
@ -178,14 +177,14 @@ TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
|||||||
TEST(RawMockTest, InfoForUninterestingCall) {
|
TEST(RawMockTest, InfoForUninterestingCall) {
|
||||||
MockFoo raw_foo;
|
MockFoo raw_foo;
|
||||||
|
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "info";
|
GMOCK_FLAG_SET(verbose, "info");
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
raw_foo.DoThis();
|
raw_foo.DoThis();
|
||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RawMockTest, IsNaggy_IsNice_IsStrict) {
|
TEST(RawMockTest, IsNaggy_IsNice_IsStrict) {
|
||||||
@ -223,14 +222,14 @@ TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) {
|
|||||||
TEST(NiceMockTest, InfoForUninterestingCall) {
|
TEST(NiceMockTest, InfoForUninterestingCall) {
|
||||||
NiceMock<MockFoo> nice_foo;
|
NiceMock<MockFoo> nice_foo;
|
||||||
|
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "info";
|
GMOCK_FLAG_SET(verbose, "info");
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
nice_foo.DoThis();
|
nice_foo.DoThis();
|
||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
@ -326,8 +325,8 @@ TEST(NiceMockTest, IsNaggy_IsNice_IsStrict) {
|
|||||||
|
|
||||||
// Tests that a naggy mock generates warnings for uninteresting calls.
|
// Tests that a naggy mock generates warnings for uninteresting calls.
|
||||||
TEST(NaggyMockTest, WarningForUninterestingCall) {
|
TEST(NaggyMockTest, WarningForUninterestingCall) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
NaggyMock<MockFoo> naggy_foo;
|
NaggyMock<MockFoo> naggy_foo;
|
||||||
|
|
||||||
@ -337,14 +336,14 @@ TEST(NaggyMockTest, WarningForUninterestingCall) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that a naggy mock generates a warning for an uninteresting call
|
// Tests that a naggy mock generates a warning for an uninteresting call
|
||||||
// that deletes the mock object.
|
// that deletes the mock object.
|
||||||
TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>;
|
NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>;
|
||||||
|
|
||||||
@ -356,7 +355,7 @@ TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
@ -419,8 +418,8 @@ TEST(NaggyMockTest, AcceptsClassNamedMock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(NaggyMockTest, IsNaggyInDestructor) {
|
TEST(NaggyMockTest, IsNaggyInDestructor) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -431,7 +430,7 @@ TEST(NaggyMockTest, IsNaggyInDestructor) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) {
|
TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) {
|
||||||
|
@ -76,7 +76,6 @@ using testing::DoDefault;
|
|||||||
using testing::Eq;
|
using testing::Eq;
|
||||||
using testing::Expectation;
|
using testing::Expectation;
|
||||||
using testing::ExpectationSet;
|
using testing::ExpectationSet;
|
||||||
using testing::GMOCK_FLAG(verbose);
|
|
||||||
using testing::Gt;
|
using testing::Gt;
|
||||||
using testing::IgnoreResult;
|
using testing::IgnoreResult;
|
||||||
using testing::InSequence;
|
using testing::InSequence;
|
||||||
@ -696,9 +695,9 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||||
int original_behavior = testing::GMOCK_FLAG(default_mock_behavior);
|
int original_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||||
|
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = kAllow;
|
GMOCK_FLAG_SET(default_mock_behavior, kAllow);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
{
|
{
|
||||||
MockA a;
|
MockA a;
|
||||||
@ -707,7 +706,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
|||||||
std::string output = GetCapturedStdout();
|
std::string output = GetCapturedStdout();
|
||||||
EXPECT_TRUE(output.empty()) << output;
|
EXPECT_TRUE(output.empty()) << output;
|
||||||
|
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = kWarn;
|
GMOCK_FLAG_SET(default_mock_behavior, kWarn);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
{
|
{
|
||||||
MockA a;
|
MockA a;
|
||||||
@ -718,14 +717,14 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
|||||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||||
warning_output);
|
warning_output);
|
||||||
|
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = kFail;
|
GMOCK_FLAG_SET(default_mock_behavior, kFail);
|
||||||
EXPECT_NONFATAL_FAILURE({
|
EXPECT_NONFATAL_FAILURE({
|
||||||
MockA a;
|
MockA a;
|
||||||
a.DoA(0);
|
a.DoA(0);
|
||||||
}, "Uninteresting mock function call");
|
}, "Uninteresting mock function call");
|
||||||
|
|
||||||
// Out of bounds values are converted to kWarn
|
// Out of bounds values are converted to kWarn
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = -1;
|
GMOCK_FLAG_SET(default_mock_behavior, -1);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
{
|
{
|
||||||
MockA a;
|
MockA a;
|
||||||
@ -735,7 +734,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
|||||||
EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
|
EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
|
||||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||||
warning_output);
|
warning_output);
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = 3;
|
GMOCK_FLAG_SET(default_mock_behavior, 3);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
{
|
{
|
||||||
MockA a;
|
MockA a;
|
||||||
@ -746,7 +745,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
|||||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||||
warning_output);
|
warning_output);
|
||||||
|
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = original_behavior;
|
GMOCK_FLAG_SET(default_mock_behavior, original_behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
@ -2024,10 +2023,10 @@ class MockC {
|
|||||||
class VerboseFlagPreservingFixture : public testing::Test {
|
class VerboseFlagPreservingFixture : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
VerboseFlagPreservingFixture()
|
VerboseFlagPreservingFixture()
|
||||||
: saved_verbose_flag_(GMOCK_FLAG(verbose)) {}
|
: saved_verbose_flag_(GMOCK_FLAG_GET(verbose)) {}
|
||||||
|
|
||||||
~VerboseFlagPreservingFixture() override {
|
~VerboseFlagPreservingFixture() override {
|
||||||
GMOCK_FLAG(verbose) = saved_verbose_flag_;
|
GMOCK_FLAG_SET(verbose, saved_verbose_flag_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -2043,7 +2042,7 @@ class VerboseFlagPreservingFixture : public testing::Test {
|
|||||||
// --gmock_verbose=warning is specified.
|
// --gmock_verbose=warning is specified.
|
||||||
TEST(FunctionCallMessageTest,
|
TEST(FunctionCallMessageTest,
|
||||||
UninterestingCallOnNaggyMockGeneratesNoStackTraceWhenVerboseWarning) {
|
UninterestingCallOnNaggyMockGeneratesNoStackTraceWhenVerboseWarning) {
|
||||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||||
NaggyMock<MockC> c;
|
NaggyMock<MockC> c;
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
||||||
@ -2057,7 +2056,7 @@ TEST(FunctionCallMessageTest,
|
|||||||
// --gmock_verbose=info is specified.
|
// --gmock_verbose=info is specified.
|
||||||
TEST(FunctionCallMessageTest,
|
TEST(FunctionCallMessageTest,
|
||||||
UninterestingCallOnNaggyMockGeneratesFyiWithStackTraceWhenVerboseInfo) {
|
UninterestingCallOnNaggyMockGeneratesFyiWithStackTraceWhenVerboseInfo) {
|
||||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||||
NaggyMock<MockC> c;
|
NaggyMock<MockC> c;
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
||||||
@ -2213,7 +2212,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
|
|||||||
// Tests that --gmock_verbose=info causes both expected and
|
// Tests that --gmock_verbose=info causes both expected and
|
||||||
// uninteresting calls to be reported.
|
// uninteresting calls to be reported.
|
||||||
TEST_F(GMockVerboseFlagTest, Info) {
|
TEST_F(GMockVerboseFlagTest, Info) {
|
||||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||||
TestExpectedCall(true);
|
TestExpectedCall(true);
|
||||||
TestUninterestingCallOnNaggyMock(true);
|
TestUninterestingCallOnNaggyMock(true);
|
||||||
}
|
}
|
||||||
@ -2221,7 +2220,7 @@ TEST_F(GMockVerboseFlagTest, Info) {
|
|||||||
// Tests that --gmock_verbose=warning causes uninteresting calls to be
|
// Tests that --gmock_verbose=warning causes uninteresting calls to be
|
||||||
// reported.
|
// reported.
|
||||||
TEST_F(GMockVerboseFlagTest, Warning) {
|
TEST_F(GMockVerboseFlagTest, Warning) {
|
||||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||||
TestExpectedCall(false);
|
TestExpectedCall(false);
|
||||||
TestUninterestingCallOnNaggyMock(true);
|
TestUninterestingCallOnNaggyMock(true);
|
||||||
}
|
}
|
||||||
@ -2229,7 +2228,7 @@ TEST_F(GMockVerboseFlagTest, Warning) {
|
|||||||
// Tests that --gmock_verbose=warning causes neither expected nor
|
// Tests that --gmock_verbose=warning causes neither expected nor
|
||||||
// uninteresting calls to be reported.
|
// uninteresting calls to be reported.
|
||||||
TEST_F(GMockVerboseFlagTest, Error) {
|
TEST_F(GMockVerboseFlagTest, Error) {
|
||||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||||
TestExpectedCall(false);
|
TestExpectedCall(false);
|
||||||
TestUninterestingCallOnNaggyMock(false);
|
TestUninterestingCallOnNaggyMock(false);
|
||||||
}
|
}
|
||||||
@ -2237,7 +2236,7 @@ TEST_F(GMockVerboseFlagTest, Error) {
|
|||||||
// Tests that --gmock_verbose=SOME_INVALID_VALUE has the same effect
|
// Tests that --gmock_verbose=SOME_INVALID_VALUE has the same effect
|
||||||
// as --gmock_verbose=warning.
|
// as --gmock_verbose=warning.
|
||||||
TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) {
|
TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) {
|
||||||
GMOCK_FLAG(verbose) = "invalid"; // Treated as "warning".
|
GMOCK_FLAG_SET(verbose, "invalid"); // Treated as "warning".
|
||||||
TestExpectedCall(false);
|
TestExpectedCall(false);
|
||||||
TestUninterestingCallOnNaggyMock(true);
|
TestUninterestingCallOnNaggyMock(true);
|
||||||
}
|
}
|
||||||
@ -2270,21 +2269,21 @@ class GMockLogTest : public VerboseFlagPreservingFixture {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsWarning) {
|
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsWarning) {
|
||||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||||
EXPECT_CALL(helper_, Foo(_))
|
EXPECT_CALL(helper_, Foo(_))
|
||||||
.WillOnce(Return(PrintMeNot()));
|
.WillOnce(Return(PrintMeNot()));
|
||||||
helper_.Foo(PrintMeNot()); // This is an expected call.
|
helper_.Foo(PrintMeNot()); // This is an expected call.
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsError) {
|
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsError) {
|
||||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||||
EXPECT_CALL(helper_, Foo(_))
|
EXPECT_CALL(helper_, Foo(_))
|
||||||
.WillOnce(Return(PrintMeNot()));
|
.WillOnce(Return(PrintMeNot()));
|
||||||
helper_.Foo(PrintMeNot()); // This is an expected call.
|
helper_.Foo(PrintMeNot()); // This is an expected call.
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GMockLogTest, DoesNotPrintWarningInternallyIfVerbosityIsError) {
|
TEST_F(GMockLogTest, DoesNotPrintWarningInternallyIfVerbosityIsError) {
|
||||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||||
ON_CALL(helper_, Foo(_))
|
ON_CALL(helper_, Foo(_))
|
||||||
.WillByDefault(Return(PrintMeNot()));
|
.WillByDefault(Return(PrintMeNot()));
|
||||||
helper_.Foo(PrintMeNot()); // This should generate a warning.
|
helper_.Foo(PrintMeNot()); // This should generate a warning.
|
||||||
@ -2768,8 +2767,8 @@ int main(int argc, char **argv) {
|
|||||||
testing::InitGoogleMock(&argc, argv);
|
testing::InitGoogleMock(&argc, argv);
|
||||||
// Ensures that the tests pass no matter what value of
|
// Ensures that the tests pass no matter what value of
|
||||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||||
testing::GMOCK_FLAG(catch_leaked_mocks) = true;
|
GMOCK_FLAG_SET(catch_leaked_mocks, true);
|
||||||
testing::GMOCK_FLAG(verbose) = testing::internal::kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, testing::internal::kWarningVerbosity);
|
||||||
|
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
@ -72,21 +72,21 @@ class GMockOutputTest : public testing::Test {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(GMockOutputTest, ExpectedCall) {
|
TEST_F(GMockOutputTest, ExpectedCall) {
|
||||||
testing::GMOCK_FLAG(verbose) = "info";
|
GMOCK_FLAG_SET(verbose, "info");
|
||||||
|
|
||||||
EXPECT_CALL(foo_, Bar2(0, _));
|
EXPECT_CALL(foo_, Bar2(0, _));
|
||||||
foo_.Bar2(0, 0); // Expected call
|
foo_.Bar2(0, 0); // Expected call
|
||||||
|
|
||||||
testing::GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) {
|
TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) {
|
||||||
testing::GMOCK_FLAG(verbose) = "info";
|
GMOCK_FLAG_SET(verbose, "info");
|
||||||
|
|
||||||
EXPECT_CALL(foo_, Bar3(0, _));
|
EXPECT_CALL(foo_, Bar3(0, _));
|
||||||
foo_.Bar3(0, 0); // Expected call
|
foo_.Bar3(0, 0); // Expected call
|
||||||
|
|
||||||
testing::GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GMockOutputTest, ExplicitActionsRunOut) {
|
TEST_F(GMockOutputTest, ExplicitActionsRunOut) {
|
||||||
@ -297,8 +297,8 @@ int main(int argc, char **argv) {
|
|||||||
testing::InitGoogleMock(&argc, argv);
|
testing::InitGoogleMock(&argc, argv);
|
||||||
// Ensures that the tests pass no matter what value of
|
// Ensures that the tests pass no matter what value of
|
||||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||||
testing::GMOCK_FLAG(catch_leaked_mocks) = true;
|
GMOCK_FLAG_SET(catch_leaked_mocks, true);
|
||||||
testing::GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
TestCatchesLeakedMocksInAdHocTests();
|
TestCatchesLeakedMocksInAdHocTests();
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
|
@ -40,8 +40,6 @@
|
|||||||
|
|
||||||
#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||||
|
|
||||||
using testing::GMOCK_FLAG(default_mock_behavior);
|
|
||||||
using testing::GMOCK_FLAG(verbose);
|
|
||||||
using testing::InitGoogleMock;
|
using testing::InitGoogleMock;
|
||||||
|
|
||||||
// Verifies that calling InitGoogleMock() on argv results in new_argv,
|
// Verifies that calling InitGoogleMock() on argv results in new_argv,
|
||||||
@ -49,7 +47,7 @@ using testing::InitGoogleMock;
|
|||||||
template <typename Char, int M, int N>
|
template <typename Char, int M, int N>
|
||||||
void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
||||||
const ::std::string& expected_gmock_verbose) {
|
const ::std::string& expected_gmock_verbose) {
|
||||||
const ::std::string old_verbose = GMOCK_FLAG(verbose);
|
const ::std::string old_verbose = GMOCK_FLAG_GET(verbose);
|
||||||
|
|
||||||
int argc = M - 1;
|
int argc = M - 1;
|
||||||
InitGoogleMock(&argc, const_cast<Char**>(argv));
|
InitGoogleMock(&argc, const_cast<Char**>(argv));
|
||||||
@ -59,8 +57,8 @@ void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
|||||||
EXPECT_STREQ(new_argv[i], argv[i]);
|
EXPECT_STREQ(new_argv[i], argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG(verbose).c_str());
|
EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG_GET(verbose));
|
||||||
GMOCK_FLAG(verbose) = old_verbose; // Restores the gmock_verbose flag.
|
GMOCK_FLAG_SET(verbose, old_verbose); // Restores the gmock_verbose flag.
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||||
@ -68,7 +66,7 @@ TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
|||||||
|
|
||||||
const char* new_argv[] = {nullptr};
|
const char* new_argv[] = {nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||||
@ -76,7 +74,7 @@ TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
|||||||
|
|
||||||
const char* new_argv[] = {"foo.exe", nullptr};
|
const char* new_argv[] = {"foo.exe", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
||||||
@ -88,16 +86,16 @@ TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesMultipleFlags) {
|
TEST(InitGoogleMockTest, ParsesMultipleFlags) {
|
||||||
int old_default_behavior = GMOCK_FLAG(default_mock_behavior);
|
int old_default_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||||
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
||||||
L"--gmock_default_mock_behavior=2", nullptr};
|
L"--gmock_default_mock_behavior=2", nullptr};
|
||||||
|
|
||||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, "info");
|
TestInitGoogleMock(argv, new_argv, "info");
|
||||||
EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior));
|
EXPECT_EQ(2, GMOCK_FLAG_GET(default_mock_behavior));
|
||||||
EXPECT_NE(2, old_default_behavior);
|
EXPECT_NE(2, old_default_behavior);
|
||||||
GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
|
GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||||
@ -105,7 +103,7 @@ TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
|||||||
|
|
||||||
const char* new_argv[] = {"foo.exe", "--non_gmock_flag=blah", nullptr};
|
const char* new_argv[] = {"foo.exe", "--non_gmock_flag=blah", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||||
@ -122,7 +120,7 @@ TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) {
|
|||||||
|
|
||||||
const wchar_t* new_argv[] = {nullptr};
|
const wchar_t* new_argv[] = {nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||||
@ -130,7 +128,7 @@ TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
|||||||
|
|
||||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
||||||
@ -142,16 +140,16 @@ TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesMultipleFlags) {
|
TEST(WideInitGoogleMockTest, ParsesMultipleFlags) {
|
||||||
int old_default_behavior = GMOCK_FLAG(default_mock_behavior);
|
int old_default_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||||
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
||||||
L"--gmock_default_mock_behavior=2", nullptr};
|
L"--gmock_default_mock_behavior=2", nullptr};
|
||||||
|
|
||||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, "info");
|
TestInitGoogleMock(argv, new_argv, "info");
|
||||||
EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior));
|
EXPECT_EQ(2, GMOCK_FLAG_GET(default_mock_behavior));
|
||||||
EXPECT_NE(2, old_default_behavior);
|
EXPECT_NE(2, old_default_behavior);
|
||||||
GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
|
GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||||
@ -159,7 +157,7 @@ TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
|||||||
|
|
||||||
const wchar_t* new_argv[] = {L"foo.exe", L"--non_gmock_flag=blah", nullptr};
|
const wchar_t* new_argv[] = {L"foo.exe", L"--non_gmock_flag=blah", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||||
@ -175,7 +173,7 @@ TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
|||||||
|
|
||||||
// Makes sure Google Mock flags can be accessed in code.
|
// Makes sure Google Mock flags can be accessed in code.
|
||||||
TEST(FlagTest, IsAccessibleInCode) {
|
TEST(FlagTest, IsAccessibleInCode) {
|
||||||
bool dummy = testing::GMOCK_FLAG(catch_leaked_mocks) &&
|
bool dummy =
|
||||||
testing::GMOCK_FLAG(verbose) == "";
|
GMOCK_FLAG_GET(catch_leaked_mocks) && GMOCK_FLAG_GET(verbose) == "";
|
||||||
(void)dummy; // Avoids the "unused local variable" warning.
|
(void)dummy; // Avoids the "unused local variable" warning.
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user