Lots of changes:
* changes the XML report format to match JUnit/Ant's. * improves file path handling. * allows the user to disable RTTI using the GTEST_HAS_RTTI macro. * makes the code compile with -Wswitch-enum.
This commit is contained in:
		| @@ -123,8 +123,6 @@ TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { | ||||
|   EXPECT_FALSE(FilePath("a\\b\\").IsEmpty()); | ||||
| } | ||||
|  | ||||
| // FilePath's functions used by UnitTestOptions::GetOutputFile. | ||||
|  | ||||
| // RemoveDirectoryName "" -> "" | ||||
| TEST(RemoveDirectoryNameTest, WhenEmptyName) { | ||||
|   EXPECT_STREQ("", FilePath("").RemoveDirectoryName().c_str()); | ||||
| @@ -257,6 +255,110 @@ TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { | ||||
|       FilePath("foo" PATH_SEP "bar").RemoveTrailingPathSeparator().c_str()); | ||||
| } | ||||
|  | ||||
| TEST(DirectoryTest, RootDirectoryExists) { | ||||
| #ifdef GTEST_OS_WINDOWS  // We are on Windows. | ||||
|   char current_drive[_MAX_PATH]; | ||||
|   current_drive[0] = _getdrive() + 'A' - 1; | ||||
|   current_drive[1] = ':'; | ||||
|   current_drive[2] = '\\'; | ||||
|   current_drive[3] = '\0'; | ||||
|   EXPECT_TRUE(FilePath(current_drive).DirectoryExists()); | ||||
| #else | ||||
|   EXPECT_TRUE(FilePath("/").DirectoryExists()); | ||||
| #endif  // GTEST_OS_WINDOWS | ||||
| } | ||||
|  | ||||
| #ifdef GTEST_OS_WINDOWS | ||||
| TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { | ||||
|   const int saved_drive_ = _getdrive(); | ||||
|   // Find a drive that doesn't exist. Start with 'Z' to avoid common ones. | ||||
|   for (char drive = 'Z'; drive >= 'A'; drive--) | ||||
|     if (_chdrive(drive - 'A' + 1) == -1) { | ||||
|       char non_drive[_MAX_PATH]; | ||||
|       non_drive[0] = drive; | ||||
|       non_drive[1] = ':'; | ||||
|       non_drive[2] = '\\'; | ||||
|       non_drive[3] = '\0'; | ||||
|       EXPECT_FALSE(FilePath(non_drive).DirectoryExists()); | ||||
|       break; | ||||
|     } | ||||
|   _chdrive(saved_drive_); | ||||
| } | ||||
| #endif // GTEST_OS_WINDOWS | ||||
|  | ||||
| TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { | ||||
|   EXPECT_FALSE(FilePath("").DirectoryExists()); | ||||
| } | ||||
|  | ||||
| TEST(DirectoryTest, CurrentDirectoryExists) { | ||||
| #ifdef GTEST_OS_WINDOWS  // We are on Windows. | ||||
| #ifndef _WIN32_CE  // Windows CE doesn't have a current directory. | ||||
|   EXPECT_TRUE(FilePath(".").DirectoryExists()); | ||||
|   EXPECT_TRUE(FilePath(".\\").DirectoryExists()); | ||||
| #endif  // _WIN32_CE | ||||
| #else | ||||
|   EXPECT_TRUE(FilePath(".").DirectoryExists()); | ||||
|   EXPECT_TRUE(FilePath("./").DirectoryExists()); | ||||
| #endif  // GTEST_OS_WINDOWS | ||||
| } | ||||
|  | ||||
| TEST(NormalizeTest, NullStringsEqualEmptyDirectory) { | ||||
|   EXPECT_STREQ("", FilePath(NULL).c_str()); | ||||
|   EXPECT_STREQ("", FilePath(String(NULL)).c_str()); | ||||
| } | ||||
|  | ||||
| // "foo/bar" == foo//bar" == "foo///bar" | ||||
| TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { | ||||
|   EXPECT_STREQ("foo" PATH_SEP "bar", | ||||
|     FilePath("foo" PATH_SEP "bar").c_str()); | ||||
|   EXPECT_STREQ("foo" PATH_SEP "bar", | ||||
|     FilePath("foo" PATH_SEP PATH_SEP "bar").c_str()); | ||||
|   EXPECT_STREQ("foo" PATH_SEP "bar", | ||||
|     FilePath("foo" PATH_SEP PATH_SEP PATH_SEP "bar").c_str()); | ||||
| } | ||||
|  | ||||
| // "/bar" == //bar" == "///bar" | ||||
| TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { | ||||
|   EXPECT_STREQ(PATH_SEP "bar", | ||||
|     FilePath(PATH_SEP "bar").c_str()); | ||||
|   EXPECT_STREQ(PATH_SEP "bar", | ||||
|     FilePath(PATH_SEP PATH_SEP "bar").c_str()); | ||||
|   EXPECT_STREQ(PATH_SEP "bar", | ||||
|     FilePath(PATH_SEP PATH_SEP PATH_SEP "bar").c_str()); | ||||
| } | ||||
|  | ||||
| // "foo/" == foo//" == "foo///" | ||||
| TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { | ||||
|   EXPECT_STREQ("foo" PATH_SEP, | ||||
|     FilePath("foo" PATH_SEP).c_str()); | ||||
|   EXPECT_STREQ("foo" PATH_SEP, | ||||
|     FilePath("foo" PATH_SEP PATH_SEP).c_str()); | ||||
|   EXPECT_STREQ("foo" PATH_SEP, | ||||
|     FilePath("foo" PATH_SEP PATH_SEP PATH_SEP).c_str()); | ||||
| } | ||||
|  | ||||
| TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { | ||||
|   FilePath default_path; | ||||
|   FilePath non_default_path("path"); | ||||
|   non_default_path = default_path; | ||||
|   EXPECT_STREQ("", non_default_path.c_str()); | ||||
|   EXPECT_STREQ("", default_path.c_str());  // RHS var is unchanged. | ||||
| } | ||||
|  | ||||
| TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) { | ||||
|   FilePath non_default_path("path"); | ||||
|   FilePath default_path; | ||||
|   default_path = non_default_path; | ||||
|   EXPECT_STREQ("path", default_path.c_str()); | ||||
|   EXPECT_STREQ("path", non_default_path.c_str());  // RHS var is unchanged. | ||||
| } | ||||
|  | ||||
| TEST(AssignmentOperatorTest, ConstAssignedToNonConst) { | ||||
|   const FilePath const_default_path("const_path"); | ||||
|   FilePath non_default_path("path"); | ||||
|   non_default_path = const_default_path; | ||||
|   EXPECT_STREQ("const_path", non_default_path.c_str()); | ||||
| } | ||||
|  | ||||
| class DirectoryCreationTest : public Test { | ||||
|  protected: | ||||
|   | ||||
| @@ -58,10 +58,12 @@ | ||||
|  | ||||
| namespace testing { | ||||
| namespace internal { | ||||
| const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); | ||||
| bool ParseInt32Flag(const char* str, const char* flag, Int32* value); | ||||
| }  // namespace internal | ||||
| }  // namespace testing | ||||
|  | ||||
| using testing::internal::FormatTimeInMillisAsSeconds; | ||||
| using testing::internal::ParseInt32Flag; | ||||
|  | ||||
| namespace testing { | ||||
| @@ -118,6 +120,28 @@ using testing::internal::WideStringToUtf8; | ||||
| // This line tests that we can define tests in an unnamed namespace. | ||||
| namespace { | ||||
|  | ||||
| // Tests FormatTimeInMillisAsSeconds(). | ||||
|  | ||||
| TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { | ||||
|   EXPECT_STREQ("0", FormatTimeInMillisAsSeconds(0)); | ||||
| } | ||||
|  | ||||
| TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) { | ||||
|   EXPECT_STREQ("0.003", FormatTimeInMillisAsSeconds(3)); | ||||
|   EXPECT_STREQ("0.01", FormatTimeInMillisAsSeconds(10)); | ||||
|   EXPECT_STREQ("0.2", FormatTimeInMillisAsSeconds(200)); | ||||
|   EXPECT_STREQ("1.2", FormatTimeInMillisAsSeconds(1200)); | ||||
|   EXPECT_STREQ("3", FormatTimeInMillisAsSeconds(3000)); | ||||
| } | ||||
|  | ||||
| TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { | ||||
|   EXPECT_STREQ("-0.003", FormatTimeInMillisAsSeconds(-3)); | ||||
|   EXPECT_STREQ("-0.01", FormatTimeInMillisAsSeconds(-10)); | ||||
|   EXPECT_STREQ("-0.2", FormatTimeInMillisAsSeconds(-200)); | ||||
|   EXPECT_STREQ("-1.2", FormatTimeInMillisAsSeconds(-1200)); | ||||
|   EXPECT_STREQ("-3", FormatTimeInMillisAsSeconds(-3000)); | ||||
| } | ||||
|  | ||||
| #ifndef __SYMBIAN32__ | ||||
| // NULL testing does not work with Symbian compilers. | ||||
|  | ||||
|   | ||||
| @@ -122,9 +122,9 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): | ||||
|       actual = minidom.parse(output_file1) | ||||
|     else: | ||||
|       actual = minidom.parse(output_file2) | ||||
|     self._NormalizeXml(actual.documentElement) | ||||
|     self._AssertEquivalentElements(expected.documentElement, | ||||
|                                    actual.documentElement) | ||||
|     self.NormalizeXml(actual.documentElement) | ||||
|     self.AssertEquivalentNodes(expected.documentElement, | ||||
|                                actual.documentElement) | ||||
|     expected.unlink() | ||||
|     actual.unlink() | ||||
|  | ||||
|   | ||||
| @@ -54,14 +54,20 @@ EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?> | ||||
|   </testsuite> | ||||
|   <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*"> | ||||
|     <testcase name="Fails" status="run" time="*" classname="FailedTest"> | ||||
|       <failure message="gtest_xml_output_unittest_.cc:*
Value of: 2
Expected: 1" type=""/> | ||||
|       <failure message="Value of: 2
Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:* | ||||
| Value of: 2 | ||||
| Expected: 1]]></failure> | ||||
|     </testcase> | ||||
|   </testsuite> | ||||
|   <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*"> | ||||
|     <testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/> | ||||
|     <testcase name="Fails" status="run" time="*" classname="MixedResultTest"> | ||||
|       <failure message="gtest_xml_output_unittest_.cc:*
Value of: 2
Expected: 1" type=""/> | ||||
|       <failure message="gtest_xml_output_unittest_.cc:*
Value of: 3
Expected: 2" type=""/> | ||||
|       <failure message="Value of: 2
Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:* | ||||
| Value of: 2 | ||||
| Expected: 1]]></failure> | ||||
|       <failure message="Value of: 3
Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:* | ||||
| Value of: 3 | ||||
| Expected: 2]]></failure> | ||||
|     </testcase> | ||||
|     <testcase name="DISABLED_test" status="notrun" time="*" classname="MixedResultTest"/> | ||||
|   </testsuite> | ||||
| @@ -160,14 +166,14 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): | ||||
|  | ||||
|     expected = minidom.parseString(expected_xml) | ||||
|     actual   = minidom.parse(xml_path) | ||||
|     self._NormalizeXml(actual.documentElement) | ||||
|     self._AssertEquivalentElements(expected.documentElement, | ||||
|                                    actual.documentElement) | ||||
|     self.NormalizeXml(actual.documentElement) | ||||
|     self.AssertEquivalentNodes(expected.documentElement, | ||||
|                                actual.documentElement) | ||||
|     expected.unlink() | ||||
|     actual  .unlink() | ||||
|  | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|   os.environ['GTEST_STACK_TRACE_DEPTH'] = '0' | ||||
|   os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' | ||||
|   gtest_test_utils.Main() | ||||
|   | ||||
| @@ -47,27 +47,35 @@ class GTestXMLTestCase(unittest.TestCase): | ||||
|   """ | ||||
|  | ||||
|  | ||||
|   def _AssertEquivalentElements(self, expected_element, actual_element): | ||||
|   def AssertEquivalentNodes(self, expected_node, actual_node): | ||||
|     """ | ||||
|     Asserts that actual_element (a DOM element object) is equivalent to | ||||
|     expected_element (another DOM element object), in that it meets all | ||||
|     of the following conditions: | ||||
|     *  It has the same tag name as expected_element. | ||||
|     *  It has the same set of attributes as expected_element, each with | ||||
|        the same value as the corresponding attribute of expected_element. | ||||
|        An exception is any attribute named "time", which need only be | ||||
|        convertible to a long integer. | ||||
|     *  Each child element is equivalent to a child element of | ||||
|        expected_element.  Child elements are matched according to an | ||||
|        attribute that varies depending on the element; "name" for | ||||
|        <testsuite> and <testcase> elements, "message" for <failure> | ||||
|        elements.  This matching is necessary because child elements are | ||||
|        not guaranteed to be ordered in any particular way. | ||||
|     """ | ||||
|     self.assertEquals(expected_element.tagName, actual_element.tagName) | ||||
|     Asserts that actual_node (a DOM node object) is equivalent to | ||||
|     expected_node (another DOM node object), in that either both of | ||||
|     them are CDATA nodes and have the same value, or both are DOM | ||||
|     elements and actual_node meets all of the following conditions: | ||||
|  | ||||
|     expected_attributes = expected_element.attributes | ||||
|     actual_attributes   = actual_element  .attributes | ||||
|     *  It has the same tag name as expected_node. | ||||
|     *  It has the same set of attributes as expected_node, each with | ||||
|        the same value as the corresponding attribute of expected_node. | ||||
|        An exception is any attribute named "time", which needs only be | ||||
|        convertible to a floating-point number. | ||||
|     *  It has an equivalent set of child nodes (including elements and | ||||
|        CDATA sections) as expected_node.  Note that we ignore the | ||||
|        order of the children as they are not guaranteed to be in any | ||||
|        particular order. | ||||
|     """ | ||||
|  | ||||
|     if expected_node.nodeType == Node.CDATA_SECTION_NODE: | ||||
|       self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType) | ||||
|       self.assertEquals(expected_node.nodeValue, actual_node.nodeValue) | ||||
|       return | ||||
|  | ||||
|     self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType) | ||||
|     self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType) | ||||
|     self.assertEquals(expected_node.tagName, actual_node.tagName) | ||||
|  | ||||
|     expected_attributes = expected_node.attributes | ||||
|     actual_attributes   = actual_node  .attributes | ||||
|     self.assertEquals(expected_attributes.length, actual_attributes.length) | ||||
|     for i in range(expected_attributes.length): | ||||
|       expected_attr = expected_attributes.item(i) | ||||
| @@ -75,13 +83,13 @@ class GTestXMLTestCase(unittest.TestCase): | ||||
|       self.assert_(actual_attr is not None) | ||||
|       self.assertEquals(expected_attr.value, actual_attr.value) | ||||
|  | ||||
|     expected_child = self._GetChildElements(expected_element) | ||||
|     actual_child   = self._GetChildElements(actual_element) | ||||
|     self.assertEquals(len(expected_child), len(actual_child)) | ||||
|     for child_id, element in expected_child.iteritems(): | ||||
|       self.assert_(child_id in actual_child, | ||||
|                    '<%s> is not in <%s>' % (child_id, actual_child)) | ||||
|       self._AssertEquivalentElements(element, actual_child[child_id]) | ||||
|     expected_children = self._GetChildren(expected_node) | ||||
|     actual_children = self._GetChildren(actual_node) | ||||
|     self.assertEquals(len(expected_children), len(actual_children)) | ||||
|     for child_id, child in expected_children.iteritems(): | ||||
|       self.assert_(child_id in actual_children, | ||||
|                    '<%s> is not in <%s>' % (child_id, actual_children)) | ||||
|       self.AssertEquivalentNodes(child, actual_children[child_id]) | ||||
|  | ||||
|   identifying_attribute = { | ||||
|     "testsuite": "name", | ||||
| @@ -89,18 +97,20 @@ class GTestXMLTestCase(unittest.TestCase): | ||||
|     "failure":   "message", | ||||
|     } | ||||
|  | ||||
|   def _GetChildElements(self, element): | ||||
|   def _GetChildren(self, element): | ||||
|     """ | ||||
|     Fetches all of the Element type child nodes of element, a DOM | ||||
|     Element object.  Returns them as the values of a dictionary keyed by | ||||
|     the value of one of the node's attributes.  For <testsuite> and | ||||
|     <testcase> elements, the identifying attribute is "name"; for | ||||
|     <failure> elements, it is "message".  An exception is raised if | ||||
|     any element other than the above three is encountered, if two | ||||
|     child elements with the same identifying attributes are encountered, | ||||
|     or if any other type of node is encountered, other than Text nodes | ||||
|     containing only whitespace. | ||||
|     Fetches all of the child nodes of element, a DOM Element object. | ||||
|     Returns them as the values of a dictionary keyed by the IDs of the | ||||
|     children.  For <testsuite> and <testcase> elements, the ID is the | ||||
|     value of their "name" attribute; for <failure> elements, it is the | ||||
|     value of the "message" attribute; for CDATA section node, it is | ||||
|     "detail".  An exception is raised if any element other than the | ||||
|     above four is encountered, if two child elements with the same | ||||
|     identifying attributes are encountered, or if any other type of | ||||
|     node is encountered, other than Text nodes containing only | ||||
|     whitespace. | ||||
|     """ | ||||
|  | ||||
|     children = {} | ||||
|     for child in element.childNodes: | ||||
|       if child.nodeType == Node.ELEMENT_NODE: | ||||
| @@ -111,11 +121,14 @@ class GTestXMLTestCase(unittest.TestCase): | ||||
|         children[childID] = child | ||||
|       elif child.nodeType == Node.TEXT_NODE: | ||||
|         self.assert_(child.nodeValue.isspace()) | ||||
|       elif child.nodeType == Node.CDATA_SECTION_NODE: | ||||
|         self.assert_("detail" not in children) | ||||
|         children["detail"] = child | ||||
|       else: | ||||
|         self.fail("Encountered unexpected node type %d" % child.nodeType) | ||||
|     return children | ||||
|  | ||||
|   def _NormalizeXml(self, element): | ||||
|   def NormalizeXml(self, element): | ||||
|     """ | ||||
|     Normalizes Google Test's XML output to eliminate references to transient | ||||
|     information that may change from run to run. | ||||
| @@ -126,13 +139,20 @@ class GTestXMLTestCase(unittest.TestCase): | ||||
|     *  The line number reported in the first line of the "message" | ||||
|        attribute of <failure> elements is replaced with a single asterisk. | ||||
|     *  The directory names in file paths are removed. | ||||
|     *  The stack traces are removed. | ||||
|     """ | ||||
|  | ||||
|     if element.tagName in ("testsuite", "testcase"): | ||||
|       time = element.getAttributeNode("time") | ||||
|       time.value = re.sub(r"^\d+$", "*", time.value) | ||||
|       time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) | ||||
|     elif element.tagName == "failure": | ||||
|       message = element.getAttributeNode("message") | ||||
|       message.value = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", message.value) | ||||
|       for child in element.childNodes: | ||||
|         if child.nodeType == Node.CDATA_SECTION_NODE: | ||||
|           # Removes the source line number. | ||||
|           cdata = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", child.nodeValue) | ||||
|           # Removes the actual stack trace. | ||||
|           child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*", | ||||
|                                    "", cdata) | ||||
|     for child in element.childNodes: | ||||
|       if child.nodeType == Node.ELEMENT_NODE: | ||||
|         self._NormalizeXml(child) | ||||
|         self.NormalizeXml(child) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 shiqian
					shiqian