blob: 24a2ec43b50ec29769f87fd37e707ff42f532c89 [file] [log] [blame]
mistergfa52cd62019-04-18 10:05:29 -04001#!/usr/bin/env python
2#
3# Copyright 2008, Google Inc.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met:
9#
10# * Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# * Redistributions in binary form must reproduce the above
13# copyright notice, this list of conditions and the following disclaimer
14# in the documentation and/or other materials provided with the
15# distribution.
16# * Neither the name of Google Inc. nor the names of its
17# contributors may be used to endorse or promote products derived from
18# this software without specific prior written permission.
19#
20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32"""Tests for gmock_doctor.py."""
33
34import os
35import sys
36
37IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
38if not IS_LINUX:
39 sys.stderr.write(
40 'WARNING: Negative compilation tests are not supported on this platform')
41 sys.exit(0)
42
43# Suppresses the 'Import not at the top of the file' lint complaint.
44# pylint: disable-msg=C6204
45import google3.third_party.googletest.googlemock.scripts.gmock_doctor
46gmock_doctor = google3.third_party.googletest.googlemock.scripts.gmock_doctor
47from google3.testing.pybase import fake_target_util
48from google3.testing.pybase import googletest
49# pylint: enable-msg=C6204
50
51
52def GetCompilerCommand():
53 """Returns the command used for compiling gmock_doctor_nc.cc."""
54
55 # Parses the fake output generated by the cc_fake_binary rule.
56 target = fake_target_util.ParseFakeTargetFile(
57 'google3/third_party/googletest/googlemock/test/gmock_doctor_nc')
58
59 # Looks up the command for making the desired target.
60 command = target.CommandMap()['gmock_doctor_nc.o']
61
62 # Looks up where Makefile is.
63 makefile_dir = target.MakefileDir()
64
65 # Changes the current directory to where Makefile is - the
66 # compilation must be done there.
67 os.chdir(makefile_dir)
68
69 return command
70
71
72def CompileSection(section_name):
73 """Compiles the given section in gmock_doctor_nc.cc.
74
75 The error messages from the compiler will be printed on stdout such that
76 they can be easily piped to the Google Mock Doctor.
77
78 Args:
79 section_name: Name of the section in gmock_doctor_nc.cc that should
80 be compiled.
81 """
82
83 command = GetCompilerCommand()
84 (_, compiler_errors) = googletest.GetCommandStderr(
85 command + ' -DTEST_' + section_name,
86 env = {'TEST_TMPDIR': os.environ['TEST_TMPDIR']})
87 print compiler_errors
88
89
90class GMockDoctorTest(googletest.TestCase):
91 def setUp(self):
92 self.command = GetCompilerCommand()
93
94 def CheckDiagnoses(self, test_name, diseases):
95 """Checks the diagnoses for the given compiler output.
96
97 Args:
98 test_name: Name of the section in gmock_doctor_nc.cc that should
99 be compiled.
100
101 diseases: A list of disease short names that Google Mock Doctor
102 should diagnose.
103 """
104
105 _, compiler_errors = googletest.GetCommandStderr(
106 self.command + ' -DTEST_' + test_name,
107 env = {'TEST_TMPDIR': os.environ['TEST_TMPDIR']})
108
109 self.CheckDiagnosesForOutput(compiler_errors, diseases)
110
111 def CheckDiagnosesForOutput(self, compiler_errors, diseases):
112 """Checks the diagnoses for the given test.
113
114 Args:
115 compiler_errors: The compiler diagnostics to check for diseases.
116
117 diseases: A list of disease short names that Google Mock Doctor
118 should diagnose.
119 """
120
121 diagnoses = gmock_doctor.Diagnose(compiler_errors)
122 num_diseases = len(diseases)
123 num_diagnoses = len(diagnoses)
124
125 for i in range(min(num_diseases, num_diagnoses)):
126 self.assert_(('[' + diseases[i] + ' ') in diagnoses[i],
127 ('Compiler error message:\n\n'
128 '%sgmock_doctor.py\'s diagnoses:\n%s\n\n'
129 'Failed to diagnose the %s disease.')
130 % (compiler_errors, diagnoses[i], diseases[i]))
131
132 self.assertEquals(num_diseases, num_diagnoses,
133 ('%d diseases, but %d diagnoses, where the '
134 'compiler errors are:\n%s\n'
135 'and where the diseases are:\n%s\n'
136 'and where the diagnoses are:\n%s\n')
137 % (num_diseases, num_diagnoses, compiler_errors,
138 str(diseases), str(diagnoses)))
139
140 def testMOP(self):
141 self.CheckDiagnoses('MOP', 2 * ['MOP'])
142
143 def testNRS1(self):
144 self.CheckDiagnoses('NRS1', ['NRS'])
145
146 def testNRS2(self):
147 self.CheckDiagnoses('NRS2', ['NRS'])
148
149 def testNRS3(self):
150 self.CheckDiagnoses('NRS3', ['NRS'])
151
152 def testIBRA(self):
153 self.CheckDiagnoses('IBRA', ['IBRA'])
154
155 def testOFM(self):
156 self.CheckDiagnoses('OFM', ['OFM'])
157
158 def testNoNUSForNonGMockSymbol(self):
159 self.CheckDiagnoses('NO_NUS_FOR_NON_GMOCK_SYMBOL', [])
160
161 def testNUSVariable(self):
162 self.CheckDiagnoses('NUS_VARIABLE', ['NUS'])
163
164 def testNUSFunction(self):
165 self.CheckDiagnoses('NUS_FUNCTION', ['NUS'])
166
167 def testNUSFunctionTemplate(self):
168 self.CheckDiagnoses('NUS_FUNCTION_TEMPLATE', ['NUS'])
169
170 def testNUSFunctionTemplateWithTypeArg(self):
171 self.CheckDiagnoses('NUS_FUNCTION_TEMPLATE_WITH_TYPE_ARG', ['NUS'])
172
173 def testNUSFunctionTemplateWithNontypeArg(self):
174 self.CheckDiagnoses('NUS_FUNCTION_TEMPLATE_WITH_NONTYPE_ARG', ['NUS'])
175
176 def testNUSClass(self):
177 self.CheckDiagnoses('NUS_CLASS', 2 * ['NUS'])
178
179 def testNRR(self):
180 self.CheckDiagnoses('NRR', ['NRR'])
181
182 def testMultipleOccurrences(self):
183 self.CheckDiagnoses('MULTI_OCCURRENCES_OF_SAME_DISEASE', 2 * ['IBRA'])
184
185 def testNRNULL(self):
186 self.CheckDiagnoses('NRNULL', ['NRNULL'])
187
188 def testWPP(self):
189 self.CheckDiagnoses('WPP', 3 * ['WPP'])
190
191 def testTTB(self):
192 self.CheckDiagnoses('TTB', 3 * ['TTB'])
193
194 def testUnderstandsCharaterPositionsInGcc(self):
195 # We cannot guarantee that the system compiler will output character
196 # positions so we inject the compiler output.
197 compiler_errors = (
198 'In file included from /usr/include/gmock/gmock.h:58:0,\n'
199 ' from foo.cpp:4:\n'
200 '/usr/include/gmock/gmock-actions.h: In member function'
201 " 'testing::internal::ReturnAction<R>::operator testing::Action<Func>()"
202 ' const [with F = const std::complex<double>&(unsigned int),'
203 " R = std::complex<double>]':\n"
204 'foo.cpp:116:28: instantiated from here\n'
205 '/usr/include/gmock/gmock-actions.h:449:5: error:'
206 " creating array with negative size ('-0x00000000000000001')")
207 self.CheckDiagnosesForOutput(compiler_errors, ['NRR'])
208
209 def testUnderstandsLeftAndRightSingleQuotes(self):
210 # We cannot guarantee that the system compiler will output single quote
211 # characters so we inject the compiler output.
212 compiler_errors = (
213 'In file included from /usr/include/gmock/gmock.h:58,\n'
214 ' from foo.cpp:4:\n'
215 '/usr/include/gmock/gmock-actions.h: In member function'
216 ' \xe2\x80\x98testing::internal::ReturnAction<R>::operator'
217 ' testing::Action<Func>() const'
218 ' [with F = const std::complex<double>&(unsigned int),'
219 ' R = std::complex<double>]\xe2\x80\x99:\n'
220 'foo.cpp:116: instantiated from here\n'
221 '/usr/include/gmock/gmock-actions.h:449: error:'
222 ' creating array with negative size'
223 ' (\xe2\x80\x98-0x00000000000000001\xe2\x80\x99)')
224 self.CheckDiagnosesForOutput(compiler_errors, ['NRR'])
225
226
227if __name__ == '__main__':
228 if len(sys.argv) == 1:
229 googletest.main()
230 else:
231 # To make it easy for a user to see Google Mock Doctor in action,
232 # we compile the given section in gmock_doctor_nc.cc and direct
233 # the error messages to stdout, when the test is run with a
234 # section name on the command line. Then the user can pipe the
235 # output to Google Mock Doctor and see what the diagnoses are
236 # like. For example, to demo how Google Mock Doctor diagnoses the
237 # NRN disease:
238 #
239 # $ blaze build third_party/googletest/googlemock/test:gmock_doctor_test
240 # $ blaze-bin/third_party/googletest/googlemock/test/gmock_doctor_test NRN | \
241 # third_party/googletest/googlemock/scripts/gmock_doctor.py
242 CompileSection(sys.argv[1])