Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
c2ad46a5
Commit
c2ad46a5
authored
Jun 02, 2009
by
zhanyong.wan
Browse files
Improves gmock generator and adds a test for it (by Neal Norwitz).
parent
9413f2ff
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
159 additions
and
11 deletions
+159
-11
scripts/generator/cpp/ast.py
scripts/generator/cpp/ast.py
+9
-5
scripts/generator/cpp/gmock_class.py
scripts/generator/cpp/gmock_class.py
+13
-6
scripts/generator/cpp/gmock_class_test.py
scripts/generator/cpp/gmock_class_test.py
+137
-0
No files found.
scripts/generator/cpp/ast.py
View file @
c2ad46a5
...
@@ -782,7 +782,7 @@ class AstBuilder(object):
...
@@ -782,7 +782,7 @@ class AstBuilder(object):
parts
=
self
.
converter
.
DeclarationToParts
(
temp_tokens
,
True
)
parts
=
self
.
converter
.
DeclarationToParts
(
temp_tokens
,
True
)
(
name
,
type_name
,
templated_types
,
modifiers
,
default
,
(
name
,
type_name
,
templated_types
,
modifiers
,
default
,
unused_other_tokens
)
=
parts
unused_other_tokens
)
=
parts
t0
=
temp_tokens
[
0
]
t0
=
temp_tokens
[
0
]
names
=
[
t
.
name
for
t
in
temp_tokens
]
names
=
[
t
.
name
for
t
in
temp_tokens
]
if
templated_types
:
if
templated_types
:
...
@@ -1551,18 +1551,22 @@ class AstBuilder(object):
...
@@ -1551,18 +1551,22 @@ class AstBuilder(object):
token
=
self
.
_GetNextToken
()
token
=
self
.
_GetNextToken
()
self
.
namespace_stack
.
append
(
name
)
self
.
namespace_stack
.
append
(
name
)
assert
token
.
token_type
==
tokenize
.
SYNTAX
,
token
assert
token
.
token_type
==
tokenize
.
SYNTAX
,
token
# Create an internal token that denotes when the namespace is complete.
internal_token
=
tokenize
.
Token
(
_INTERNAL_TOKEN
,
_NAMESPACE_POP
,
None
,
None
)
internal_token
.
whence
=
token
.
whence
if
token
.
name
==
'='
:
if
token
.
name
==
'='
:
# TODO(nnorwitz): handle aliasing namespaces.
# TODO(nnorwitz): handle aliasing namespaces.
name
,
next_token
=
self
.
GetName
()
name
,
next_token
=
self
.
GetName
()
assert
next_token
.
name
==
';'
,
next_token
assert
next_token
.
name
==
';'
,
next_token
self
.
_AddBackToken
(
internal_token
)
else
:
else
:
assert
token
.
name
==
'{'
,
token
assert
token
.
name
==
'{'
,
token
tokens
=
list
(
self
.
GetScope
())
tokens
=
list
(
self
.
GetScope
())
del
tokens
[
-
1
]
# Remove trailing '}'.
# Replace the trailing } with the internal namespace pop token.
tokens
[
-
1
]
=
internal_token
# Handle namespace with nothing in it.
# Handle namespace with nothing in it.
self
.
_AddBackTokens
(
tokens
)
self
.
_AddBackTokens
(
tokens
)
token
=
tokenize
.
Token
(
_INTERNAL_TOKEN
,
_NAMESPACE_POP
,
None
,
None
)
self
.
_AddBackToken
(
token
)
return
None
return
None
def
handle_using
(
self
):
def
handle_using
(
self
):
...
@@ -1672,7 +1676,7 @@ def PrintIndentifiers(filename, should_print):
...
@@ -1672,7 +1676,7 @@ def PrintIndentifiers(filename, should_print):
if
should_print
(
node
):
if
should_print
(
node
):
print
(
node
.
name
)
print
(
node
.
name
)
except
KeyboardInterrupt
:
except
KeyboardInterrupt
:
return
return
except
:
except
:
pass
pass
...
...
scripts/generator/cpp/gmock_class.py
View file @
c2ad46a5
#!/usr/bin/env python
#!/usr/bin/env python
#
#
# Copyright 2008 Google Inc.
# Copyright 2008 Google Inc.
All Rights Reserved.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# you may not use this file except in compliance with the License.
...
@@ -73,7 +73,13 @@ def _GenerateMethods(output_lines, source, class_node):
...
@@ -73,7 +73,13 @@ def _GenerateMethods(output_lines, source, class_node):
# of the first parameter to the end of the last parameter.
# of the first parameter to the end of the last parameter.
start
=
node
.
parameters
[
0
].
start
start
=
node
.
parameters
[
0
].
start
end
=
node
.
parameters
[
-
1
].
end
end
=
node
.
parameters
[
-
1
].
end
args
=
re
.
sub
(
' +'
,
' '
,
source
[
start
:
end
].
replace
(
'
\n
'
,
''
))
# Remove // comments.
args_strings
=
re
.
sub
(
r
'//.*'
,
''
,
source
[
start
:
end
])
# Condense multiple spaces and eliminate newlines putting the
# parameters together on a single line. Ensure there is a
# space in an argument which is split by a newline without
# intervening whitespace, e.g.: int\nBar
args
=
re
.
sub
(
' +'
,
' '
,
args_strings
.
replace
(
'
\n
'
,
' '
))
# Create the prototype.
# Create the prototype.
indent
=
' '
*
_INDENT
indent
=
' '
*
_INDENT
...
@@ -120,8 +126,6 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
...
@@ -120,8 +126,6 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
lines
.
append
(
'} // namespace %s'
%
class_node
.
namespace
[
i
])
lines
.
append
(
'} // namespace %s'
%
class_node
.
namespace
[
i
])
lines
.
append
(
''
)
# Add an extra newline.
lines
.
append
(
''
)
# Add an extra newline.
sys
.
stdout
.
write
(
'
\n
'
.
join
(
lines
))
if
desired_class_names
:
if
desired_class_names
:
missing_class_name_list
=
list
(
desired_class_names
-
processed_class_names
)
missing_class_name_list
=
list
(
desired_class_names
-
processed_class_names
)
if
missing_class_name_list
:
if
missing_class_name_list
:
...
@@ -129,7 +133,9 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
...
@@ -129,7 +133,9 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
sys
.
stderr
.
write
(
'Class(es) not found in %s: %s
\n
'
%
sys
.
stderr
.
write
(
'Class(es) not found in %s: %s
\n
'
%
(
filename
,
', '
.
join
(
missing_class_name_list
)))
(
filename
,
', '
.
join
(
missing_class_name_list
)))
elif
not
processed_class_names
:
elif
not
processed_class_names
:
sys
.
stderr
.
write
(
'No class found in %s
\n
'
%
filename
)
sys
.
stderr
.
write
(
'No class found in %s
\n
'
%
filename
)
return
lines
def
main
(
argv
=
sys
.
argv
):
def
main
(
argv
=
sys
.
argv
):
...
@@ -164,7 +170,8 @@ def main(argv=sys.argv):
...
@@ -164,7 +170,8 @@ def main(argv=sys.argv):
# An error message was already printed since we couldn't parse.
# An error message was already printed since we couldn't parse.
pass
pass
else
:
else
:
_GenerateMocks
(
filename
,
source
,
entire_ast
,
desired_class_names
)
lines
=
_GenerateMocks
(
filename
,
source
,
entire_ast
,
desired_class_names
)
sys
.
stdout
.
write
(
'
\n
'
.
join
(
lines
))
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
...
...
scripts/generator/cpp/gmock_class_test.py
0 → 100755
View file @
c2ad46a5
#!/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."""
__author__
=
'nnorwitz@google.com (Neal Norwitz)'
import
os
import
sys
import
unittest
# Allow the cpp imports below to work when run as a standalone script.
sys
.
path
.
append
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
__file__
)))
from
cpp
import
ast
from
cpp
import
gmock_class
class
TestCase
(
unittest
.
TestCase
):
"""Helper class that adds assert methods."""
def
assertEqualIgnoreLeadingWhitespace
(
self
,
expected_lines
,
lines
):
"""Specialized assert that ignores the indent level."""
stripped_lines
=
'
\n
'
.
join
([
s
.
lstrip
()
for
s
in
lines
.
split
(
'
\n
'
)])
self
.
assertEqual
(
expected_lines
,
stripped_lines
)
class
GenerateMethodsTest
(
TestCase
):
def
GenerateMethodSource
(
self
,
cpp_source
):
"""Helper method to convert C++ source to gMock 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
''
.
join
(
method_source_lines
)
def
testStrangeNewlineInParameter
(
self
):
source
=
"""
class Foo {
public:
virtual void Bar(int
a) = 0;
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD1(Bar,
\n
void(int a));'
,
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_CONST_METHOD2(Bar,
\n
void(int a, int b));'
,
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_METHOD2(Bar,
\n
const string&(int /* keeper */, int b));'
,
self
.
GenerateMethodSource
(
source
))
class
GenerateMocksTest
(
TestCase
):
def
GenerateMocks
(
self
,
cpp_source
):
"""Helper method to convert C++ source to complete gMock 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 {
class Test {
public:
virtual void Foo();
};
} // namespace Baz
} // namespace Foo
"""
expected
=
"""
\
namespace Foo {
namespace Baz {
class MockTest : public Test {
public:
MOCK_METHOD0(Foo,
void());
};
} // namespace Baz
} // namespace Foo
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
if
__name__
==
'__main__'
:
unittest
.
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment