Beef up tests for CFX_XMLNode insertions.

Also add helper functions to make expected results more obvious.


Change-Id: Id122b388600a42beb7525ebbcef4757603fca2cc
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/54351
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/xml/cfx_xmlnode_unittest.cpp b/core/fxcrt/xml/cfx_xmlnode_unittest.cpp
index e707d80..6055e92 100644
--- a/core/fxcrt/xml/cfx_xmlnode_unittest.cpp
+++ b/core/fxcrt/xml/cfx_xmlnode_unittest.cpp
@@ -2,9 +2,32 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+namespace {
+
+WideString ChildrenString(CFX_XMLElement* pParent) {
+  WideString result;
+  for (CFX_XMLNode* pChild = pParent->GetFirstChild(); pChild;
+       pChild = pChild->GetNextSibling()) {
+    result += static_cast<CFX_XMLElement*>(pChild)->GetName();
+  }
+  return result;
+}
+
+WideString ReverseChildrenString(CFX_XMLElement* pParent) {
+  WideString result;
+  for (CFX_XMLNode* pChild = pParent->GetLastChildForTesting(); pChild;
+       pChild = pChild->GetPrevSiblingForTesting()) {
+    result = static_cast<CFX_XMLElement*>(pChild)->GetName() + result;
+  }
+  return result;
+}
+
+}  // namespace
+
 TEST(CFX_XMLNodeTest, GetParent) {
   CFX_XMLElement node1(L"node");
   CFX_XMLElement node2(L"node2");
@@ -78,35 +101,47 @@
 }
 
 TEST(CFX_XMLNodeTest, AddingChildren) {
-  CFX_XMLElement node1(L"node");
-  CFX_XMLElement node2(L"node2");
-  CFX_XMLElement node3(L"node3");
+  CFX_XMLElement parent(L"Root");
+  CFX_XMLElement nodeA(L"A");
+  CFX_XMLElement nodeB(L"B");
 
-  node1.AppendChild(&node2);
-  node1.AppendChild(&node3);
+  parent.AppendChild(&nodeA);
+  parent.AppendChild(&nodeB);
 
-  EXPECT_EQ(&node1, node2.GetParent());
-  EXPECT_EQ(&node1, node3.GetParent());
+  EXPECT_EQ(L"AB", ChildrenString(&parent));
+  EXPECT_EQ(L"AB", ReverseChildrenString(&parent));
+  EXPECT_EQ(&parent, nodeA.GetParent());
+  EXPECT_EQ(&parent, nodeB.GetParent());
+  EXPECT_EQ(&nodeA, parent.GetFirstChild());
+  EXPECT_EQ(&nodeB, nodeA.GetNextSibling());
+  EXPECT_TRUE(nodeB.GetNextSibling() == nullptr);
 
-  EXPECT_EQ(&node2, node1.GetFirstChild());
-  EXPECT_EQ(&node3, node2.GetNextSibling());
-  EXPECT_TRUE(node3.GetNextSibling() == nullptr);
+  // Insert to negative appends last child.
+  CFX_XMLElement nodeC(L"C");
+  parent.InsertChildNode(&nodeC, -1);
+  EXPECT_EQ(L"ABC", ChildrenString(&parent));
+  EXPECT_EQ(L"ABC", ReverseChildrenString(&parent));
+  EXPECT_EQ(&parent, nodeC.GetParent());
+  EXPECT_EQ(&nodeC, nodeB.GetNextSibling());
+  EXPECT_TRUE(nodeC.GetNextSibling() == nullptr);
 
-  // Insert to negative appends.
-  CFX_XMLElement node4(L"node4");
-  node1.InsertChildNode(&node4, -1);
-  EXPECT_EQ(&node1, node4.GetParent());
-  EXPECT_EQ(&node4, node3.GetNextSibling());
-  EXPECT_TRUE(node4.GetNextSibling() == nullptr);
+  // Insertion occurs before a zero based index.
+  CFX_XMLElement nodeD(L"D");
+  parent.InsertChildNode(&nodeD, 1);
+  EXPECT_EQ(L"ADBC", ChildrenString(&parent));
+  EXPECT_EQ(L"ADBC", ReverseChildrenString(&parent));
 
-  CFX_XMLElement node5(L"node5");
-  node1.InsertChildNode(&node5, 1);
-  EXPECT_EQ(&node1, node5.GetParent());
-  EXPECT_EQ(&node2, node1.GetFirstChild());
-  EXPECT_EQ(&node5, node2.GetNextSibling());
-  EXPECT_EQ(&node3, node5.GetNextSibling());
-  EXPECT_EQ(&node4, node3.GetNextSibling());
-  EXPECT_TRUE(node4.GetNextSibling() == nullptr);
+  // Insert to 0 appends first child.
+  CFX_XMLElement nodeE(L"E");
+  parent.InsertChildNode(&nodeE, 0);
+  EXPECT_EQ(L"EADBC", ChildrenString(&parent));
+  EXPECT_EQ(L"EADBC", ReverseChildrenString(&parent));
+
+  // Insert to out-of-bounds index appends last child.
+  CFX_XMLElement nodeF(L"F");
+  parent.InsertChildNode(&nodeF, 10);
+  EXPECT_EQ(L"EADBCF", ChildrenString(&parent));
+  EXPECT_EQ(L"EADBCF", ReverseChildrenString(&parent));
 }
 
 #ifndef NDEBUG
@@ -129,16 +164,20 @@
   node1.AppendChild(&node3);
   node1.AppendChild(&node4);
 
+  EXPECT_EQ(L"node2node3node4", ChildrenString(&node1));
+  EXPECT_EQ(L"node2node3node4", ReverseChildrenString(&node1));
   EXPECT_EQ(&node2, node1.GetFirstChild());
   EXPECT_EQ(&node3, node2.GetNextSibling());
   EXPECT_EQ(&node4, node3.GetNextSibling());
   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
 
   node1.RemoveChildNode(&node3);
+
+  EXPECT_EQ(L"node2node4", ChildrenString(&node1));
+  EXPECT_EQ(L"node2node4", ReverseChildrenString(&node1));
   EXPECT_TRUE(node3.GetParent() == nullptr);
   EXPECT_TRUE(node3.GetNextSibling() == nullptr);
   EXPECT_TRUE(node3.GetPrevSiblingForTesting() == nullptr);
-
   EXPECT_EQ(&node2, node1.GetFirstChild());
   EXPECT_EQ(&node4, node2.GetNextSibling());
   EXPECT_EQ(&node2, node4.GetPrevSiblingForTesting());
@@ -155,16 +194,20 @@
   node1.AppendChild(&node3);
   node1.AppendChild(&node4);
 
+  EXPECT_EQ(L"node2node3node4", ChildrenString(&node1));
+  EXPECT_EQ(L"node2node3node4", ReverseChildrenString(&node1));
   EXPECT_EQ(&node2, node1.GetFirstChild());
   EXPECT_EQ(&node3, node2.GetNextSibling());
   EXPECT_EQ(&node4, node3.GetNextSibling());
   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
 
   node1.RemoveChildNode(&node2);
+
+  EXPECT_EQ(L"node3node4", ChildrenString(&node1));
+  EXPECT_EQ(L"node3node4", ReverseChildrenString(&node1));
   EXPECT_TRUE(node2.GetParent() == nullptr);
   EXPECT_TRUE(node2.GetNextSibling() == nullptr);
   EXPECT_TRUE(node2.GetPrevSiblingForTesting() == nullptr);
-
   EXPECT_EQ(&node3, node1.GetFirstChild());
   EXPECT_TRUE(node3.GetPrevSiblingForTesting() == nullptr);
   EXPECT_EQ(&node4, node3.GetNextSibling());
@@ -181,16 +224,20 @@
   node1.AppendChild(&node3);
   node1.AppendChild(&node4);
 
+  EXPECT_EQ(L"node2node3node4", ChildrenString(&node1));
+  EXPECT_EQ(L"node2node3node4", ReverseChildrenString(&node1));
   EXPECT_EQ(&node2, node1.GetFirstChild());
   EXPECT_EQ(&node3, node2.GetNextSibling());
   EXPECT_EQ(&node4, node3.GetNextSibling());
   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
 
   node1.RemoveChildNode(&node4);
+
+  EXPECT_EQ(L"node2node3", ChildrenString(&node1));
+  EXPECT_EQ(L"node2node3", ReverseChildrenString(&node1));
   EXPECT_TRUE(node4.GetParent() == nullptr);
   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
   EXPECT_TRUE(node4.GetPrevSiblingForTesting() == nullptr);
-
   EXPECT_EQ(&node2, node1.GetFirstChild());
   EXPECT_EQ(&node3, node2.GetNextSibling());
   EXPECT_TRUE(node3.GetNextSibling() == nullptr);