Googletest export
Add a matcher `testing::ReturnRoundRobin` which, on each call, returns the next element in the sequence, restarting at the beginning once it has reached the end. PiperOrigin-RevId: 276312136
This commit is contained in:
parent
1110c471ca
commit
37f3227831
@ -504,7 +504,7 @@ which must be a permanent callback.
|
|||||||
|
|
||||||
<!-- mdformat off(no multiline tables) -->
|
<!-- mdformat off(no multiline tables) -->
|
||||||
| | |
|
| | |
|
||||||
| :-------------------------- | :-------------------------------------------- |
|
| :-------------------------------- | :-------------------------------------------- |
|
||||||
| `Return()` | Return from a `void` mock function. |
|
| `Return()` | Return from a `void` mock function. |
|
||||||
| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type <i>at the time the expectation is set</i>, not when the action is executed. |
|
| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type <i>at the time the expectation is set</i>, not when the action is executed. |
|
||||||
| `ReturnArg<N>()` | Return the `N`-th (0-based) argument. |
|
| `ReturnArg<N>()` | Return the `N`-th (0-based) argument. |
|
||||||
@ -513,6 +513,7 @@ which must be a permanent callback.
|
|||||||
| `ReturnPointee(ptr)` | Return the value pointed to by `ptr`. |
|
| `ReturnPointee(ptr)` | Return the value pointed to by `ptr`. |
|
||||||
| `ReturnRef(variable)` | Return a reference to `variable`. |
|
| `ReturnRef(variable)` | Return a reference to `variable`. |
|
||||||
| `ReturnRefOfCopy(value)` | Return a reference to a copy of `value`; the copy lives as long as the action. |
|
| `ReturnRefOfCopy(value)` | Return a reference to a copy of `value`; the copy lives as long as the action. |
|
||||||
|
| `ReturnRoundRobin({a1, ..., ak})` | Each call will return the next `ai` in the list, starting at the beginning when the end of the list is reached. |
|
||||||
<!-- mdformat on -->
|
<!-- mdformat on -->
|
||||||
|
|
||||||
#### Side Effects
|
#### Side Effects
|
||||||
|
@ -716,6 +716,36 @@ class ReturnRefOfCopyAction {
|
|||||||
GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction);
|
GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Implements the polymorphic ReturnRoundRobin(v) action, which can be
|
||||||
|
// used in any function that returns the element_type of v.
|
||||||
|
template <typename T>
|
||||||
|
class ReturnRoundRobinAction {
|
||||||
|
public:
|
||||||
|
explicit ReturnRoundRobinAction(std::vector<T> values) {
|
||||||
|
GTEST_CHECK_(!values.empty())
|
||||||
|
<< "ReturnRoundRobin requires at least one element.";
|
||||||
|
state_->values = std::move(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
T operator()(Args&&...) const {
|
||||||
|
return state_->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct State {
|
||||||
|
T Next() {
|
||||||
|
T ret_val = values[i++];
|
||||||
|
if (i == values.size()) i = 0;
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<T> values;
|
||||||
|
size_t i = 0;
|
||||||
|
};
|
||||||
|
std::shared_ptr<State> state_ = std::make_shared<State>();
|
||||||
|
};
|
||||||
|
|
||||||
// Implements the polymorphic DoDefault() action.
|
// Implements the polymorphic DoDefault() action.
|
||||||
class DoDefaultAction {
|
class DoDefaultAction {
|
||||||
public:
|
public:
|
||||||
@ -1039,6 +1069,23 @@ internal::ByMoveWrapper<R> ByMove(R x) {
|
|||||||
return internal::ByMoveWrapper<R>(std::move(x));
|
return internal::ByMoveWrapper<R>(std::move(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates an action that returns an element of `vals`. Calling this action will
|
||||||
|
// repeatedly return the next value from `vals` until it reaches the end and
|
||||||
|
// will restart from the beginning.
|
||||||
|
template <typename T>
|
||||||
|
internal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) {
|
||||||
|
return internal::ReturnRoundRobinAction<T>(std::move(vals));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an action that returns an element of `vals`. Calling this action will
|
||||||
|
// repeatedly return the next value from `vals` until it reaches the end and
|
||||||
|
// will restart from the beginning.
|
||||||
|
template <typename T>
|
||||||
|
internal::ReturnRoundRobinAction<T> ReturnRoundRobin(
|
||||||
|
std::initializer_list<T> vals) {
|
||||||
|
return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals));
|
||||||
|
}
|
||||||
|
|
||||||
// Creates an action that does the default action for the give mock function.
|
// Creates an action that does the default action for the give mock function.
|
||||||
inline internal::DoDefaultAction DoDefault() {
|
inline internal::DoDefaultAction DoDefault() {
|
||||||
return internal::DoDefaultAction();
|
return internal::DoDefaultAction();
|
||||||
|
5
googlemock/scripts/README.md
Normal file
5
googlemock/scripts/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Please Note:
|
||||||
|
|
||||||
|
Files in this directory are no longer supported by the maintainers. They
|
||||||
|
represent mosty historical artifacts and supported by the community only. There
|
||||||
|
is no guarantee whatsoever that these scripts still work.
|
@ -17,10 +17,7 @@
|
|||||||
|
|
||||||
"""Generate an Abstract Syntax Tree (AST) for C++."""
|
"""Generate an Abstract Syntax Tree (AST) for C++."""
|
||||||
|
|
||||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
# FIXME:
|
||||||
|
|
||||||
|
|
||||||
# TODO:
|
|
||||||
# * Tokens should never be exported, need to convert to Nodes
|
# * Tokens should never be exported, need to convert to Nodes
|
||||||
# (return types, parameters, etc.)
|
# (return types, parameters, etc.)
|
||||||
# * Handle static class data for templatized classes
|
# * Handle static class data for templatized classes
|
||||||
@ -338,7 +335,7 @@ class Class(_GenericDeclaration):
|
|||||||
# TODO(nnorwitz): handle namespaces, etc.
|
# TODO(nnorwitz): handle namespaces, etc.
|
||||||
if self.bases:
|
if self.bases:
|
||||||
for token_list in self.bases:
|
for token_list in self.bases:
|
||||||
# TODO(nnorwitz): bases are tokens, do name comparison.
|
# TODO(nnorwitz): bases are tokens, do name comparision.
|
||||||
for token in token_list:
|
for token in token_list:
|
||||||
if token.name == node.name:
|
if token.name == node.name:
|
||||||
return True
|
return True
|
||||||
@ -381,7 +378,7 @@ class Function(_GenericDeclaration):
|
|||||||
|
|
||||||
def Requires(self, node):
|
def Requires(self, node):
|
||||||
if self.parameters:
|
if self.parameters:
|
||||||
# TODO(nnorwitz): parameters are tokens, do name comparison.
|
# TODO(nnorwitz): parameters are tokens, do name comparision.
|
||||||
for p in self.parameters:
|
for p in self.parameters:
|
||||||
if p.name == node.name:
|
if p.name == node.name:
|
||||||
return True
|
return True
|
||||||
@ -739,6 +736,14 @@ class AstBuilder(object):
|
|||||||
if token.token_type == tokenize.NAME:
|
if token.token_type == tokenize.NAME:
|
||||||
if (keywords.IsKeyword(token.name) and
|
if (keywords.IsKeyword(token.name) and
|
||||||
not keywords.IsBuiltinType(token.name)):
|
not keywords.IsBuiltinType(token.name)):
|
||||||
|
if token.name == 'enum':
|
||||||
|
# Pop the next token and only put it back if it's not
|
||||||
|
# 'class'. This allows us to support the two-token
|
||||||
|
# 'enum class' keyword as if it were simply 'enum'.
|
||||||
|
next = self._GetNextToken()
|
||||||
|
if next.name != 'class':
|
||||||
|
self._AddBackToken(next)
|
||||||
|
|
||||||
method = getattr(self, 'handle_' + token.name)
|
method = getattr(self, 'handle_' + token.name)
|
||||||
return method()
|
return method()
|
||||||
elif token.name == self.in_class_name_only:
|
elif token.name == self.in_class_name_only:
|
||||||
@ -754,7 +759,8 @@ class AstBuilder(object):
|
|||||||
# Handle data or function declaration/definition.
|
# Handle data or function declaration/definition.
|
||||||
syntax = tokenize.SYNTAX
|
syntax = tokenize.SYNTAX
|
||||||
temp_tokens, last_token = \
|
temp_tokens, last_token = \
|
||||||
self._GetVarTokensUpTo(syntax, '(', ';', '{', '[')
|
self._GetVarTokensUpToIgnoringTemplates(syntax,
|
||||||
|
'(', ';', '{', '[')
|
||||||
temp_tokens.insert(0, token)
|
temp_tokens.insert(0, token)
|
||||||
if last_token.name == '(':
|
if last_token.name == '(':
|
||||||
# If there is an assignment before the paren,
|
# If there is an assignment before the paren,
|
||||||
@ -858,7 +864,25 @@ class AstBuilder(object):
|
|||||||
last_token = self._GetNextToken()
|
last_token = self._GetNextToken()
|
||||||
return tokens, last_token
|
return tokens, last_token
|
||||||
|
|
||||||
# TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necessary.
|
# Same as _GetVarTokensUpTo, but skips over '<...>' which could contain an
|
||||||
|
# expected token.
|
||||||
|
def _GetVarTokensUpToIgnoringTemplates(self, expected_token_type,
|
||||||
|
*expected_tokens):
|
||||||
|
last_token = self._GetNextToken()
|
||||||
|
tokens = []
|
||||||
|
nesting = 0
|
||||||
|
while (nesting > 0 or
|
||||||
|
last_token.token_type != expected_token_type or
|
||||||
|
last_token.name not in expected_tokens):
|
||||||
|
tokens.append(last_token)
|
||||||
|
last_token = self._GetNextToken()
|
||||||
|
if last_token.name == '<':
|
||||||
|
nesting += 1
|
||||||
|
elif last_token.name == '>':
|
||||||
|
nesting -= 1
|
||||||
|
return tokens, last_token
|
||||||
|
|
||||||
|
# TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary.
|
||||||
def _IgnoreUpTo(self, token_type, token):
|
def _IgnoreUpTo(self, token_type, token):
|
||||||
unused_tokens = self._GetTokensUpTo(token_type, token)
|
unused_tokens = self._GetTokensUpTo(token_type, token)
|
||||||
|
|
||||||
@ -1264,9 +1288,6 @@ class AstBuilder(object):
|
|||||||
return self._GetNestedType(Union)
|
return self._GetNestedType(Union)
|
||||||
|
|
||||||
def handle_enum(self):
|
def handle_enum(self):
|
||||||
token = self._GetNextToken()
|
|
||||||
if not (token.token_type == tokenize.NAME and token.name == 'class'):
|
|
||||||
self._AddBackToken(token)
|
|
||||||
return self._GetNestedType(Enum)
|
return self._GetNestedType(Enum)
|
||||||
|
|
||||||
def handle_auto(self):
|
def handle_auto(self):
|
||||||
@ -1298,7 +1319,8 @@ class AstBuilder(object):
|
|||||||
if token2.token_type == tokenize.SYNTAX and token2.name == '~':
|
if token2.token_type == tokenize.SYNTAX and token2.name == '~':
|
||||||
return self.GetMethod(FUNCTION_VIRTUAL + FUNCTION_DTOR, None)
|
return self.GetMethod(FUNCTION_VIRTUAL + FUNCTION_DTOR, None)
|
||||||
assert token.token_type == tokenize.NAME or token.name == '::', token
|
assert token.token_type == tokenize.NAME or token.name == '::', token
|
||||||
return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(') # )
|
return_type_and_name, _ = self._GetVarTokensUpToIgnoringTemplates(
|
||||||
|
tokenize.SYNTAX, '(') # )
|
||||||
return_type_and_name.insert(0, token)
|
return_type_and_name.insert(0, token)
|
||||||
if token2 is not token:
|
if token2 is not token:
|
||||||
return_type_and_name.insert(1, token2)
|
return_type_and_name.insert(1, token2)
|
||||||
|
@ -1,18 +1,33 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
# Copyright 2008, Google Inc.
|
||||||
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# you may not use this file except in compliance with the License.
|
# modification, are permitted provided that the following conditions are
|
||||||
# You may obtain a copy of the License at
|
# met:
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# * 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.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
# See the License for the specific language governing permissions and
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
# limitations under the License.
|
# 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.
|
||||||
|
|
||||||
"""Generate Google Mock classes from base classes.
|
"""Generate Google Mock classes from base classes.
|
||||||
|
|
||||||
@ -26,9 +41,6 @@ Usage:
|
|||||||
Output is sent to stdout.
|
Output is sent to stdout.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
@ -48,6 +60,50 @@ _VERSION = (1, 0, 1) # The version of this script.
|
|||||||
_INDENT = 2
|
_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 and a boolean to indicate whether we have multiple args
|
||||||
|
(which is not handled correctly).
|
||||||
|
"""
|
||||||
|
has_multiarg_error = False
|
||||||
|
# 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, e = _RenderType(arg)
|
||||||
|
if e: has_multiarg_error = True
|
||||||
|
template_args.append(rendered_arg)
|
||||||
|
return_type += '<' + ', '.join(template_args) + '>'
|
||||||
|
# We are actually not handling multi-template-args correctly. So mark it.
|
||||||
|
if len(template_args) > 1:
|
||||||
|
has_multiarg_error = True
|
||||||
|
if ast_type.pointer:
|
||||||
|
return_type += '*'
|
||||||
|
if ast_type.reference:
|
||||||
|
return_type += '&'
|
||||||
|
return return_type, has_multiarg_error
|
||||||
|
|
||||||
|
|
||||||
|
def _GetNumParameters(parameters, source):
|
||||||
|
num_parameters = len(parameters)
|
||||||
|
if num_parameters == 1:
|
||||||
|
first_param = parameters[0]
|
||||||
|
if source[first_param.start:first_param.end].strip() == 'void':
|
||||||
|
# We must treat T(void) as a function with no parameters.
|
||||||
|
return 0
|
||||||
|
return num_parameters
|
||||||
|
|
||||||
|
|
||||||
def _GenerateMethods(output_lines, source, class_node):
|
def _GenerateMethods(output_lines, source, class_node):
|
||||||
function_type = (ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL |
|
function_type = (ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL |
|
||||||
ast.FUNCTION_OVERRIDE)
|
ast.FUNCTION_OVERRIDE)
|
||||||
@ -63,32 +119,16 @@ def _GenerateMethods(output_lines, source, class_node):
|
|||||||
const = ''
|
const = ''
|
||||||
if node.modifiers & ast.FUNCTION_CONST:
|
if node.modifiers & ast.FUNCTION_CONST:
|
||||||
const = 'CONST_'
|
const = 'CONST_'
|
||||||
|
num_parameters = _GetNumParameters(node.parameters, source)
|
||||||
return_type = 'void'
|
return_type = 'void'
|
||||||
if node.return_type:
|
if node.return_type:
|
||||||
# Add modifiers like 'const'.
|
return_type, has_multiarg_error = _RenderType(node.return_type)
|
||||||
modifiers = ''
|
if has_multiarg_error:
|
||||||
if node.return_type.modifiers:
|
|
||||||
modifiers = ' '.join(node.return_type.modifiers) + ' '
|
|
||||||
return_type = modifiers + node.return_type.name
|
|
||||||
template_args = [arg.name for arg in node.return_type.templated_types]
|
|
||||||
if template_args:
|
|
||||||
return_type += '<' + ', '.join(template_args) + '>'
|
|
||||||
if len(template_args) > 1:
|
|
||||||
for line in [
|
for line in [
|
||||||
'// The following line won\'t really compile, as the return',
|
'// The following line won\'t really compile, as the return',
|
||||||
'// type has multiple template arguments. To fix it, use a',
|
'// type has multiple template arguments. To fix it, use a',
|
||||||
'// typedef for the return type.']:
|
'// typedef for the return type.']:
|
||||||
output_lines.append(indent + line)
|
output_lines.append(indent + line)
|
||||||
if node.return_type.pointer:
|
|
||||||
return_type += '*'
|
|
||||||
if node.return_type.reference:
|
|
||||||
return_type += '&'
|
|
||||||
num_parameters = len(node.parameters)
|
|
||||||
if len(node.parameters) == 1:
|
|
||||||
first_param = node.parameters[0]
|
|
||||||
if source[first_param.start:first_param.end].strip() == 'void':
|
|
||||||
# We must treat T(void) as a function with no parameters.
|
|
||||||
num_parameters = 0
|
|
||||||
tmpl = ''
|
tmpl = ''
|
||||||
if class_node.templated_types:
|
if class_node.templated_types:
|
||||||
tmpl = '_T'
|
tmpl = '_T'
|
||||||
|
@ -1,25 +1,36 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright 2009 Neal Norwitz All Rights Reserved.
|
# Copyright 2009, Google Inc.
|
||||||
# Portions Copyright 2009 Google Inc. All Rights Reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# you may not use this file except in compliance with the License.
|
# modification, are permitted provided that the following conditions are
|
||||||
# You may obtain a copy of the License at
|
# met:
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# * 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.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
# See the License for the specific language governing permissions and
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
# limitations under the License.
|
# 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.
|
||||||
|
|
||||||
"""Tests for gmock.scripts.generator.cpp.gmock_class."""
|
"""Tests for gmock.scripts.generator.cpp.gmock_class."""
|
||||||
|
|
||||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
@ -444,19 +455,63 @@ void(const FooType& test_arg));
|
|||||||
self.assertEqualIgnoreLeadingWhitespace(
|
self.assertEqualIgnoreLeadingWhitespace(
|
||||||
expected, self.GenerateMocks(source))
|
expected, self.GenerateMocks(source))
|
||||||
|
|
||||||
def testEnumClass(self):
|
def testEnumType(self):
|
||||||
source = """
|
source = """
|
||||||
class Test {
|
class Test {
|
||||||
public:
|
public:
|
||||||
enum class Baz { BAZINGA };
|
enum Bar {
|
||||||
virtual void Bar(const FooType& test_arg);
|
BAZ, QUX, QUUX, QUUUX
|
||||||
|
};
|
||||||
|
virtual void Foo();
|
||||||
};
|
};
|
||||||
"""
|
"""
|
||||||
expected = """\
|
expected = """\
|
||||||
class MockTest : public Test {
|
class MockTest : public Test {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD1(Bar,
|
MOCK_METHOD0(Foo,
|
||||||
void(const FooType& test_arg));
|
void());
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
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_METHOD0(Foo,
|
||||||
|
void());
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
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_METHOD0(foo,
|
||||||
|
std::function<int (std::string)>());
|
||||||
};
|
};
|
||||||
"""
|
"""
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
self.assertEqualIgnoreLeadingWhitespace(
|
||||||
|
@ -1,25 +1,36 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright 2007 Neal Norwitz
|
# Copyright 2007, Google Inc.
|
||||||
# Portions Copyright 2007 Google Inc.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# you may not use this file except in compliance with the License.
|
# modification, are permitted provided that the following conditions are
|
||||||
# You may obtain a copy of the License at
|
# met:
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# * 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.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
# See the License for the specific language governing permissions and
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
# limitations under the License.
|
# 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.
|
||||||
|
|
||||||
"""C++ keywords and helper utilities for determining keywords."""
|
"""C++ keywords and helper utilities for determining keywords."""
|
||||||
|
|
||||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Python 3.x
|
# Python 3.x
|
||||||
import builtins
|
import builtins
|
||||||
|
@ -1,25 +1,36 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright 2007 Neal Norwitz
|
# Copyright 2007, Google Inc.
|
||||||
# Portions Copyright 2007 Google Inc.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# you may not use this file except in compliance with the License.
|
# modification, are permitted provided that the following conditions are
|
||||||
# You may obtain a copy of the License at
|
# met:
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# * 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.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
# See the License for the specific language governing permissions and
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
# limitations under the License.
|
# 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.
|
||||||
|
|
||||||
"""Tokenize C++ source code."""
|
"""Tokenize C++ source code."""
|
||||||
|
|
||||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Python 3.x
|
# Python 3.x
|
||||||
import builtins
|
import builtins
|
||||||
|
@ -1,28 +1,38 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright 2007 Neal Norwitz
|
# Copyright 2007, Google Inc.
|
||||||
# Portions Copyright 2007 Google Inc.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# you may not use this file except in compliance with the License.
|
# modification, are permitted provided that the following conditions are
|
||||||
# You may obtain a copy of the License at
|
# met:
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# * 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.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
# See the License for the specific language governing permissions and
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
# limitations under the License.
|
# 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.
|
||||||
|
|
||||||
"""Generic utilities for C++ parsing."""
|
"""Generic utilities for C++ parsing."""
|
||||||
|
|
||||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
|
||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
# Set to True to see the start/end token indices.
|
# Set to True to see the start/end token indices.
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
|
@ -1,22 +1,36 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
# Copyright 2008, Google Inc.
|
||||||
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# you may not use this file except in compliance with the License.
|
# modification, are permitted provided that the following conditions are
|
||||||
# You may obtain a copy of the License at
|
# met:
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# * 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.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
# See the License for the specific language governing permissions and
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
# limitations under the License.
|
# 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.
|
||||||
|
|
||||||
"""Driver for starting up Google Mock class generator."""
|
"""Driver for starting up Google Mock class generator."""
|
||||||
|
|
||||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -1,303 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# These variables are automatically filled in by the configure script.
|
|
||||||
name="@PACKAGE_TARNAME@"
|
|
||||||
version="@PACKAGE_VERSION@"
|
|
||||||
|
|
||||||
show_usage()
|
|
||||||
{
|
|
||||||
echo "Usage: gmock-config [OPTIONS...]"
|
|
||||||
}
|
|
||||||
|
|
||||||
show_help()
|
|
||||||
{
|
|
||||||
show_usage
|
|
||||||
cat <<\EOF
|
|
||||||
|
|
||||||
The `gmock-config' script provides access to the necessary compile and linking
|
|
||||||
flags to connect with Google C++ Mocking Framework, both in a build prior to
|
|
||||||
installation, and on the system proper after installation. The installation
|
|
||||||
overrides may be issued in combination with any other queries, but will only
|
|
||||||
affect installation queries if called on a built but not installed gmock. The
|
|
||||||
installation queries may not be issued with any other types of queries, and
|
|
||||||
only one installation query may be made at a time. The version queries and
|
|
||||||
compiler flag queries may be combined as desired but not mixed. Different
|
|
||||||
version queries are always combined with logical "and" semantics, and only the
|
|
||||||
last of any particular query is used while all previous ones ignored. All
|
|
||||||
versions must be specified as a sequence of numbers separated by periods.
|
|
||||||
Compiler flag queries output the union of the sets of flags when combined.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
gmock-config --min-version=1.0 || echo "Insufficient Google Mock version."
|
|
||||||
|
|
||||||
g++ $(gmock-config --cppflags --cxxflags) -o foo.o -c foo.cpp
|
|
||||||
g++ $(gmock-config --ldflags --libs) -o foo foo.o
|
|
||||||
|
|
||||||
# When using a built but not installed Google Mock:
|
|
||||||
g++ $(../../my_gmock_build/scripts/gmock-config ...) ...
|
|
||||||
|
|
||||||
# When using an installed Google Mock, but with installation overrides:
|
|
||||||
export GMOCK_PREFIX="/opt"
|
|
||||||
g++ $(gmock-config --libdir="/opt/lib64" ...) ...
|
|
||||||
|
|
||||||
Help:
|
|
||||||
--usage brief usage information
|
|
||||||
--help display this help message
|
|
||||||
|
|
||||||
Installation Overrides:
|
|
||||||
--prefix=<dir> overrides the installation prefix
|
|
||||||
--exec-prefix=<dir> overrides the executable installation prefix
|
|
||||||
--libdir=<dir> overrides the library installation prefix
|
|
||||||
--includedir=<dir> overrides the header file installation prefix
|
|
||||||
|
|
||||||
Installation Queries:
|
|
||||||
--prefix installation prefix
|
|
||||||
--exec-prefix executable installation prefix
|
|
||||||
--libdir library installation directory
|
|
||||||
--includedir header file installation directory
|
|
||||||
--version the version of the Google Mock installation
|
|
||||||
|
|
||||||
Version Queries:
|
|
||||||
--min-version=VERSION return 0 if the version is at least VERSION
|
|
||||||
--exact-version=VERSION return 0 if the version is exactly VERSION
|
|
||||||
--max-version=VERSION return 0 if the version is at most VERSION
|
|
||||||
|
|
||||||
Compilation Flag Queries:
|
|
||||||
--cppflags compile flags specific to the C-like preprocessors
|
|
||||||
--cxxflags compile flags appropriate for C++ programs
|
|
||||||
--ldflags linker flags
|
|
||||||
--libs libraries for linking
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# This function bounds our version with a min and a max. It uses some clever
|
|
||||||
# POSIX-compliant variable expansion to portably do all the work in the shell
|
|
||||||
# and avoid any dependency on a particular "sed" or "awk" implementation.
|
|
||||||
# Notable is that it will only ever compare the first 3 components of versions.
|
|
||||||
# Further components will be cleanly stripped off. All versions must be
|
|
||||||
# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and
|
|
||||||
# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should
|
|
||||||
# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than
|
|
||||||
# continuing to maintain our own shell version.
|
|
||||||
check_versions()
|
|
||||||
{
|
|
||||||
major_version=${version%%.*}
|
|
||||||
minor_version="0"
|
|
||||||
point_version="0"
|
|
||||||
if test "${version#*.}" != "${version}"; then
|
|
||||||
minor_version=${version#*.}
|
|
||||||
minor_version=${minor_version%%.*}
|
|
||||||
fi
|
|
||||||
if test "${version#*.*.}" != "${version}"; then
|
|
||||||
point_version=${version#*.*.}
|
|
||||||
point_version=${point_version%%.*}
|
|
||||||
fi
|
|
||||||
|
|
||||||
min_version="$1"
|
|
||||||
min_major_version=${min_version%%.*}
|
|
||||||
min_minor_version="0"
|
|
||||||
min_point_version="0"
|
|
||||||
if test "${min_version#*.}" != "${min_version}"; then
|
|
||||||
min_minor_version=${min_version#*.}
|
|
||||||
min_minor_version=${min_minor_version%%.*}
|
|
||||||
fi
|
|
||||||
if test "${min_version#*.*.}" != "${min_version}"; then
|
|
||||||
min_point_version=${min_version#*.*.}
|
|
||||||
min_point_version=${min_point_version%%.*}
|
|
||||||
fi
|
|
||||||
|
|
||||||
max_version="$2"
|
|
||||||
max_major_version=${max_version%%.*}
|
|
||||||
max_minor_version="0"
|
|
||||||
max_point_version="0"
|
|
||||||
if test "${max_version#*.}" != "${max_version}"; then
|
|
||||||
max_minor_version=${max_version#*.}
|
|
||||||
max_minor_version=${max_minor_version%%.*}
|
|
||||||
fi
|
|
||||||
if test "${max_version#*.*.}" != "${max_version}"; then
|
|
||||||
max_point_version=${max_version#*.*.}
|
|
||||||
max_point_version=${max_point_version%%.*}
|
|
||||||
fi
|
|
||||||
|
|
||||||
test $(($major_version)) -lt $(($min_major_version)) && exit 1
|
|
||||||
if test $(($major_version)) -eq $(($min_major_version)); then
|
|
||||||
test $(($minor_version)) -lt $(($min_minor_version)) && exit 1
|
|
||||||
if test $(($minor_version)) -eq $(($min_minor_version)); then
|
|
||||||
test $(($point_version)) -lt $(($min_point_version)) && exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
test $(($major_version)) -gt $(($max_major_version)) && exit 1
|
|
||||||
if test $(($major_version)) -eq $(($max_major_version)); then
|
|
||||||
test $(($minor_version)) -gt $(($max_minor_version)) && exit 1
|
|
||||||
if test $(($minor_version)) -eq $(($max_minor_version)); then
|
|
||||||
test $(($point_version)) -gt $(($max_point_version)) && exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Show the usage line when no arguments are specified.
|
|
||||||
if test $# -eq 0; then
|
|
||||||
show_usage
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
while test $# -gt 0; do
|
|
||||||
case $1 in
|
|
||||||
--usage) show_usage; exit 0;;
|
|
||||||
--help) show_help; exit 0;;
|
|
||||||
|
|
||||||
# Installation overrides
|
|
||||||
--prefix=*) GMOCK_PREFIX=${1#--prefix=};;
|
|
||||||
--exec-prefix=*) GMOCK_EXEC_PREFIX=${1#--exec-prefix=};;
|
|
||||||
--libdir=*) GMOCK_LIBDIR=${1#--libdir=};;
|
|
||||||
--includedir=*) GMOCK_INCLUDEDIR=${1#--includedir=};;
|
|
||||||
|
|
||||||
# Installation queries
|
|
||||||
--prefix|--exec-prefix|--libdir|--includedir|--version)
|
|
||||||
if test -n "${do_query}"; then
|
|
||||||
show_usage
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
do_query=${1#--}
|
|
||||||
;;
|
|
||||||
|
|
||||||
# Version checking
|
|
||||||
--min-version=*)
|
|
||||||
do_check_versions=yes
|
|
||||||
min_version=${1#--min-version=}
|
|
||||||
;;
|
|
||||||
--max-version=*)
|
|
||||||
do_check_versions=yes
|
|
||||||
max_version=${1#--max-version=}
|
|
||||||
;;
|
|
||||||
--exact-version=*)
|
|
||||||
do_check_versions=yes
|
|
||||||
exact_version=${1#--exact-version=}
|
|
||||||
;;
|
|
||||||
|
|
||||||
# Compiler flag output
|
|
||||||
--cppflags) echo_cppflags=yes;;
|
|
||||||
--cxxflags) echo_cxxflags=yes;;
|
|
||||||
--ldflags) echo_ldflags=yes;;
|
|
||||||
--libs) echo_libs=yes;;
|
|
||||||
|
|
||||||
# Everything else is an error
|
|
||||||
*) show_usage; exit 1;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
# These have defaults filled in by the configure script but can also be
|
|
||||||
# overridden by environment variables or command line parameters.
|
|
||||||
prefix="${GMOCK_PREFIX:-@prefix@}"
|
|
||||||
exec_prefix="${GMOCK_EXEC_PREFIX:-@exec_prefix@}"
|
|
||||||
libdir="${GMOCK_LIBDIR:-@libdir@}"
|
|
||||||
includedir="${GMOCK_INCLUDEDIR:-@includedir@}"
|
|
||||||
|
|
||||||
# We try and detect if our binary is not located at its installed location. If
|
|
||||||
# it's not, we provide variables pointing to the source and build tree rather
|
|
||||||
# than to the install tree. We also locate Google Test using the configured
|
|
||||||
# gtest-config script rather than searching the PATH and our bindir for one.
|
|
||||||
# This allows building against a just-built gmock rather than an installed
|
|
||||||
# gmock.
|
|
||||||
bindir="@bindir@"
|
|
||||||
this_relative_bindir=`dirname $0`
|
|
||||||
this_bindir=`cd ${this_relative_bindir}; pwd -P`
|
|
||||||
if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
|
|
||||||
# The path to the script doesn't end in the bindir sequence from Autoconf,
|
|
||||||
# assume that we are in a build tree.
|
|
||||||
build_dir=`dirname ${this_bindir}`
|
|
||||||
src_dir=`cd ${this_bindir}/@top_srcdir@; pwd -P`
|
|
||||||
|
|
||||||
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
|
|
||||||
# should work to remove it, and/or remove libtool altogether, replacing it
|
|
||||||
# with direct references to the library and a link path.
|
|
||||||
gmock_libs="${build_dir}/lib/libgmock.la"
|
|
||||||
gmock_ldflags=""
|
|
||||||
|
|
||||||
# We provide hooks to include from either the source or build dir, where the
|
|
||||||
# build dir is always preferred. This will potentially allow us to write
|
|
||||||
# build rules for generated headers and have them automatically be preferred
|
|
||||||
# over provided versions.
|
|
||||||
gmock_cppflags="-I${build_dir}/include -I${src_dir}/include"
|
|
||||||
gmock_cxxflags=""
|
|
||||||
|
|
||||||
# Directly invoke the gtest-config script used during the build process.
|
|
||||||
gtest_config="@GTEST_CONFIG@"
|
|
||||||
else
|
|
||||||
# We're using an installed gmock, although it may be staged under some
|
|
||||||
# prefix. Assume (as our own libraries do) that we can resolve the prefix,
|
|
||||||
# and are present in the dynamic link paths.
|
|
||||||
gmock_ldflags="-L${libdir}"
|
|
||||||
gmock_libs="-l${name}"
|
|
||||||
gmock_cppflags="-I${includedir}"
|
|
||||||
gmock_cxxflags=""
|
|
||||||
|
|
||||||
# We also prefer any gtest-config script installed in our prefix. Lacking
|
|
||||||
# one, we look in the PATH for one.
|
|
||||||
gtest_config="${bindir}/gtest-config"
|
|
||||||
if test ! -x "${gtest_config}"; then
|
|
||||||
gtest_config=`which gtest-config`
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ensure that we have located a Google Test to link against.
|
|
||||||
if ! test -x "${gtest_config}"; then
|
|
||||||
echo "Unable to locate Google Test, check your Google Mock configuration" \
|
|
||||||
"and installation" >&2
|
|
||||||
exit 1
|
|
||||||
elif ! "${gtest_config}" "--exact-version=@GTEST_VERSION@"; then
|
|
||||||
echo "The Google Test found is not the same version as Google Mock was " \
|
|
||||||
"built against" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add the necessary Google Test bits into the various flag variables
|
|
||||||
gmock_cppflags="${gmock_cppflags} `${gtest_config} --cppflags`"
|
|
||||||
gmock_cxxflags="${gmock_cxxflags} `${gtest_config} --cxxflags`"
|
|
||||||
gmock_ldflags="${gmock_ldflags} `${gtest_config} --ldflags`"
|
|
||||||
gmock_libs="${gmock_libs} `${gtest_config} --libs`"
|
|
||||||
|
|
||||||
# Do an installation query if requested.
|
|
||||||
if test -n "$do_query"; then
|
|
||||||
case $do_query in
|
|
||||||
prefix) echo $prefix; exit 0;;
|
|
||||||
exec-prefix) echo $exec_prefix; exit 0;;
|
|
||||||
libdir) echo $libdir; exit 0;;
|
|
||||||
includedir) echo $includedir; exit 0;;
|
|
||||||
version) echo $version; exit 0;;
|
|
||||||
*) show_usage; exit 1;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Do a version check if requested.
|
|
||||||
if test "$do_check_versions" = "yes"; then
|
|
||||||
# Make sure we didn't receive a bad combination of parameters.
|
|
||||||
test "$echo_cppflags" = "yes" && show_usage && exit 1
|
|
||||||
test "$echo_cxxflags" = "yes" && show_usage && exit 1
|
|
||||||
test "$echo_ldflags" = "yes" && show_usage && exit 1
|
|
||||||
test "$echo_libs" = "yes" && show_usage && exit 1
|
|
||||||
|
|
||||||
if test "$exact_version" != ""; then
|
|
||||||
check_versions $exact_version $exact_version
|
|
||||||
# unreachable
|
|
||||||
else
|
|
||||||
check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999}
|
|
||||||
# unreachable
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Do the output in the correct order so that these can be used in-line of
|
|
||||||
# a compiler invocation.
|
|
||||||
output=""
|
|
||||||
test "$echo_cppflags" = "yes" && output="$output $gmock_cppflags"
|
|
||||||
test "$echo_cxxflags" = "yes" && output="$output $gmock_cxxflags"
|
|
||||||
test "$echo_ldflags" = "yes" && output="$output $gmock_ldflags"
|
|
||||||
test "$echo_libs" = "yes" && output="$output $gmock_libs"
|
|
||||||
echo $output
|
|
||||||
|
|
||||||
exit 0
|
|
@ -1,640 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2008, 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.
|
|
||||||
|
|
||||||
"""Converts compiler's errors in code using Google Mock to plain English."""
|
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
|
||||||
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
_VERSION = '1.0.3'
|
|
||||||
|
|
||||||
_EMAIL = 'googlemock@googlegroups.com'
|
|
||||||
|
|
||||||
_COMMON_GMOCK_SYMBOLS = [
|
|
||||||
# Matchers
|
|
||||||
'_',
|
|
||||||
'A',
|
|
||||||
'AddressSatisfies',
|
|
||||||
'AllOf',
|
|
||||||
'An',
|
|
||||||
'AnyOf',
|
|
||||||
'ContainerEq',
|
|
||||||
'Contains',
|
|
||||||
'ContainsRegex',
|
|
||||||
'DoubleEq',
|
|
||||||
'ElementsAre',
|
|
||||||
'ElementsAreArray',
|
|
||||||
'EndsWith',
|
|
||||||
'Eq',
|
|
||||||
'Field',
|
|
||||||
'FloatEq',
|
|
||||||
'Ge',
|
|
||||||
'Gt',
|
|
||||||
'HasSubstr',
|
|
||||||
'IsInitializedProto',
|
|
||||||
'Le',
|
|
||||||
'Lt',
|
|
||||||
'MatcherCast',
|
|
||||||
'Matches',
|
|
||||||
'MatchesRegex',
|
|
||||||
'NanSensitiveDoubleEq',
|
|
||||||
'NanSensitiveFloatEq',
|
|
||||||
'Ne',
|
|
||||||
'Not',
|
|
||||||
'NotNull',
|
|
||||||
'Pointee',
|
|
||||||
'Property',
|
|
||||||
'Ref',
|
|
||||||
'ResultOf',
|
|
||||||
'SafeMatcherCast',
|
|
||||||
'StartsWith',
|
|
||||||
'StrCaseEq',
|
|
||||||
'StrCaseNe',
|
|
||||||
'StrEq',
|
|
||||||
'StrNe',
|
|
||||||
'Truly',
|
|
||||||
'TypedEq',
|
|
||||||
'Value',
|
|
||||||
|
|
||||||
# Actions
|
|
||||||
'Assign',
|
|
||||||
'ByRef',
|
|
||||||
'DeleteArg',
|
|
||||||
'DoAll',
|
|
||||||
'DoDefault',
|
|
||||||
'IgnoreResult',
|
|
||||||
'Invoke',
|
|
||||||
'InvokeArgument',
|
|
||||||
'InvokeWithoutArgs',
|
|
||||||
'Return',
|
|
||||||
'ReturnNew',
|
|
||||||
'ReturnNull',
|
|
||||||
'ReturnRef',
|
|
||||||
'SaveArg',
|
|
||||||
'SetArgReferee',
|
|
||||||
'SetArgPointee',
|
|
||||||
'SetArgumentPointee',
|
|
||||||
'SetArrayArgument',
|
|
||||||
'SetErrnoAndReturn',
|
|
||||||
'Throw',
|
|
||||||
'WithArg',
|
|
||||||
'WithArgs',
|
|
||||||
'WithoutArgs',
|
|
||||||
|
|
||||||
# Cardinalities
|
|
||||||
'AnyNumber',
|
|
||||||
'AtLeast',
|
|
||||||
'AtMost',
|
|
||||||
'Between',
|
|
||||||
'Exactly',
|
|
||||||
|
|
||||||
# Sequences
|
|
||||||
'InSequence',
|
|
||||||
'Sequence',
|
|
||||||
|
|
||||||
# Misc
|
|
||||||
'DefaultValue',
|
|
||||||
'Mock',
|
|
||||||
]
|
|
||||||
|
|
||||||
# Regex for matching source file path and line number in the compiler's errors.
|
|
||||||
_GCC_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):(\d+:)?\s+'
|
|
||||||
_CLANG_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):(?P<column>\d+):\s+'
|
|
||||||
_CLANG_NON_GMOCK_FILE_LINE_RE = (
|
|
||||||
r'(?P<file>.*[/\\^](?!gmock-)[^/\\]+):(?P<line>\d+):(?P<column>\d+):\s+')
|
|
||||||
|
|
||||||
|
|
||||||
def _FindAllMatches(regex, s):
|
|
||||||
"""Generates all matches of regex in string s."""
|
|
||||||
|
|
||||||
r = re.compile(regex)
|
|
||||||
return r.finditer(s)
|
|
||||||
|
|
||||||
|
|
||||||
def _GenericDiagnoser(short_name, long_name, diagnoses, msg):
|
|
||||||
"""Diagnoses the given disease by pattern matching.
|
|
||||||
|
|
||||||
Can provide different diagnoses for different patterns.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
short_name: Short name of the disease.
|
|
||||||
long_name: Long name of the disease.
|
|
||||||
diagnoses: A list of pairs (regex, pattern for formatting the diagnosis
|
|
||||||
for matching regex).
|
|
||||||
msg: Compiler's error messages.
|
|
||||||
Yields:
|
|
||||||
Tuples of the form
|
|
||||||
(short name of disease, long name of disease, diagnosis).
|
|
||||||
"""
|
|
||||||
for regex, diagnosis in diagnoses:
|
|
||||||
if re.search(regex, msg):
|
|
||||||
diagnosis = '%(file)s:%(line)s:' + diagnosis
|
|
||||||
for m in _FindAllMatches(regex, msg):
|
|
||||||
yield (short_name, long_name, diagnosis % m.groupdict())
|
|
||||||
|
|
||||||
|
|
||||||
def _NeedToReturnReferenceDiagnoser(msg):
|
|
||||||
"""Diagnoses the NRR disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (r'In member function \'testing::internal::ReturnAction<R>.*\n'
|
|
||||||
+ _GCC_FILE_LINE_RE + r'instantiated from here\n'
|
|
||||||
r'.*gmock-actions\.h.*error: creating array with negative size')
|
|
||||||
clang_regex = (r'error:.*array.*negative.*\r?\n'
|
|
||||||
r'(.*\n)*?' +
|
|
||||||
_CLANG_NON_GMOCK_FILE_LINE_RE +
|
|
||||||
r'note: in instantiation of function template specialization '
|
|
||||||
r'\'testing::internal::ReturnAction<(?P<type>.*)>'
|
|
||||||
r'::operator Action<.*>\' requested here')
|
|
||||||
clang11_re = (r'use_ReturnRef_instead_of_Return_to_return_a_reference.*'
|
|
||||||
r'(.*\n)*?' + _CLANG_NON_GMOCK_FILE_LINE_RE)
|
|
||||||
|
|
||||||
diagnosis = """
|
|
||||||
You are using a Return() action in a function that returns a reference to
|
|
||||||
%(type)s. Please use ReturnRef() instead."""
|
|
||||||
return _GenericDiagnoser('NRR', 'Need to Return Reference',
|
|
||||||
[(clang_regex, diagnosis),
|
|
||||||
(clang11_re, diagnosis % {'type': 'a type'}),
|
|
||||||
(gcc_regex, diagnosis % {'type': 'a type'})],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _NeedToReturnSomethingDiagnoser(msg):
|
|
||||||
"""Diagnoses the NRS disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE + r'(instantiated from here\n.'
|
|
||||||
r'*gmock.*actions\.h.*error: void value not ignored)'
|
|
||||||
r'|(error: control reaches end of non-void function)')
|
|
||||||
clang_regex1 = (_CLANG_FILE_LINE_RE +
|
|
||||||
r'error: cannot initialize return object '
|
|
||||||
r'of type \'Result\' \(aka \'(?P<return_type>.*)\'\) '
|
|
||||||
r'with an rvalue of type \'void\'')
|
|
||||||
clang_regex2 = (_CLANG_FILE_LINE_RE +
|
|
||||||
r'error: cannot initialize return object '
|
|
||||||
r'of type \'(?P<return_type>.*)\' '
|
|
||||||
r'with an rvalue of type \'void\'')
|
|
||||||
diagnosis = """
|
|
||||||
You are using an action that returns void, but it needs to return
|
|
||||||
%(return_type)s. Please tell it *what* to return. Perhaps you can use
|
|
||||||
the pattern DoAll(some_action, Return(some_value))?"""
|
|
||||||
return _GenericDiagnoser(
|
|
||||||
'NRS',
|
|
||||||
'Need to Return Something',
|
|
||||||
[(gcc_regex, diagnosis % {'return_type': '*something*'}),
|
|
||||||
(clang_regex1, diagnosis),
|
|
||||||
(clang_regex2, diagnosis)],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _NeedToReturnNothingDiagnoser(msg):
|
|
||||||
"""Diagnoses the NRN disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n'
|
|
||||||
r'.*gmock-actions\.h.*error: instantiation of '
|
|
||||||
r'\'testing::internal::ReturnAction<R>::Impl<F>::value_\' '
|
|
||||||
r'as type \'void\'')
|
|
||||||
clang_regex1 = (r'error: field has incomplete type '
|
|
||||||
r'\'Result\' \(aka \'void\'\)(\r)?\n'
|
|
||||||
r'(.*\n)*?' +
|
|
||||||
_CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
|
|
||||||
r'of function template specialization '
|
|
||||||
r'\'testing::internal::ReturnAction<(?P<return_type>.*)>'
|
|
||||||
r'::operator Action<void \(.*\)>\' requested here')
|
|
||||||
clang_regex2 = (r'error: field has incomplete type '
|
|
||||||
r'\'Result\' \(aka \'void\'\)(\r)?\n'
|
|
||||||
r'(.*\n)*?' +
|
|
||||||
_CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
|
|
||||||
r'of function template specialization '
|
|
||||||
r'\'testing::internal::DoBothAction<.*>'
|
|
||||||
r'::operator Action<(?P<return_type>.*) \(.*\)>\' '
|
|
||||||
r'requested here')
|
|
||||||
diagnosis = """
|
|
||||||
You are using an action that returns %(return_type)s, but it needs to return
|
|
||||||
void. Please use a void-returning action instead.
|
|
||||||
|
|
||||||
All actions but the last in DoAll(...) must return void. Perhaps you need
|
|
||||||
to re-arrange the order of actions in a DoAll(), if you are using one?"""
|
|
||||||
return _GenericDiagnoser(
|
|
||||||
'NRN',
|
|
||||||
'Need to Return Nothing',
|
|
||||||
[(gcc_regex, diagnosis % {'return_type': '*something*'}),
|
|
||||||
(clang_regex1, diagnosis),
|
|
||||||
(clang_regex2, diagnosis)],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _IncompleteByReferenceArgumentDiagnoser(msg):
|
|
||||||
"""Diagnoses the IBRA disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n'
|
|
||||||
r'.*gtest-printers\.h.*error: invalid application of '
|
|
||||||
r'\'sizeof\' to incomplete type \'(?P<type>.*)\'')
|
|
||||||
|
|
||||||
clang_regex = (r'.*gtest-printers\.h.*error: invalid application of '
|
|
||||||
r'\'sizeof\' to an incomplete type '
|
|
||||||
r'\'(?P<type>.*)( const)?\'\r?\n'
|
|
||||||
r'(.*\n)*?' +
|
|
||||||
_CLANG_NON_GMOCK_FILE_LINE_RE +
|
|
||||||
r'note: in instantiation of member function '
|
|
||||||
r'\'testing::internal2::TypeWithoutFormatter<.*>::'
|
|
||||||
r'PrintValue\' requested here')
|
|
||||||
diagnosis = """
|
|
||||||
In order to mock this function, Google Mock needs to see the definition
|
|
||||||
of type "%(type)s" - declaration alone is not enough. Either #include
|
|
||||||
the header that defines it, or change the argument to be passed
|
|
||||||
by pointer."""
|
|
||||||
|
|
||||||
return _GenericDiagnoser('IBRA', 'Incomplete By-Reference Argument Type',
|
|
||||||
[(gcc_regex, diagnosis),
|
|
||||||
(clang_regex, diagnosis)],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _OverloadedFunctionMatcherDiagnoser(msg):
|
|
||||||
"""Diagnoses the OFM disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for '
|
|
||||||
r'call to \'Truly\(<unresolved overloaded function type>\)')
|
|
||||||
clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function for '
|
|
||||||
r'call to \'Truly')
|
|
||||||
diagnosis = """
|
|
||||||
The argument you gave to Truly() is an overloaded function. Please tell
|
|
||||||
your compiler which overloaded version you want to use.
|
|
||||||
|
|
||||||
For example, if you want to use the version whose signature is
|
|
||||||
bool Foo(int n);
|
|
||||||
you should write
|
|
||||||
Truly(static_cast<bool (*)(int n)>(Foo))"""
|
|
||||||
return _GenericDiagnoser('OFM', 'Overloaded Function Matcher',
|
|
||||||
[(gcc_regex, diagnosis),
|
|
||||||
(clang_regex, diagnosis)],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _OverloadedFunctionActionDiagnoser(msg):
|
|
||||||
"""Diagnoses the OFA disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for call to '
|
|
||||||
r'\'Invoke\(<unresolved overloaded function type>')
|
|
||||||
clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching '
|
|
||||||
r'function for call to \'Invoke\'\r?\n'
|
|
||||||
r'(.*\n)*?'
|
|
||||||
r'.*\bgmock-generated-actions\.h:\d+:\d+:\s+'
|
|
||||||
r'note: candidate template ignored:\s+'
|
|
||||||
r'couldn\'t infer template argument \'FunctionImpl\'')
|
|
||||||
diagnosis = """
|
|
||||||
Function you are passing to Invoke is overloaded. Please tell your compiler
|
|
||||||
which overloaded version you want to use.
|
|
||||||
|
|
||||||
For example, if you want to use the version whose signature is
|
|
||||||
bool MyFunction(int n, double x);
|
|
||||||
you should write something like
|
|
||||||
Invoke(static_cast<bool (*)(int n, double x)>(MyFunction))"""
|
|
||||||
return _GenericDiagnoser('OFA', 'Overloaded Function Action',
|
|
||||||
[(gcc_regex, diagnosis),
|
|
||||||
(clang_regex, diagnosis)],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _OverloadedMethodActionDiagnoser(msg):
|
|
||||||
"""Diagnoses the OMA disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for '
|
|
||||||
r'call to \'Invoke\(.+, <unresolved overloaded function '
|
|
||||||
r'type>\)')
|
|
||||||
clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function '
|
|
||||||
r'for call to \'Invoke\'\r?\n'
|
|
||||||
r'(.*\n)*?'
|
|
||||||
r'.*\bgmock-generated-actions\.h:\d+:\d+: '
|
|
||||||
r'note: candidate function template not viable: '
|
|
||||||
r'requires .*, but 2 (arguments )?were provided')
|
|
||||||
diagnosis = """
|
|
||||||
The second argument you gave to Invoke() is an overloaded method. Please
|
|
||||||
tell your compiler which overloaded version you want to use.
|
|
||||||
|
|
||||||
For example, if you want to use the version whose signature is
|
|
||||||
class Foo {
|
|
||||||
...
|
|
||||||
bool Bar(int n, double x);
|
|
||||||
};
|
|
||||||
you should write something like
|
|
||||||
Invoke(foo, static_cast<bool (Foo::*)(int n, double x)>(&Foo::Bar))"""
|
|
||||||
return _GenericDiagnoser('OMA', 'Overloaded Method Action',
|
|
||||||
[(gcc_regex, diagnosis),
|
|
||||||
(clang_regex, diagnosis)],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _MockObjectPointerDiagnoser(msg):
|
|
||||||
"""Diagnoses the MOP disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: request for member '
|
|
||||||
r'\'gmock_(?P<method>.+)\' in \'(?P<mock_object>.+)\', '
|
|
||||||
r'which is of non-class type \'(.*::)*(?P<class_name>.+)\*\'')
|
|
||||||
clang_regex = (_CLANG_FILE_LINE_RE + r'error: member reference type '
|
|
||||||
r'\'(?P<class_name>.*?) *\' is a pointer; '
|
|
||||||
r'(did you mean|maybe you meant) to use \'->\'\?')
|
|
||||||
diagnosis = """
|
|
||||||
The first argument to ON_CALL() and EXPECT_CALL() must be a mock *object*,
|
|
||||||
not a *pointer* to it. Please write '*(%(mock_object)s)' instead of
|
|
||||||
'%(mock_object)s' as your first argument.
|
|
||||||
|
|
||||||
For example, given the mock class:
|
|
||||||
|
|
||||||
class %(class_name)s : public ... {
|
|
||||||
...
|
|
||||||
MOCK_METHOD0(%(method)s, ...);
|
|
||||||
};
|
|
||||||
|
|
||||||
and the following mock instance:
|
|
||||||
|
|
||||||
%(class_name)s* mock_ptr = ...
|
|
||||||
|
|
||||||
you should use the EXPECT_CALL like this:
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_ptr, %(method)s(...));"""
|
|
||||||
|
|
||||||
return _GenericDiagnoser(
|
|
||||||
'MOP',
|
|
||||||
'Mock Object Pointer',
|
|
||||||
[(gcc_regex, diagnosis),
|
|
||||||
(clang_regex, diagnosis % {'mock_object': 'mock_object',
|
|
||||||
'method': 'method',
|
|
||||||
'class_name': '%(class_name)s'})],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _NeedToUseSymbolDiagnoser(msg):
|
|
||||||
"""Diagnoses the NUS disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: \'(?P<symbol>.+)\' '
|
|
||||||
r'(was not declared in this scope|has not been declared)')
|
|
||||||
clang_regex = (_CLANG_FILE_LINE_RE +
|
|
||||||
r'error: (use of undeclared identifier|unknown type name|'
|
|
||||||
r'no template named) \'(?P<symbol>[^\']+)\'')
|
|
||||||
diagnosis = """
|
|
||||||
'%(symbol)s' is defined by Google Mock in the testing namespace.
|
|
||||||
Did you forget to write
|
|
||||||
using testing::%(symbol)s;
|
|
||||||
?"""
|
|
||||||
for m in (list(_FindAllMatches(gcc_regex, msg)) +
|
|
||||||
list(_FindAllMatches(clang_regex, msg))):
|
|
||||||
symbol = m.groupdict()['symbol']
|
|
||||||
if symbol in _COMMON_GMOCK_SYMBOLS:
|
|
||||||
yield ('NUS', 'Need to Use Symbol', diagnosis % m.groupdict())
|
|
||||||
|
|
||||||
|
|
||||||
def _NeedToUseReturnNullDiagnoser(msg):
|
|
||||||
"""Diagnoses the NRNULL disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = ('instantiated from \'testing::internal::ReturnAction<R>'
|
|
||||||
'::operator testing::Action<Func>\(\) const.*\n' +
|
|
||||||
_GCC_FILE_LINE_RE + r'instantiated from here\n'
|
|
||||||
r'.*error: no matching function for call to \'ImplicitCast_\('
|
|
||||||
r'(:?long )?int&\)')
|
|
||||||
clang_regex = (r'\bgmock-actions.h:.* error: no matching function for '
|
|
||||||
r'call to \'ImplicitCast_\'\r?\n'
|
|
||||||
r'(.*\n)*?' +
|
|
||||||
_CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
|
|
||||||
r'of function template specialization '
|
|
||||||
r'\'testing::internal::ReturnAction<(int|long)>::operator '
|
|
||||||
r'Action<(?P<type>.*)\(\)>\' requested here')
|
|
||||||
diagnosis = """
|
|
||||||
You are probably calling Return(NULL) and the compiler isn't sure how to turn
|
|
||||||
NULL into %(type)s. Use ReturnNull() instead.
|
|
||||||
Note: the line number may be off; please fix all instances of Return(NULL)."""
|
|
||||||
return _GenericDiagnoser(
|
|
||||||
'NRNULL', 'Need to use ReturnNull',
|
|
||||||
[(clang_regex, diagnosis),
|
|
||||||
(gcc_regex, diagnosis % {'type': 'the right type'})],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _TypeInTemplatedBaseDiagnoser(msg):
|
|
||||||
"""Diagnoses the TTB disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
# This version works when the type is used as the mock function's return
|
|
||||||
# type.
|
|
||||||
gcc_4_3_1_regex_type_in_retval = (
|
|
||||||
r'In member function \'int .*\n' + _GCC_FILE_LINE_RE +
|
|
||||||
r'error: a function call cannot appear in a constant-expression')
|
|
||||||
gcc_4_4_0_regex_type_in_retval = (
|
|
||||||
r'error: a function call cannot appear in a constant-expression'
|
|
||||||
+ _GCC_FILE_LINE_RE + r'error: template argument 1 is invalid\n')
|
|
||||||
# This version works when the type is used as the mock function's sole
|
|
||||||
# parameter type.
|
|
||||||
gcc_regex_type_of_sole_param = (
|
|
||||||
_GCC_FILE_LINE_RE +
|
|
||||||
r'error: \'(?P<type>.+)\' was not declared in this scope\n'
|
|
||||||
r'.*error: template argument 1 is invalid\n')
|
|
||||||
# This version works when the type is used as a parameter of a mock
|
|
||||||
# function that has multiple parameters.
|
|
||||||
gcc_regex_type_of_a_param = (
|
|
||||||
r'error: expected `;\' before \'::\' token\n'
|
|
||||||
+ _GCC_FILE_LINE_RE +
|
|
||||||
r'error: \'(?P<type>.+)\' was not declared in this scope\n'
|
|
||||||
r'.*error: template argument 1 is invalid\n'
|
|
||||||
r'.*error: \'.+\' was not declared in this scope')
|
|
||||||
clang_regex_type_of_retval_or_sole_param = (
|
|
||||||
_CLANG_FILE_LINE_RE +
|
|
||||||
r'error: use of undeclared identifier \'(?P<type>.*)\'\n'
|
|
||||||
r'(.*\n)*?'
|
|
||||||
r'(?P=file):(?P=line):\d+: error: '
|
|
||||||
r'non-friend class member \'Result\' cannot have a qualified name'
|
|
||||||
)
|
|
||||||
clang_regex_type_of_a_param = (
|
|
||||||
_CLANG_FILE_LINE_RE +
|
|
||||||
r'error: C\+\+ requires a type specifier for all declarations\n'
|
|
||||||
r'(.*\n)*?'
|
|
||||||
r'(?P=file):(?P=line):(?P=column): error: '
|
|
||||||
r'C\+\+ requires a type specifier for all declarations'
|
|
||||||
)
|
|
||||||
clang_regex_unknown_type = (
|
|
||||||
_CLANG_FILE_LINE_RE +
|
|
||||||
r'error: unknown type name \'(?P<type>[^\']+)\''
|
|
||||||
)
|
|
||||||
|
|
||||||
diagnosis = """
|
|
||||||
In a mock class template, types or typedefs defined in the base class
|
|
||||||
template are *not* automatically visible. This is how C++ works. Before
|
|
||||||
you can use a type or typedef named %(type)s defined in base class Base<T>, you
|
|
||||||
need to make it visible. One way to do it is:
|
|
||||||
|
|
||||||
typedef typename Base<T>::%(type)s %(type)s;"""
|
|
||||||
|
|
||||||
for diag in _GenericDiagnoser(
|
|
||||||
'TTB', 'Type in Template Base',
|
|
||||||
[(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
|
|
||||||
(gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
|
|
||||||
(gcc_regex_type_of_sole_param, diagnosis),
|
|
||||||
(gcc_regex_type_of_a_param, diagnosis),
|
|
||||||
(clang_regex_type_of_retval_or_sole_param, diagnosis),
|
|
||||||
(clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})],
|
|
||||||
msg):
|
|
||||||
yield diag
|
|
||||||
# Avoid overlap with the NUS pattern.
|
|
||||||
for m in _FindAllMatches(clang_regex_unknown_type, msg):
|
|
||||||
type_ = m.groupdict()['type']
|
|
||||||
if type_ not in _COMMON_GMOCK_SYMBOLS:
|
|
||||||
yield ('TTB', 'Type in Template Base', diagnosis % m.groupdict())
|
|
||||||
|
|
||||||
|
|
||||||
def _WrongMockMethodMacroDiagnoser(msg):
|
|
||||||
"""Diagnoses the WMM disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE +
|
|
||||||
r'.*this_method_does_not_take_(?P<wrong_args>\d+)_argument.*\n'
|
|
||||||
r'.*\n'
|
|
||||||
r'.*candidates are.*FunctionMocker<[^>]+A(?P<args>\d+)\)>')
|
|
||||||
clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE +
|
|
||||||
r'error:.*array.*negative.*r?\n'
|
|
||||||
r'(.*\n)*?'
|
|
||||||
r'(?P=file):(?P=line):(?P=column): error: too few arguments '
|
|
||||||
r'to function call, expected (?P<args>\d+), '
|
|
||||||
r'have (?P<wrong_args>\d+)')
|
|
||||||
clang11_re = (_CLANG_NON_GMOCK_FILE_LINE_RE +
|
|
||||||
r'.*this_method_does_not_take_'
|
|
||||||
r'(?P<wrong_args>\d+)_argument.*')
|
|
||||||
diagnosis = """
|
|
||||||
You are using MOCK_METHOD%(wrong_args)s to define a mock method that has
|
|
||||||
%(args)s arguments. Use MOCK_METHOD%(args)s (or MOCK_CONST_METHOD%(args)s,
|
|
||||||
MOCK_METHOD%(args)s_T, MOCK_CONST_METHOD%(args)s_T as appropriate) instead."""
|
|
||||||
return _GenericDiagnoser('WMM', 'Wrong MOCK_METHODn Macro',
|
|
||||||
[(gcc_regex, diagnosis),
|
|
||||||
(clang11_re, diagnosis % {'wrong_args': 'm',
|
|
||||||
'args': 'n'}),
|
|
||||||
(clang_regex, diagnosis)],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _WrongParenPositionDiagnoser(msg):
|
|
||||||
"""Diagnoses the WPP disease, given the error messages by the compiler."""
|
|
||||||
|
|
||||||
gcc_regex = (_GCC_FILE_LINE_RE +
|
|
||||||
r'error:.*testing::internal::MockSpec<.* has no member named \''
|
|
||||||
r'(?P<method>\w+)\'')
|
|
||||||
clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE +
|
|
||||||
r'error: no member named \'(?P<method>\w+)\' in '
|
|
||||||
r'\'testing::internal::MockSpec<.*>\'')
|
|
||||||
diagnosis = """
|
|
||||||
The closing parenthesis of ON_CALL or EXPECT_CALL should be *before*
|
|
||||||
".%(method)s". For example, you should write:
|
|
||||||
EXPECT_CALL(my_mock, Foo(_)).%(method)s(...);
|
|
||||||
instead of:
|
|
||||||
EXPECT_CALL(my_mock, Foo(_).%(method)s(...));"""
|
|
||||||
return _GenericDiagnoser('WPP', 'Wrong Parenthesis Position',
|
|
||||||
[(gcc_regex, diagnosis),
|
|
||||||
(clang_regex, diagnosis)],
|
|
||||||
msg)
|
|
||||||
|
|
||||||
|
|
||||||
_DIAGNOSERS = [
|
|
||||||
_IncompleteByReferenceArgumentDiagnoser,
|
|
||||||
_MockObjectPointerDiagnoser,
|
|
||||||
_NeedToReturnNothingDiagnoser,
|
|
||||||
_NeedToReturnReferenceDiagnoser,
|
|
||||||
_NeedToReturnSomethingDiagnoser,
|
|
||||||
_NeedToUseReturnNullDiagnoser,
|
|
||||||
_NeedToUseSymbolDiagnoser,
|
|
||||||
_OverloadedFunctionActionDiagnoser,
|
|
||||||
_OverloadedFunctionMatcherDiagnoser,
|
|
||||||
_OverloadedMethodActionDiagnoser,
|
|
||||||
_TypeInTemplatedBaseDiagnoser,
|
|
||||||
_WrongMockMethodMacroDiagnoser,
|
|
||||||
_WrongParenPositionDiagnoser,
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def Diagnose(msg):
|
|
||||||
"""Generates all possible diagnoses given the compiler error message."""
|
|
||||||
|
|
||||||
msg = re.sub(r'\x1b\[[^m]*m', '', msg) # Strips all color formatting.
|
|
||||||
# Assuming the string is using the UTF-8 encoding, replaces the left and
|
|
||||||
# the right single quote characters with apostrophes.
|
|
||||||
msg = re.sub(r'(\xe2\x80\x98|\xe2\x80\x99)', "'", msg)
|
|
||||||
|
|
||||||
diagnoses = []
|
|
||||||
for diagnoser in _DIAGNOSERS:
|
|
||||||
for diag in diagnoser(msg):
|
|
||||||
diagnosis = '[%s - %s]\n%s' % diag
|
|
||||||
if not diagnosis in diagnoses:
|
|
||||||
diagnoses.append(diagnosis)
|
|
||||||
return diagnoses
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
print ('Google Mock Doctor v%s - '
|
|
||||||
'diagnoses problems in code using Google Mock.' % _VERSION)
|
|
||||||
|
|
||||||
if sys.stdin.isatty():
|
|
||||||
print ('Please copy and paste the compiler errors here. Press c-D when '
|
|
||||||
'you are done:')
|
|
||||||
else:
|
|
||||||
print ('Waiting for compiler errors on stdin . . .')
|
|
||||||
|
|
||||||
msg = sys.stdin.read().strip()
|
|
||||||
diagnoses = Diagnose(msg)
|
|
||||||
count = len(diagnoses)
|
|
||||||
if not count:
|
|
||||||
print ("""
|
|
||||||
Your compiler complained:
|
|
||||||
8<------------------------------------------------------------
|
|
||||||
%s
|
|
||||||
------------------------------------------------------------>8
|
|
||||||
|
|
||||||
Uh-oh, I'm not smart enough to figure out what the problem is. :-(
|
|
||||||
However...
|
|
||||||
If you send your source code and the compiler's error messages to
|
|
||||||
%s, you can be helped and I can get smarter --
|
|
||||||
win-win for us!""" % (msg, _EMAIL))
|
|
||||||
else:
|
|
||||||
print ('------------------------------------------------------------')
|
|
||||||
print ('Your code appears to have the following',)
|
|
||||||
if count > 1:
|
|
||||||
print ('%s diseases:' % (count,))
|
|
||||||
else:
|
|
||||||
print ('disease:')
|
|
||||||
i = 0
|
|
||||||
for d in diagnoses:
|
|
||||||
i += 1
|
|
||||||
if count > 1:
|
|
||||||
print ('\n#%s:' % (i,))
|
|
||||||
print (d)
|
|
||||||
print ("""
|
|
||||||
How did I do? If you think I'm wrong or unhelpful, please send your
|
|
||||||
source code and the compiler's error messages to %s.
|
|
||||||
Then you can be helped and I can get smarter -- I promise I won't be upset!""" %
|
|
||||||
_EMAIL)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,18 +1,33 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright 2007 Google Inc.
|
# Copyright 2009, Google Inc.
|
||||||
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# you may not use this file except in compliance with the License.
|
# modification, are permitted provided that the following conditions are
|
||||||
# You may obtain a copy of the License at
|
# met:
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# * 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.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
# See the License for the specific language governing permissions and
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
# limitations under the License.
|
# 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.
|
||||||
|
|
||||||
"""Tool for uploading diffs from a version control system to the codereview app.
|
"""Tool for uploading diffs from a version control system to the codereview app.
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ using testing::Return;
|
|||||||
using testing::ReturnNull;
|
using testing::ReturnNull;
|
||||||
using testing::ReturnRef;
|
using testing::ReturnRef;
|
||||||
using testing::ReturnRefOfCopy;
|
using testing::ReturnRefOfCopy;
|
||||||
|
using testing::ReturnRoundRobin;
|
||||||
using testing::SetArgPointee;
|
using testing::SetArgPointee;
|
||||||
using testing::SetArgumentPointee;
|
using testing::SetArgumentPointee;
|
||||||
using testing::Unused;
|
using testing::Unused;
|
||||||
@ -670,6 +671,31 @@ TEST(ReturnRefOfCopyTest, IsCovariant) {
|
|||||||
EXPECT_NE(&derived, &a.Perform(std::make_tuple()));
|
EXPECT_NE(&derived, &a.Perform(std::make_tuple()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that ReturnRoundRobin(v) works with initializer lists
|
||||||
|
TEST(ReturnRoundRobinTest, WorksForInitList) {
|
||||||
|
Action<int()> ret = ReturnRoundRobin({1, 2, 3});
|
||||||
|
|
||||||
|
EXPECT_EQ(1, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(2, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(3, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(1, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(2, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(3, ret.Perform(std::make_tuple()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that ReturnRoundRobin(v) works with vectors
|
||||||
|
TEST(ReturnRoundRobinTest, WorksForVector) {
|
||||||
|
std::vector<double> v = {4.4, 5.5, 6.6};
|
||||||
|
Action<double()> ret = ReturnRoundRobin(v);
|
||||||
|
|
||||||
|
EXPECT_EQ(4.4, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(5.5, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(6.6, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(4.4, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(5.5, ret.Perform(std::make_tuple()));
|
||||||
|
EXPECT_EQ(6.6, ret.Perform(std::make_tuple()));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that DoDefault() does the default action for the mock method.
|
// Tests that DoDefault() does the default action for the mock method.
|
||||||
|
|
||||||
class MockClass {
|
class MockClass {
|
||||||
|
5
googletest/scripts/README.md
Normal file
5
googletest/scripts/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Please Note:
|
||||||
|
|
||||||
|
Files in this directory are no longer supported by the maintainers. They
|
||||||
|
represent mosty historical artifacts and supported by the community only. There
|
||||||
|
is no guarantee whatsoever that these scripts still work.
|
@ -111,6 +111,8 @@ def HeaderPreamble(n):
|
|||||||
// '%(command)s'. DO NOT EDIT BY HAND!
|
// '%(command)s'. DO NOT EDIT BY HAND!
|
||||||
//
|
//
|
||||||
// Implements a family of generic predicate assertion macros.
|
// Implements a family of generic predicate assertion macros.
|
||||||
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||||
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||||
@ -246,8 +248,10 @@ AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS
|
|||||||
|
|
||||||
impl += ' << ") evaluates to false, where"'
|
impl += ' << ") evaluates to false, where"'
|
||||||
|
|
||||||
impl += Iter(n, """
|
impl += Iter(
|
||||||
<< "\\n" << e%s << " evaluates to " << v%s""")
|
n, """
|
||||||
|
<< "\\n" << e%s << " evaluates to " << ::testing::PrintToString(v%s)"""
|
||||||
|
)
|
||||||
|
|
||||||
impl += """;
|
impl += """;
|
||||||
}
|
}
|
||||||
@ -510,7 +514,7 @@ struct PredFormatFunctor%(n)s {
|
|||||||
|
|
||||||
class Predicate%(n)sTest : public testing::Test {
|
class Predicate%(n)sTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
void SetUp() override {
|
||||||
expected_to_finish_ = true;
|
expected_to_finish_ = true;
|
||||||
finished_ = false;""" % DEFS
|
finished_ = false;""" % DEFS
|
||||||
|
|
||||||
@ -520,7 +524,7 @@ class Predicate%(n)sTest : public testing::Test {
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
tests += """
|
tests += """
|
||||||
virtual void TearDown() {
|
void TearDown() override {
|
||||||
// Verifies that each of the predicate's arguments was evaluated
|
// Verifies that each of the predicate's arguments was evaluated
|
||||||
// exactly once."""
|
// exactly once."""
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python2.7
|
||||||
#
|
#
|
||||||
# Copyright 2008, Google Inc.
|
# Copyright 2008, Google Inc.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
@ -62,7 +62,7 @@ GRAMMAR:
|
|||||||
EXPRESSION has Python syntax.
|
EXPRESSION has Python syntax.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@ -246,7 +246,7 @@ def ParseToken(lines, pos, regex, token_type):
|
|||||||
if m and not m.start():
|
if m and not m.start():
|
||||||
return MakeToken(lines, pos, pos + m.end(), token_type)
|
return MakeToken(lines, pos, pos + m.end(), token_type)
|
||||||
else:
|
else:
|
||||||
print 'ERROR: %s expected at %s.' % (token_type, pos)
|
print('ERROR: %s expected at %s.' % (token_type, pos))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@ -453,8 +453,8 @@ def PushFront(a_list, elem):
|
|||||||
def PopToken(a_list, token_type=None):
|
def PopToken(a_list, token_type=None):
|
||||||
token = PopFront(a_list)
|
token = PopFront(a_list)
|
||||||
if token_type is not None and token.token_type != token_type:
|
if token_type is not None and token.token_type != token_type:
|
||||||
print 'ERROR: %s expected at %s' % (token_type, token.start)
|
print('ERROR: %s expected at %s' % (token_type, token.start))
|
||||||
print 'ERROR: %s found instead' % (token,)
|
print('ERROR: %s found instead' % (token,))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
return token
|
return token
|
||||||
@ -616,15 +616,15 @@ class Env:
|
|||||||
if identifier == var:
|
if identifier == var:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
print 'ERROR: meta variable %s is undefined.' % (identifier,)
|
print('ERROR: meta variable %s is undefined.' % (identifier,))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def EvalExp(self, exp):
|
def EvalExp(self, exp):
|
||||||
try:
|
try:
|
||||||
result = eval(exp.python_exp)
|
result = eval(exp.python_exp)
|
||||||
except Exception, e:
|
except Exception as e: # pylint: disable=broad-except
|
||||||
print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e)
|
print('ERROR: caught exception %s: %s' % (e.__class__.__name__, e))
|
||||||
print ('ERROR: failed to evaluate meta expression %s at %s' %
|
print('ERROR: failed to evaluate meta expression %s at %s' %
|
||||||
(exp.python_exp, exp.token.start))
|
(exp.python_exp, exp.token.start))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return result
|
return result
|
||||||
@ -634,7 +634,7 @@ class Env:
|
|||||||
if identifier == var:
|
if identifier == var:
|
||||||
return (lower, upper)
|
return (lower, upper)
|
||||||
|
|
||||||
print 'ERROR: range %s is undefined.' % (identifier,)
|
print('ERROR: range %s is undefined.' % (identifier,))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@ -694,8 +694,8 @@ def RunAtomicCode(env, node, output):
|
|||||||
elif isinstance(node, CodeNode):
|
elif isinstance(node, CodeNode):
|
||||||
RunCode(env.Clone(), node, output)
|
RunCode(env.Clone(), node, output)
|
||||||
else:
|
else:
|
||||||
print 'BAD'
|
print('BAD')
|
||||||
print node
|
print(node)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@ -830,7 +830,7 @@ def ConvertFromPumpSource(src_text):
|
|||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
if len(argv) == 1:
|
if len(argv) == 1:
|
||||||
print __doc__
|
print(__doc__)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
file_path = argv[-1]
|
file_path = argv[-1]
|
||||||
@ -840,7 +840,7 @@ def main(argv):
|
|||||||
else:
|
else:
|
||||||
output_file_path = '-'
|
output_file_path = '-'
|
||||||
if output_file_path == '-':
|
if output_file_path == '-':
|
||||||
print output_str,
|
print(output_str,)
|
||||||
else:
|
else:
|
||||||
output_file = file(output_file_path, 'w')
|
output_file = file(output_file_path, 'w')
|
||||||
output_file.write('// This file was GENERATED by command:\n')
|
output_file.write('// This file was GENERATED by command:\n')
|
||||||
|
32
googletest/scripts/run_with_path.py
Executable file
32
googletest/scripts/run_with_path.py
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright 2010 Google Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
"""Runs program specified in the command line with the substituted PATH.
|
||||||
|
|
||||||
|
This script is needed for to support building under Pulse which is unable
|
||||||
|
to override the existing PATH variable.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
SUBST_PATH_ENV_VAR_NAME = "SUBST_PATH"
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if SUBST_PATH_ENV_VAR_NAME in os.environ:
|
||||||
|
os.environ["PATH"] = os.environ[SUBST_PATH_ENV_VAR_NAME]
|
||||||
|
|
||||||
|
exit_code = subprocess.Popen(sys.argv[1:]).wait()
|
||||||
|
|
||||||
|
# exit_code is negative (-signal) if the process has been terminated by
|
||||||
|
# a signal. Returning negative exit code is not portable and so we return
|
||||||
|
# 100 instead.
|
||||||
|
if exit_code < 0:
|
||||||
|
exit_code = 100
|
||||||
|
|
||||||
|
sys.exit(exit_code)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -1,18 +1,33 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright 2007 Google Inc.
|
# Copyright 2007, Google Inc.
|
||||||
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# you may not use this file except in compliance with the License.
|
# modification, are permitted provided that the following conditions are
|
||||||
# You may obtain a copy of the License at
|
# met:
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# * 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.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
# See the License for the specific language governing permissions and
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
# limitations under the License.
|
# 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.
|
||||||
|
|
||||||
"""Tool for uploading diffs from a version control system to the codereview app.
|
"""Tool for uploading diffs from a version control system to the codereview app.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user