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/internal/gmock-internal-utils.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Declares Google Mock flags that we want a user to use programmatically.
|
||||
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
||||
GMOCK_DECLARE_string_(verbose);
|
||||
GMOCK_DECLARE_int32_(default_mock_behavior);
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses the command line for the flags
|
||||
// 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_int32_(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_)
|
||||
|
||||
// Macros for declaring flags.
|
||||
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
||||
# define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name)
|
||||
# define GMOCK_DECLARE_string_(name) \
|
||||
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_bool_(name) \
|
||||
namespace testing { \
|
||||
GTEST_API_ extern bool 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.
|
||||
# define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
|
||||
# define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val)
|
||||
# define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
||||
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
namespace testing { \
|
||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \
|
||||
}
|
||||
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
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_)
|
||||
|
||||
#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_
|
||||
|
@ -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
|
||||
// according to the --gmock_verbose flag.
|
||||
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.
|
||||
return true;
|
||||
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
||||
} else if (GMOCK_FLAG_GET(verbose) == kErrorVerbosity) {
|
||||
// Always hide it if --gmock_verbose=error.
|
||||
return false;
|
||||
} else {
|
||||
|
@ -283,7 +283,7 @@ GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
||||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
||||
// Include a stack trace only if --gmock_verbose=info is specified.
|
||||
const int stack_frames_to_skip =
|
||||
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1;
|
||||
GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1;
|
||||
switch (reaction) {
|
||||
case kAllow:
|
||||
Log(kInfo, msg, stack_frames_to_skip);
|
||||
@ -613,8 +613,7 @@ class MockObjectRegistry {
|
||||
// object alive. Therefore we report any living object as test
|
||||
// failure, unless the user explicitly asked us to ignore it.
|
||||
~MockObjectRegistry() {
|
||||
if (!GMOCK_FLAG(catch_leaked_mocks))
|
||||
return;
|
||||
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
||||
|
||||
int leaked_count = 0;
|
||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||
@ -716,9 +715,10 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
||||
internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
|
||||
g_uninteresting_call_reaction[mock_obj];
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0)
|
||||
? internal::intToCallReaction(
|
||||
GMOCK_FLAG_GET(default_mock_behavior))
|
||||
: g_uninteresting_call_reaction[mock_obj];
|
||||
}
|
||||
|
||||
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||
|
@ -31,13 +31,11 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||
"true if and only if Google Mock should report leaked "
|
||||
"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."
|
||||
" Valid values:\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"
|
||||
" 2 - by default, mocks act as StrictMocks.");
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// 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.
|
||||
static const char* ParseGoogleMockFlagValue(const char* str,
|
||||
const char* flag,
|
||||
const char* flag_name,
|
||||
bool def_optional) {
|
||||
// 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_".
|
||||
const std::string flag_str = std::string("--gmock_") + flag;
|
||||
const size_t flag_len = flag_str.length();
|
||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
|
||||
const std::string flag_name_str = std::string("--gmock_") + flag_name;
|
||||
const size_t flag_name_len = flag_name_str.length();
|
||||
if (strncmp(str, flag_name_str.c_str(), flag_name_len) != 0) return nullptr;
|
||||
|
||||
// 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.
|
||||
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
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
||||
bool* value) {
|
||||
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||
bool* value) {
|
||||
// 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.
|
||||
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
|
||||
// true. On failure, returns false without changing *value.
|
||||
template <typename String>
|
||||
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
||||
String* value) {
|
||||
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||
String* value) {
|
||||
// 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.
|
||||
if (value_str == nullptr) return false;
|
||||
@ -123,17 +122,17 @@ static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
|
||||
int32_t* value) {
|
||||
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||
int32_t* value) {
|
||||
// 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.
|
||||
if (value_str == nullptr) return false;
|
||||
|
||||
// Sets *value to the value of the flag.
|
||||
return ParseInt32(Message() << "The value of flag --" << flag,
|
||||
value_str, value);
|
||||
return ParseInt32(Message() << "The value of flag --" << flag_name, value_str,
|
||||
value);
|
||||
}
|
||||
|
||||
// The internal implementation of InitGoogleMock().
|
||||
@ -152,11 +151,22 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
|
||||
const char* const arg = arg_string.c_str();
|
||||
|
||||
// Do we see a Google Mock flag?
|
||||
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
|
||||
&GMOCK_FLAG(catch_leaked_mocks)) ||
|
||||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
|
||||
ParseGoogleMockIntFlag(arg, "default_mock_behavior",
|
||||
&GMOCK_FLAG(default_mock_behavior))) {
|
||||
bool found_gmock_flag = false;
|
||||
|
||||
#define GMOCK_INTERNAL_PARSE_FLAG(flag_name) \
|
||||
if (!found_gmock_flag) { \
|
||||
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
|
||||
// that argv has (*argc + 1) elements, the last one always being
|
||||
// NULL. The following loop moves the trailing NULL element as
|
||||
|
@ -361,27 +361,27 @@ TEST(ExpectTest, FailsNonfatallyOnFalse) {
|
||||
|
||||
class LogIsVisibleTest : public ::testing::Test {
|
||||
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_;
|
||||
};
|
||||
|
||||
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||
EXPECT_TRUE(LogIsVisible(kInfo));
|
||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||
}
|
||||
|
||||
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
|
||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||
EXPECT_FALSE(LogIsVisible(kWarning));
|
||||
}
|
||||
|
||||
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||
}
|
||||
@ -395,7 +395,7 @@ TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
||||
void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
||||
bool should_print) {
|
||||
const std::string old_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
GMOCK_FLAG_SET(verbose, verbosity);
|
||||
CaptureStdout();
|
||||
Log(severity, "Test log.\n", 0);
|
||||
if (should_print) {
|
||||
@ -407,18 +407,18 @@ void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
||||
} else {
|
||||
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,
|
||||
// Log() doesn't include the stack trace in the output.
|
||||
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||
CaptureStdout();
|
||||
Log(kInfo, "Test log.\n", -1);
|
||||
EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str());
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
}
|
||||
|
||||
struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface {
|
||||
@ -500,10 +500,10 @@ TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
|
||||
// and log severity.
|
||||
std::string GrabOutput(void(*logger)(), const char* verbosity) {
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
GMOCK_FLAG_SET(verbose, verbosity);
|
||||
CaptureStdout();
|
||||
logger();
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
return GetCapturedStdout();
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,6 @@ class Mock {
|
||||
namespace testing {
|
||||
namespace gmock_nice_strict_test {
|
||||
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::HasSubstr;
|
||||
using testing::NaggyMock;
|
||||
using testing::NiceMock;
|
||||
@ -140,8 +139,8 @@ class MockBaz {
|
||||
|
||||
// Tests that a raw mock generates warnings for uninteresting calls.
|
||||
TEST(RawMockTest, WarningForUninterestingCall) {
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
|
||||
MockFoo raw_foo;
|
||||
|
||||
@ -151,14 +150,14 @@ TEST(RawMockTest, WarningForUninterestingCall) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
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
|
||||
// that delete the mock object.
|
||||
TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
|
||||
MockFoo* const raw_foo = new MockFoo;
|
||||
|
||||
@ -170,7 +169,7 @@ TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
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
|
||||
@ -178,14 +177,14 @@ TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
TEST(RawMockTest, InfoForUninterestingCall) {
|
||||
MockFoo raw_foo;
|
||||
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "info";
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "info");
|
||||
CaptureStdout();
|
||||
raw_foo.DoThis();
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
}
|
||||
|
||||
TEST(RawMockTest, IsNaggy_IsNice_IsStrict) {
|
||||
@ -223,14 +222,14 @@ TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) {
|
||||
TEST(NiceMockTest, InfoForUninterestingCall) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "info";
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "info");
|
||||
CaptureStdout();
|
||||
nice_foo.DoThis();
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||
@ -326,8 +325,8 @@ TEST(NiceMockTest, IsNaggy_IsNice_IsStrict) {
|
||||
|
||||
// Tests that a naggy mock generates warnings for uninteresting calls.
|
||||
TEST(NaggyMockTest, WarningForUninterestingCall) {
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
|
||||
NaggyMock<MockFoo> naggy_foo;
|
||||
|
||||
@ -337,14 +336,14 @@ TEST(NaggyMockTest, WarningForUninterestingCall) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
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
|
||||
// that deletes the mock object.
|
||||
TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
|
||||
NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>;
|
||||
|
||||
@ -356,7 +355,7 @@ TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||
@ -419,8 +418,8 @@ TEST(NaggyMockTest, AcceptsClassNamedMock) {
|
||||
}
|
||||
|
||||
TEST(NaggyMockTest, IsNaggyInDestructor) {
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
CaptureStdout();
|
||||
|
||||
{
|
||||
@ -431,7 +430,7 @@ TEST(NaggyMockTest, IsNaggyInDestructor) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
}
|
||||
|
||||
TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) {
|
||||
|
@ -76,7 +76,6 @@ using testing::DoDefault;
|
||||
using testing::Eq;
|
||||
using testing::Expectation;
|
||||
using testing::ExpectationSet;
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::Gt;
|
||||
using testing::IgnoreResult;
|
||||
using testing::InSequence;
|
||||
@ -696,9 +695,9 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) {
|
||||
}
|
||||
|
||||
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();
|
||||
{
|
||||
MockA a;
|
||||
@ -707,7 +706,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||
std::string output = GetCapturedStdout();
|
||||
EXPECT_TRUE(output.empty()) << output;
|
||||
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = kWarn;
|
||||
GMOCK_FLAG_SET(default_mock_behavior, kWarn);
|
||||
CaptureStdout();
|
||||
{
|
||||
MockA a;
|
||||
@ -718,14 +717,14 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||
warning_output);
|
||||
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = kFail;
|
||||
GMOCK_FLAG_SET(default_mock_behavior, kFail);
|
||||
EXPECT_NONFATAL_FAILURE({
|
||||
MockA a;
|
||||
a.DoA(0);
|
||||
}, "Uninteresting mock function call");
|
||||
|
||||
// Out of bounds values are converted to kWarn
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = -1;
|
||||
GMOCK_FLAG_SET(default_mock_behavior, -1);
|
||||
CaptureStdout();
|
||||
{
|
||||
MockA a;
|
||||
@ -735,7 +734,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||
warning_output);
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = 3;
|
||||
GMOCK_FLAG_SET(default_mock_behavior, 3);
|
||||
CaptureStdout();
|
||||
{
|
||||
MockA a;
|
||||
@ -746,7 +745,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||
warning_output);
|
||||
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = original_behavior;
|
||||
GMOCK_FLAG_SET(default_mock_behavior, original_behavior);
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||
@ -2024,10 +2023,10 @@ class MockC {
|
||||
class VerboseFlagPreservingFixture : public testing::Test {
|
||||
protected:
|
||||
VerboseFlagPreservingFixture()
|
||||
: saved_verbose_flag_(GMOCK_FLAG(verbose)) {}
|
||||
: saved_verbose_flag_(GMOCK_FLAG_GET(verbose)) {}
|
||||
|
||||
~VerboseFlagPreservingFixture() override {
|
||||
GMOCK_FLAG(verbose) = saved_verbose_flag_;
|
||||
GMOCK_FLAG_SET(verbose, saved_verbose_flag_);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2043,7 +2042,7 @@ class VerboseFlagPreservingFixture : public testing::Test {
|
||||
// --gmock_verbose=warning is specified.
|
||||
TEST(FunctionCallMessageTest,
|
||||
UninterestingCallOnNaggyMockGeneratesNoStackTraceWhenVerboseWarning) {
|
||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||
NaggyMock<MockC> c;
|
||||
CaptureStdout();
|
||||
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
||||
@ -2057,7 +2056,7 @@ TEST(FunctionCallMessageTest,
|
||||
// --gmock_verbose=info is specified.
|
||||
TEST(FunctionCallMessageTest,
|
||||
UninterestingCallOnNaggyMockGeneratesFyiWithStackTraceWhenVerboseInfo) {
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||
NaggyMock<MockC> c;
|
||||
CaptureStdout();
|
||||
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
|
||||
// uninteresting calls to be reported.
|
||||
TEST_F(GMockVerboseFlagTest, Info) {
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||
TestExpectedCall(true);
|
||||
TestUninterestingCallOnNaggyMock(true);
|
||||
}
|
||||
@ -2221,7 +2220,7 @@ TEST_F(GMockVerboseFlagTest, Info) {
|
||||
// Tests that --gmock_verbose=warning causes uninteresting calls to be
|
||||
// reported.
|
||||
TEST_F(GMockVerboseFlagTest, Warning) {
|
||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||
TestExpectedCall(false);
|
||||
TestUninterestingCallOnNaggyMock(true);
|
||||
}
|
||||
@ -2229,7 +2228,7 @@ TEST_F(GMockVerboseFlagTest, Warning) {
|
||||
// Tests that --gmock_verbose=warning causes neither expected nor
|
||||
// uninteresting calls to be reported.
|
||||
TEST_F(GMockVerboseFlagTest, Error) {
|
||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||
TestExpectedCall(false);
|
||||
TestUninterestingCallOnNaggyMock(false);
|
||||
}
|
||||
@ -2237,7 +2236,7 @@ TEST_F(GMockVerboseFlagTest, Error) {
|
||||
// Tests that --gmock_verbose=SOME_INVALID_VALUE has the same effect
|
||||
// as --gmock_verbose=warning.
|
||||
TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) {
|
||||
GMOCK_FLAG(verbose) = "invalid"; // Treated as "warning".
|
||||
GMOCK_FLAG_SET(verbose, "invalid"); // Treated as "warning".
|
||||
TestExpectedCall(false);
|
||||
TestUninterestingCallOnNaggyMock(true);
|
||||
}
|
||||
@ -2270,21 +2269,21 @@ class GMockLogTest : public VerboseFlagPreservingFixture {
|
||||
};
|
||||
|
||||
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsWarning) {
|
||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||
EXPECT_CALL(helper_, Foo(_))
|
||||
.WillOnce(Return(PrintMeNot()));
|
||||
helper_.Foo(PrintMeNot()); // This is an expected call.
|
||||
}
|
||||
|
||||
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsError) {
|
||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||
EXPECT_CALL(helper_, Foo(_))
|
||||
.WillOnce(Return(PrintMeNot()));
|
||||
helper_.Foo(PrintMeNot()); // This is an expected call.
|
||||
}
|
||||
|
||||
TEST_F(GMockLogTest, DoesNotPrintWarningInternallyIfVerbosityIsError) {
|
||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
||||
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||
ON_CALL(helper_, Foo(_))
|
||||
.WillByDefault(Return(PrintMeNot()));
|
||||
helper_.Foo(PrintMeNot()); // This should generate a warning.
|
||||
@ -2768,8 +2767,8 @@ int main(int argc, char **argv) {
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
// Ensures that the tests pass no matter what value of
|
||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||
testing::GMOCK_FLAG(catch_leaked_mocks) = true;
|
||||
testing::GMOCK_FLAG(verbose) = testing::internal::kWarningVerbosity;
|
||||
GMOCK_FLAG_SET(catch_leaked_mocks, true);
|
||||
GMOCK_FLAG_SET(verbose, testing::internal::kWarningVerbosity);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -72,21 +72,21 @@ class GMockOutputTest : public testing::Test {
|
||||
};
|
||||
|
||||
TEST_F(GMockOutputTest, ExpectedCall) {
|
||||
testing::GMOCK_FLAG(verbose) = "info";
|
||||
GMOCK_FLAG_SET(verbose, "info");
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(0, _));
|
||||
foo_.Bar2(0, 0); // Expected call
|
||||
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) {
|
||||
testing::GMOCK_FLAG(verbose) = "info";
|
||||
GMOCK_FLAG_SET(verbose, "info");
|
||||
|
||||
EXPECT_CALL(foo_, Bar3(0, _));
|
||||
foo_.Bar3(0, 0); // Expected call
|
||||
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExplicitActionsRunOut) {
|
||||
@ -297,8 +297,8 @@ int main(int argc, char **argv) {
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
// Ensures that the tests pass no matter what value of
|
||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||
testing::GMOCK_FLAG(catch_leaked_mocks) = true;
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
GMOCK_FLAG_SET(catch_leaked_mocks, true);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
|
||||
TestCatchesLeakedMocksInAdHocTests();
|
||||
return RUN_ALL_TESTS();
|
||||
|
@ -40,8 +40,6 @@
|
||||
|
||||
#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||
|
||||
using testing::GMOCK_FLAG(default_mock_behavior);
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::InitGoogleMock;
|
||||
|
||||
// Verifies that calling InitGoogleMock() on argv results in new_argv,
|
||||
@ -49,7 +47,7 @@ using testing::InitGoogleMock;
|
||||
template <typename Char, int M, int N>
|
||||
void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
||||
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;
|
||||
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_EQ(expected_gmock_verbose, GMOCK_FLAG(verbose).c_str());
|
||||
GMOCK_FLAG(verbose) = old_verbose; // Restores the gmock_verbose flag.
|
||||
EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG_GET(verbose));
|
||||
GMOCK_FLAG_SET(verbose, old_verbose); // Restores the gmock_verbose flag.
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
@ -68,7 +66,7 @@ TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
|
||||
const char* new_argv[] = {nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
@ -76,7 +74,7 @@ TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
|
||||
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) {
|
||||
@ -88,16 +86,16 @@ TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
||||
}
|
||||
|
||||
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",
|
||||
L"--gmock_default_mock_behavior=2", nullptr};
|
||||
|
||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||
|
||||
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);
|
||||
GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
|
||||
GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior);
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
@ -105,7 +103,7 @@ TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
|
||||
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) {
|
||||
@ -122,7 +120,7 @@ TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
|
||||
const wchar_t* new_argv[] = {nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
@ -130,7 +128,7 @@ TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
|
||||
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) {
|
||||
@ -142,16 +140,16 @@ TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
||||
}
|
||||
|
||||
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",
|
||||
L"--gmock_default_mock_behavior=2", nullptr};
|
||||
|
||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||
|
||||
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);
|
||||
GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
|
||||
GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior);
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
@ -159,7 +157,7 @@ TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
|
||||
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) {
|
||||
@ -175,7 +173,7 @@ TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
|
||||
// Makes sure Google Mock flags can be accessed in code.
|
||||
TEST(FlagTest, IsAccessibleInCode) {
|
||||
bool dummy = testing::GMOCK_FLAG(catch_leaked_mocks) &&
|
||||
testing::GMOCK_FLAG(verbose) == "";
|
||||
bool dummy =
|
||||
GMOCK_FLAG_GET(catch_leaked_mocks) && GMOCK_FLAG_GET(verbose) == "";
|
||||
(void)dummy; // Avoids the "unused local variable" warning.
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user