10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2004, Google Inc.
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer.
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     and/or other materials provided with the distribution.
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     derived from this software without specific prior written permission.
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <iostream>
29cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include <sstream>
30cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include <string>
31cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/xmllite/xmlelement.h"
322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/common.h"
332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/gunit.h"
342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/thread.h"
350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing buzz::QName;
370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing buzz::XmlAttr;
380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing buzz::XmlChild;
390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing buzz::XmlElement;
400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstd::ostream& operator<<(std::ostream& os, const QName& name) {
420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  os << name.Namespace() << ":" << name.LocalPart();
430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return os;
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST(XmlElementTest, TestConstructors) {
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement elt(QName("google:test", "first"));
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<test:first xmlns:test=\"google:test\"/>", elt.Str());
490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement elt2(QName("google:test", "first"), true);
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<first xmlns=\"google:test\"/>", elt2.Str());
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST(XmlElementTest, TestAdd) {
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement elt(QName("google:test", "root"), true);
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddElement(new XmlElement(QName("google:test", "first")));
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddElement(new XmlElement(QName("google:test", "nested")), 1);
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddText("nested-value", 2);
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddText("between-", 1);
600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddText("value", 1);
610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddElement(new XmlElement(QName("google:test", "nested2")), 1);
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddElement(new XmlElement(QName("google:test", "second")));
630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddText("init-value", 1);
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddElement(new XmlElement(QName("google:test", "nested3")), 1);
650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddText("trailing-value", 1);
660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // make sure it looks ok overall
680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root xmlns=\"google:test\">"
690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        "<first><nested>nested-value</nested>between-value<nested2/></first>"
700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        "<second>init-value<nested3/>trailing-value</second></root>",
710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        elt.Str());
720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // make sure text was concatenated
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlChild * pchild =
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    elt.FirstChild()->AsElement()->FirstChild()->NextChild();
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(pchild->IsText());
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("between-value", pchild->AsText()->Text());
780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST(XmlElementTest, TestAttrs) {
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement elt(QName("", "root"));
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.SetAttr(QName("", "a"), "avalue");
830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root a=\"avalue\"/>", elt.Str());
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.SetAttr(QName("", "b"), "bvalue");
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root a=\"avalue\" b=\"bvalue\"/>", elt.Str());
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.SetAttr(QName("", "a"), "avalue2");
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue\"/>", elt.Str());
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.SetAttr(QName("", "b"), "bvalue2");
920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\"/>", elt.Str());
930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.SetAttr(QName("", "c"), "cvalue");
950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\"/>", elt.Str());
960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlAttr * patt = elt.FirstAttr();
980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(QName("", "a"), patt->Name());
990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("avalue2", patt->Value());
1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  patt = patt->NextAttr();
1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(QName("", "b"), patt->Name());
1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("bvalue2", patt->Value());
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  patt = patt->NextAttr();
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(QName("", "c"), patt->Name());
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("cvalue", patt->Value());
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  patt = patt->NextAttr();
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(NULL == patt);
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(elt.HasAttr(QName("", "a")));
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(elt.HasAttr(QName("", "b")));
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(elt.HasAttr(QName("", "c")));
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_FALSE(elt.HasAttr(QName("", "d")));
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.SetAttr(QName("", "d"), "dvalue");
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>",
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      elt.Str());
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(elt.HasAttr(QName("", "d")));
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.ClearAttr(QName("", "z"));  // not found, no effect
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>",
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      elt.Str());
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.ClearAttr(QName("", "b"));
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root a=\"avalue2\" c=\"cvalue\" d=\"dvalue\"/>", elt.Str());
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.ClearAttr(QName("", "a"));
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root c=\"cvalue\" d=\"dvalue\"/>", elt.Str());
1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.ClearAttr(QName("", "d"));
1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root c=\"cvalue\"/>", elt.Str());
1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.ClearAttr(QName("", "c"));
1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root/>", elt.Str());
1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST(XmlElementTest, TestBodyText) {
1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement elt(QName("", "root"));
1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("", elt.BodyText());
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddText("body value text");
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("body value text", elt.BodyText());
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.ClearChildren();
1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddText("more value ");
1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddText("text");
1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("more value text", elt.BodyText());
1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.ClearChildren();
1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddText("decoy");
1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.AddElement(new XmlElement(QName("", "dummy")));
1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("", elt.BodyText());
1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.SetBodyText("replacement");
1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("replacement", elt.BodyText());
1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.SetBodyText("");
1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(NULL == elt.FirstChild());
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  elt.SetBodyText("goodbye");
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("goodbye", elt.FirstChild()->AsText()->Text());
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("goodbye", elt.BodyText());
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST(XmlElementTest, TestCopyConstructor) {
1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement * element = XmlElement::ForStr(
1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "<root xmlns='test-foo'>This is a <em a='avalue' b='bvalue'>"
1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "little <b>little</b></em> test</root>");
1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement * pelCopy = new XmlElement(*element);
1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<root xmlns=\"test-foo\">This is a <em a=\"avalue\" b=\"bvalue\">"
1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "little <b>little</b></em> test</root>", pelCopy->Str());
1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  delete pelCopy;
1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  pelCopy = new XmlElement(*(element->FirstChild()->NextChild()->AsElement()));
1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("<foo:em a=\"avalue\" b=\"bvalue\" xmlns:foo=\"test-foo\">"
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "little <foo:b>little</foo:b></foo:em>", pelCopy->Str());
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlAttr * patt = pelCopy->FirstAttr();
1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(QName("", "a"), patt->Name());
1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("avalue", patt->Value());
1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  patt = patt->NextAttr();
1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(QName("", "b"), patt->Name());
1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("bvalue", patt->Value());
1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  patt = patt->NextAttr();
1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(NULL == patt);
1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  delete pelCopy;
1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  delete element;
1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST(XmlElementTest, TestNameSearch) {
1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement * element = XmlElement::ForStr(
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "<root xmlns='test-foo'>"
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "<firstname>George</firstname>"
2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "<middlename>X.</middlename>"
2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "some text"
2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "<lastname>Harrison</lastname>"
2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "<firstname>John</firstname>"
2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "<middlename>Y.</middlename>"
2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      "<lastname>Lennon</lastname>"
2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "</root>");
2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(NULL ==
2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      element->FirstNamed(QName("", "firstname")));
2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(element->FirstChild(),
2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      element->FirstNamed(QName("test-foo", "firstname")));
2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(element->FirstChild()->NextChild(),
2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      element->FirstNamed(QName("test-foo", "middlename")));
2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(element->FirstElement()->NextElement(),
2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      element->FirstNamed(QName("test-foo", "middlename")));
2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("Harrison",
2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      element->TextNamed(QName("test-foo", "lastname")));
2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(element->FirstElement()->NextElement()->NextElement(),
2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      element->FirstNamed(QName("test-foo", "lastname")));
2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("John", element->FirstNamed(QName("test-foo", "firstname"))->
2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      NextNamed(QName("test-foo", "firstname"))->BodyText());
2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("Y.", element->FirstNamed(QName("test-foo", "middlename"))->
2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      NextNamed(QName("test-foo", "middlename"))->BodyText());
2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("Lennon", element->FirstNamed(QName("test-foo", "lastname"))->
2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      NextNamed(QName("test-foo", "lastname"))->BodyText());
2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(NULL == element->FirstNamed(QName("test-foo", "firstname"))->
2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      NextNamed(QName("test-foo", "firstname"))->
2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      NextNamed(QName("test-foo", "firstname")));
2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  delete element;
2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgclass XmlElementCreatorThread : public rtc::Thread {
2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElementCreatorThread(int count, buzz::QName qname) :
2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      count_(count), qname_(qname) {}
2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
238e5b49108d39835fbab2ae1c29eff4542a57a8ed5wu@webrtc.org  virtual ~XmlElementCreatorThread() {
239e5b49108d39835fbab2ae1c29eff4542a57a8ed5wu@webrtc.org    Stop();
240e5b49108d39835fbab2ae1c29eff4542a57a8ed5wu@webrtc.org  }
241e5b49108d39835fbab2ae1c29eff4542a57a8ed5wu@webrtc.org
2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  virtual void Run() {
2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::vector<buzz::XmlElement*> elems;
2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < count_; i++) {
2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      elems.push_back(new XmlElement(qname_));
2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < count_; i++) {
2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      delete elems[i];
2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private:
2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  int count_;
2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  buzz::QName qname_;
2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// If XmlElement creation and destruction isn't thread safe,
2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// this test should crash.
2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST(XmlElementTest, TestMultithread) {
2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  int thread_count = 2;  // Was 100, but that's too slow.
2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  int elem_count = 100;  // Was 100000, but that's too slow.
2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  buzz::QName qname("foo", "bar");
2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2642a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  std::vector<rtc::Thread*> threads;
2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (int i = 0; i < thread_count; i++) {
2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    threads.push_back(
2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        new XmlElementCreatorThread(elem_count, qname));
2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    threads[i]->Start();
2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (int i = 0; i < thread_count; i++) {
2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    threads[i]->Stop();
2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    delete threads[i];
2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
276