aboutsummaryrefslogtreecommitdiffstats
path: root/googlemock/test/gmock_doctor_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'googlemock/test/gmock_doctor_test.py')
-rwxr-xr-xgooglemock/test/gmock_doctor_test.py242
1 files changed, 242 insertions, 0 deletions
diff --git a/googlemock/test/gmock_doctor_test.py b/googlemock/test/gmock_doctor_test.py
new file mode 100755
index 00000000..24a2ec43
--- /dev/null
+++ b/googlemock/test/gmock_doctor_test.py
@@ -0,0 +1,242 @@
+#!/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.
+
+"""Tests for gmock_doctor.py."""
+
+import os
+import sys
+
+IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
+if not IS_LINUX:
+ sys.stderr.write(
+ 'WARNING: Negative compilation tests are not supported on this platform')
+ sys.exit(0)
+
+# Suppresses the 'Import not at the top of the file' lint complaint.
+# pylint: disable-msg=C6204
+import google3.third_party.googletest.googlemock.scripts.gmock_doctor
+gmock_doctor = google3.third_party.googletest.googlemock.scripts.gmock_doctor
+from google3.testing.pybase import fake_target_util
+from google3.testing.pybase import googletest
+# pylint: enable-msg=C6204
+
+
+def GetCompilerCommand():
+ """Returns the command used for compiling gmock_doctor_nc.cc."""
+
+ # Parses the fake output generated by the cc_fake_binary rule.
+ target = fake_target_util.ParseFakeTargetFile(
+ 'google3/third_party/googletest/googlemock/test/gmock_doctor_nc')
+
+ # Looks up the command for making the desired target.
+ command = target.CommandMap()['gmock_doctor_nc.o']
+
+ # Looks up where Makefile is.
+ makefile_dir = target.MakefileDir()
+
+ # Changes the current directory to where Makefile is - the
+ # compilation must be done there.
+ os.chdir(makefile_dir)
+
+ return command
+
+
+def CompileSection(section_name):
+ """Compiles the given section in gmock_doctor_nc.cc.
+
+ The error messages from the compiler will be printed on stdout such that
+ they can be easily piped to the Google Mock Doctor.
+
+ Args:
+ section_name: Name of the section in gmock_doctor_nc.cc that should
+ be compiled.
+ """
+
+ command = GetCompilerCommand()
+ (_, compiler_errors) = googletest.GetCommandStderr(
+ command + ' -DTEST_' + section_name,
+ env = {'TEST_TMPDIR': os.environ['TEST_TMPDIR']})
+ print compiler_errors
+
+
+class GMockDoctorTest(googletest.TestCase):
+ def setUp(self):
+ self.command = GetCompilerCommand()
+
+ def CheckDiagnoses(self, test_name, diseases):
+ """Checks the diagnoses for the given compiler output.
+
+ Args:
+ test_name: Name of the section in gmock_doctor_nc.cc that should
+ be compiled.
+
+ diseases: A list of disease short names that Google Mock Doctor
+ should diagnose.
+ """
+
+ _, compiler_errors = googletest.GetCommandStderr(
+ self.command + ' -DTEST_' + test_name,
+ env = {'TEST_TMPDIR': os.environ['TEST_TMPDIR']})
+
+ self.CheckDiagnosesForOutput(compiler_errors, diseases)
+
+ def CheckDiagnosesForOutput(self, compiler_errors, diseases):
+ """Checks the diagnoses for the given test.
+
+ Args:
+ compiler_errors: The compiler diagnostics to check for diseases.
+
+ diseases: A list of disease short names that Google Mock Doctor
+ should diagnose.
+ """
+
+ diagnoses = gmock_doctor.Diagnose(compiler_errors)
+ num_diseases = len(diseases)
+ num_diagnoses = len(diagnoses)
+
+ for i in range(min(num_diseases, num_diagnoses)):
+ self.assert_(('[' + diseases[i] + ' ') in diagnoses[i],
+ ('Compiler error message:\n\n'
+ '%sgmock_doctor.py\'s diagnoses:\n%s\n\n'
+ 'Failed to diagnose the %s disease.')
+ % (compiler_errors, diagnoses[i], diseases[i]))
+
+ self.assertEquals(num_diseases, num_diagnoses,
+ ('%d diseases, but %d diagnoses, where the '
+ 'compiler errors are:\n%s\n'
+ 'and where the diseases are:\n%s\n'
+ 'and where the diagnoses are:\n%s\n')
+ % (num_diseases, num_diagnoses, compiler_errors,
+ str(diseases), str(diagnoses)))
+
+ def testMOP(self):
+ self.CheckDiagnoses('MOP', 2 * ['MOP'])
+
+ def testNRS1(self):
+ self.CheckDiagnoses('NRS1', ['NRS'])
+
+ def testNRS2(self):
+ self.CheckDiagnoses('NRS2', ['NRS'])
+
+ def testNRS3(self):
+ self.CheckDiagnoses('NRS3', ['NRS'])
+
+ def testIBRA(self):
+ self.CheckDiagnoses('IBRA', ['IBRA'])
+
+ def testOFM(self):
+ self.CheckDiagnoses('OFM', ['OFM'])
+
+ def testNoNUSForNonGMockSymbol(self):
+ self.CheckDiagnoses('NO_NUS_FOR_NON_GMOCK_SYMBOL', [])
+
+ def testNUSVariable(self):
+ self.CheckDiagnoses('NUS_VARIABLE', ['NUS'])
+
+ def testNUSFunction(self):
+ self.CheckDiagnoses('NUS_FUNCTION', ['NUS'])
+
+ def testNUSFunctionTemplate(self):
+ self.CheckDiagnoses('NUS_FUNCTION_TEMPLATE', ['NUS'])
+
+ def testNUSFunctionTemplateWithTypeArg(self):
+ self.CheckDiagnoses('NUS_FUNCTION_TEMPLATE_WITH_TYPE_ARG', ['NUS'])
+
+ def testNUSFunctionTemplateWithNontypeArg(self):
+ self.CheckDiagnoses('NUS_FUNCTION_TEMPLATE_WITH_NONTYPE_ARG', ['NUS'])
+
+ def testNUSClass(self):
+ self.CheckDiagnoses('NUS_CLASS', 2 * ['NUS'])
+
+ def testNRR(self):
+ self.CheckDiagnoses('NRR', ['NRR'])
+
+ def testMultipleOccurrences(self):
+ self.CheckDiagnoses('MULTI_OCCURRENCES_OF_SAME_DISEASE', 2 * ['IBRA'])
+
+ def testNRNULL(self):
+ self.CheckDiagnoses('NRNULL', ['NRNULL'])
+
+ def testWPP(self):
+ self.CheckDiagnoses('WPP', 3 * ['WPP'])
+
+ def testTTB(self):
+ self.CheckDiagnoses('TTB', 3 * ['TTB'])
+
+ def testUnderstandsCharaterPositionsInGcc(self):
+ # We cannot guarantee that the system compiler will output character
+ # positions so we inject the compiler output.
+ compiler_errors = (
+ 'In file included from /usr/include/gmock/gmock.h:58:0,\n'
+ ' from foo.cpp:4:\n'
+ '/usr/include/gmock/gmock-actions.h: In member function'
+ " 'testing::internal::ReturnAction<R>::operator testing::Action<Func>()"
+ ' const [with F = const std::complex<double>&(unsigned int),'
+ " R = std::complex<double>]':\n"
+ 'foo.cpp:116:28: instantiated from here\n'
+ '/usr/include/gmock/gmock-actions.h:449:5: error:'
+ " creating array with negative size ('-0x00000000000000001')")
+ self.CheckDiagnosesForOutput(compiler_errors, ['NRR'])
+
+ def testUnderstandsLeftAndRightSingleQuotes(self):
+ # We cannot guarantee that the system compiler will output single quote
+ # characters so we inject the compiler output.
+ compiler_errors = (
+ 'In file included from /usr/include/gmock/gmock.h:58,\n'
+ ' from foo.cpp:4:\n'
+ '/usr/include/gmock/gmock-actions.h: In member function'
+ ' \xe2\x80\x98testing::internal::ReturnAction<R>::operator'
+ ' testing::Action<Func>() const'
+ ' [with F = const std::complex<double>&(unsigned int),'
+ ' R = std::complex<double>]\xe2\x80\x99:\n'
+ 'foo.cpp:116: instantiated from here\n'
+ '/usr/include/gmock/gmock-actions.h:449: error:'
+ ' creating array with negative size'
+ ' (\xe2\x80\x98-0x00000000000000001\xe2\x80\x99)')
+ self.CheckDiagnosesForOutput(compiler_errors, ['NRR'])
+
+
+if __name__ == '__main__':
+ if len(sys.argv) == 1:
+ googletest.main()
+ else:
+ # To make it easy for a user to see Google Mock Doctor in action,
+ # we compile the given section in gmock_doctor_nc.cc and direct
+ # the error messages to stdout, when the test is run with a
+ # section name on the command line. Then the user can pipe the
+ # output to Google Mock Doctor and see what the diagnoses are
+ # like. For example, to demo how Google Mock Doctor diagnoses the
+ # NRN disease:
+ #
+ # $ blaze build third_party/googletest/googlemock/test:gmock_doctor_test
+ # $ blaze-bin/third_party/googletest/googlemock/test/gmock_doctor_test NRN | \
+ # third_party/googletest/googlemock/scripts/gmock_doctor.py
+ CompileSection(sys.argv[1])