3 * Copyright 2004, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "talk/xmllite/qname.h"
32 #include "talk/xmllite/xmlparser.h"
33 #include "webrtc/base/common.h"
34 #include "webrtc/base/gunit.h"
37 using buzz::XmlParser;
38 using buzz::XmlParseContext;
39 using buzz::XmlParseHandler;
41 class XmlParserTestHandler : public XmlParseHandler {
43 virtual void StartElement(XmlParseContext * pctx,
44 const char * name, const char ** atts) {
45 ss_ << "START (" << pctx->ResolveQName(name, false).Merged();
47 ss_ << ", " << pctx->ResolveQName(*atts, true).Merged()
48 << "='" << *(atts+1) << "'";
53 virtual void EndElement(XmlParseContext * pctx, const char * name) {
58 virtual void CharacterData(XmlParseContext * pctx,
59 const char * text, int len) {
61 ss_ << "TEXT (" << std::string(text, len) << ") ";
63 virtual void Error(XmlParseContext * pctx, XML_Error code) {
65 ss_ << "ERROR (" << static_cast<int>(code) << ") ";
67 virtual ~XmlParserTestHandler() {
74 std::string StrClear() {
75 std::string result = ss_.str();
81 std::stringstream ss_;
85 TEST(XmlParserTest, TestTrivial) {
86 XmlParserTestHandler handler;
87 XmlParser::ParseXml(&handler, "<testing/>");
88 EXPECT_EQ("START (testing) END ", handler.Str());
91 TEST(XmlParserTest, TestAttributes) {
93 XmlParserTestHandler handler;
94 XmlParser::ParseXml(&handler, "<testing a='b'/>");
95 EXPECT_EQ("START (testing, a='b') END ", handler.Str());
98 XmlParserTestHandler handler;
99 XmlParser::ParseXml(&handler, "<testing e='' long='some text'/>");
100 EXPECT_EQ("START (testing, e='', long='some text') END ", handler.Str());
104 TEST(XmlParserTest, TestNesting) {
106 XmlParserTestHandler handler;
107 XmlParser::ParseXml(&handler,
108 "<top><first/><second><third></third></second></top>");
109 EXPECT_EQ("START (top) START (first) END START (second) START (third) "
110 "END END END ", handler.Str());
113 XmlParserTestHandler handler;
114 XmlParser::ParseXml(&handler, "<top><fifth><deeper><and><deeper/></and>"
115 "<sibling><leaf/></sibling></deeper></fifth><first/><second>"
116 "<third></third></second></top>");
117 EXPECT_EQ("START (top) START (fifth) START (deeper) START (and) START "
118 "(deeper) END END START (sibling) START (leaf) END END END "
119 "END START (first) END START (second) START (third) END END END ",
124 TEST(XmlParserTest, TestXmlDecl) {
126 XmlParserTestHandler handler;
127 XmlParser::ParseXml(&handler, "<?xml version=\"1.0\"?><testing/>");
128 EXPECT_EQ("START (testing) END ", handler.Str());
131 XmlParserTestHandler handler;
132 XmlParser::ParseXml(&handler,
133 "<?xml version=\"1.0\" encoding=\"utf-8\"?><testing/>");
134 EXPECT_EQ("START (testing) END ", handler.Str());
137 XmlParserTestHandler handler;
138 XmlParser::ParseXml(&handler,
139 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
141 EXPECT_EQ("START (testing) END ", handler.Str());
145 TEST(XmlParserTest, TestNamespace) {
147 XmlParserTestHandler handler;
148 XmlParser::ParseXml(&handler, "<top xmlns='my-namespace' a='b'/>");
149 EXPECT_EQ("START (my-namespace:top, xmlns='my-namespace', a='b') END ",
153 XmlParserTestHandler handler;
154 XmlParser::ParseXml(&handler, "<foo:top xmlns:foo='my-namespace' "
155 "a='b' foo:c='d'/>");
156 EXPECT_EQ("START (my-namespace:top, "
157 "http://www.w3.org/2000/xmlns/:foo='my-namespace', "
158 "a='b', my-namespace:c='d') END ", handler.Str());
161 XmlParserTestHandler handler;
162 XmlParser::ParseXml(&handler, "<top><nested xmlns='my-namespace'><leaf/>"
163 "</nested><sibling/></top>");
164 EXPECT_EQ("START (top) START (my-namespace:nested, xmlns='my-namespace') "
165 "START (my-namespace:leaf) END END START (sibling) END END ",
170 TEST(XmlParserTest, TestIncremental) {
171 XmlParserTestHandler handler;
172 XmlParser parser(&handler);
173 std::string fragment;
175 fragment = "<stream:stream";
176 parser.Parse(fragment.c_str(), fragment.length(), false);
177 EXPECT_EQ("", handler.StrClear());
179 fragment = " id=\"abcdefg\" xmlns=\"";
180 parser.Parse(fragment.c_str(), fragment.length(), false);
181 EXPECT_EQ("", handler.StrClear());
183 fragment = "j:c\" xmlns:stream='hm";
184 parser.Parse(fragment.c_str(), fragment.length(), false);
185 EXPECT_EQ("", handler.StrClear());
187 fragment = "ph'><test";
188 parser.Parse(fragment.c_str(), fragment.length(), false);
189 EXPECT_EQ("START (hmph:stream, id='abcdefg', xmlns='j:c', "
190 "http://www.w3.org/2000/xmlns/:stream='hmph') ", handler.StrClear());
192 fragment = "ing/><again/>abracad";
193 parser.Parse(fragment.c_str(), fragment.length(), false);
194 EXPECT_EQ("START (j:c:testing) END START (j:c:again) END TEXT (abracad) ",
197 fragment = "abra</stream:";
198 parser.Parse(fragment.c_str(), fragment.length(), false);
199 EXPECT_EQ("TEXT (abra) ", handler.StrClear());
201 fragment = "stream>";
202 parser.Parse(fragment.c_str(), fragment.length(), false);
203 EXPECT_EQ("END ", handler.StrClear());
206 TEST(XmlParserTest, TestReset) {
208 XmlParserTestHandler handler;
209 XmlParser parser(&handler);
210 std::string fragment;
212 fragment = "<top><first/><second><third></third>";
213 parser.Parse(fragment.c_str(), fragment.length(), false);
214 EXPECT_EQ("START (top) START (first) END START (second) START (third) END ",
218 fragment = "<tip><first/><second><third></third>";
219 parser.Parse(fragment.c_str(), fragment.length(), false);
220 EXPECT_EQ("START (tip) START (first) END START (second) START (third) END ",
224 XmlParserTestHandler handler;
225 XmlParser parser(&handler);
226 std::string fragment;
228 fragment = "<top xmlns='m'>";
229 parser.Parse(fragment.c_str(), fragment.length(), false);
230 EXPECT_EQ("START (m:top, xmlns='m') ", handler.StrClear());
232 fragment = "<testing/><frag";
233 parser.Parse(fragment.c_str(), fragment.length(), false);
234 EXPECT_EQ("START (m:testing) END ", handler.StrClear());
237 fragment = "<testing><fragment/";
238 parser.Parse(fragment.c_str(), fragment.length(), false);
239 EXPECT_EQ("START (testing) ", handler.StrClear());
242 parser.Parse(fragment.c_str(), fragment.length(), false);
243 EXPECT_EQ("START (fragment) END ", handler.StrClear());
247 TEST(XmlParserTest, TestError) {
249 XmlParserTestHandler handler;
250 XmlParser::ParseXml(&handler, "junk");
251 EXPECT_EQ("ERROR (2) ", handler.Str());
254 XmlParserTestHandler handler;
255 XmlParser::ParseXml(&handler, "<top/> garbage ");
256 EXPECT_EQ("START (top) END ERROR (9) ", handler.Str());
259 XmlParserTestHandler handler;
260 XmlParser::ParseXml(&handler, "<-hm->");
261 EXPECT_EQ("ERROR (4) ", handler.Str());
264 XmlParserTestHandler handler;
265 XmlParser::ParseXml(&handler, "<hello>&foobar;</hello>");
266 EXPECT_EQ("START (hello) ERROR (11) ", handler.Str());
269 XmlParserTestHandler handler;
270 XmlParser::ParseXml(&handler,
271 "<!DOCTYPE HTML PUBLIC \"foobar\" \"barfoo\">");
272 EXPECT_EQ("ERROR (3) ", handler.Str());
275 // XmlParser requires utf-8
276 XmlParserTestHandler handler;
277 XmlParser::ParseXml(&handler,
278 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><test/>");
279 EXPECT_EQ("ERROR (19) ", handler.Str());
282 // XmlParser requires version 1.0
283 XmlParserTestHandler handler;
284 XmlParser::ParseXml(&handler,
285 "<?xml version=\"2.0\"?><test/>");
286 EXPECT_EQ("ERROR (2) ", handler.Str());
289 // XmlParser requires standalone documents
290 XmlParserTestHandler handler;
291 XmlParser::ParseXml(&handler,
292 "<?xml version=\"1.0\" standalone=\"no\"?><test/>");
293 EXPECT_EQ("ERROR (2) ", handler.Str());
296 // XmlParser doesn't like empty namespace URIs
297 XmlParserTestHandler handler;
298 XmlParser::ParseXml(&handler,
299 "<test xmlns:foo='' foo:bar='huh?'>");
300 EXPECT_EQ("ERROR (2) ", handler.Str());