• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include "include/cef_stream.h"
6 #include "include/cef_xml_reader.h"
7 #include "include/wrapper/cef_xml_object.h"
8 #include "tests/gtest/include/gtest/gtest.h"
9 
10 namespace {
11 
12 char g_test_xml[] =
13     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
14     "<?my_instruction my_value?>\n"
15     "<!DOCTYPE my_document SYSTEM \"example.dtd\" [\n"
16     "    <!ENTITY EA \"EA Value\">\n"
17     "    <!ENTITY EB \"EB Value\">\n"
18     "]>\n"
19     "<ns:obj xmlns:ns=\"http://www.example.org/ns\">\n"
20     "  <ns:objA>value A</ns:objA>\n"
21     "  <!-- my comment -->\n"
22     "  <ns:objB>\n"
23     "    <ns:objB_1>value B1</ns:objB_1>\n"
24     "    <ns:objB_2><![CDATA[some <br/> data]]></ns:objB_2>\n"
25     "    <ns:objB_3>&EB;</ns:objB_3>\n"
26     "    <ns:objB_4><b>this is</b> mixed content &EA;</ns:objB_4>\n"
27     "  </ns:objB>\n"
28     "  <ns:objC ns:attr1=\"value C1\" ns:attr2=\"value C2\"/><ns:objD>"
29     "</ns:objD>\n"
30     "</ns:obj>\n";
31 
32 }  // namespace
33 
34 // Test XML reading
TEST(XmlReaderTest,Read)35 TEST(XmlReaderTest, Read) {
36   // Create the stream reader.
37   CefRefPtr<CefStreamReader> stream(
38       CefStreamReader::CreateForData(g_test_xml, sizeof(g_test_xml) - 1));
39   ASSERT_TRUE(stream.get() != nullptr);
40 
41   // Create the XML reader.
42   CefRefPtr<CefXmlReader> reader(CefXmlReader::Create(
43       stream, XML_ENCODING_NONE, "http://www.example.org/example.xml"));
44   ASSERT_TRUE(reader.get() != nullptr);
45 
46   // Move to the processing instruction node.
47   ASSERT_TRUE(reader->MoveToNextNode());
48   ASSERT_EQ(reader->GetDepth(), 0);
49   ASSERT_EQ(reader->GetType(), XML_NODE_PROCESSING_INSTRUCTION);
50   ASSERT_EQ(reader->GetLocalName(), "my_instruction");
51   ASSERT_EQ(reader->GetQualifiedName(), "my_instruction");
52   ASSERT_TRUE(reader->HasValue());
53   ASSERT_EQ(reader->GetValue(), "my_value");
54 
55   // Move to the DOCTYPE node.
56   ASSERT_TRUE(reader->MoveToNextNode());
57   ASSERT_EQ(reader->GetDepth(), 0);
58   ASSERT_EQ(reader->GetType(), XML_NODE_DOCUMENT_TYPE);
59   ASSERT_EQ(reader->GetLocalName(), "my_document");
60   ASSERT_EQ(reader->GetQualifiedName(), "my_document");
61   ASSERT_FALSE(reader->HasValue());
62 
63   // Move to ns:obj element start node.
64   ASSERT_TRUE(reader->MoveToNextNode());
65   ASSERT_EQ(reader->GetDepth(), 0);
66   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
67   ASSERT_EQ(reader->GetLocalName(), "obj");
68   ASSERT_EQ(reader->GetPrefix(), "ns");
69   ASSERT_EQ(reader->GetQualifiedName(), "ns:obj");
70   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
71   ASSERT_TRUE(reader->HasAttributes());
72   ASSERT_EQ(reader->GetAttributeCount(), (size_t)1);
73   ASSERT_EQ(reader->GetAttribute(0), "http://www.example.org/ns");
74   ASSERT_EQ(reader->GetAttribute("xmlns:ns"), "http://www.example.org/ns");
75   ASSERT_EQ(reader->GetAttribute("ns", "http://www.w3.org/2000/xmlns/"),
76             "http://www.example.org/ns");
77 
78   // Move to the whitespace node.
79   ASSERT_TRUE(reader->MoveToNextNode());
80   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
81 
82   // Move to the ns:objA element start node.
83   ASSERT_TRUE(reader->MoveToNextNode());
84   ASSERT_EQ(reader->GetDepth(), 1);
85   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
86   ASSERT_EQ(reader->GetLocalName(), "objA");
87   ASSERT_EQ(reader->GetPrefix(), "ns");
88   ASSERT_EQ(reader->GetQualifiedName(), "ns:objA");
89   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
90   ASSERT_FALSE(reader->IsEmptyElement());
91   ASSERT_FALSE(reader->HasAttributes());
92   ASSERT_FALSE(reader->HasValue());
93 
94   // Move to the ns:objA value node.
95   ASSERT_TRUE(reader->MoveToNextNode());
96   ASSERT_EQ(reader->GetDepth(), 2);
97   ASSERT_EQ(reader->GetType(), XML_NODE_TEXT);
98   ASSERT_EQ(reader->GetLocalName(), "#text");
99   ASSERT_EQ(reader->GetQualifiedName(), "#text");
100   ASSERT_TRUE(reader->HasValue());
101   ASSERT_EQ(reader->GetValue(), "value A");
102 
103   // Move to the ns:objA element ending node.
104   ASSERT_TRUE(reader->MoveToNextNode());
105   ASSERT_EQ(reader->GetDepth(), 1);
106   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
107   ASSERT_EQ(reader->GetLocalName(), "objA");
108   ASSERT_EQ(reader->GetPrefix(), "ns");
109   ASSERT_EQ(reader->GetQualifiedName(), "ns:objA");
110   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
111   ASSERT_FALSE(reader->IsEmptyElement());
112   ASSERT_FALSE(reader->HasAttributes());
113   ASSERT_FALSE(reader->HasValue());
114 
115   // Move to the whitespace node.
116   ASSERT_TRUE(reader->MoveToNextNode());
117   ASSERT_EQ(reader->GetDepth(), 1);
118   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
119 
120   // Move to the comment node.
121   ASSERT_TRUE(reader->MoveToNextNode());
122   ASSERT_EQ(reader->GetDepth(), 1);
123   ASSERT_EQ(reader->GetType(), XML_NODE_COMMENT);
124   ASSERT_EQ(reader->GetLocalName(), "#comment");
125   ASSERT_EQ(reader->GetQualifiedName(), "#comment");
126   ASSERT_TRUE(reader->HasValue());
127   ASSERT_EQ(reader->GetValue(), " my comment ");
128 
129   // Move to the whitespace node.
130   ASSERT_TRUE(reader->MoveToNextNode());
131   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
132 
133   // Move to the ns:objB element start node.
134   ASSERT_TRUE(reader->MoveToNextNode());
135   ASSERT_EQ(reader->GetDepth(), 1);
136   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
137   ASSERT_EQ(reader->GetLocalName(), "objB");
138   ASSERT_EQ(reader->GetPrefix(), "ns");
139   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB");
140   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
141   ASSERT_FALSE(reader->IsEmptyElement());
142   ASSERT_FALSE(reader->HasAttributes());
143   ASSERT_FALSE(reader->HasValue());
144 
145   // Move to the whitespace node.
146   ASSERT_TRUE(reader->MoveToNextNode());
147   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
148 
149   // Move to the ns:objB_1 element start node.
150   ASSERT_TRUE(reader->MoveToNextNode());
151   ASSERT_EQ(reader->GetDepth(), 2);
152   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
153   ASSERT_EQ(reader->GetLocalName(), "objB_1");
154   ASSERT_EQ(reader->GetPrefix(), "ns");
155   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB_1");
156   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
157   ASSERT_FALSE(reader->IsEmptyElement());
158   ASSERT_FALSE(reader->HasAttributes());
159   ASSERT_FALSE(reader->HasValue());
160 
161   // Move to the ns:objB_1 value node.
162   ASSERT_TRUE(reader->MoveToNextNode());
163   ASSERT_EQ(reader->GetDepth(), 3);
164   ASSERT_EQ(reader->GetType(), XML_NODE_TEXT);
165   ASSERT_TRUE(reader->HasValue());
166   ASSERT_EQ(reader->GetValue(), "value B1");
167 
168   // Move to the ns:objB_1 element ending node.
169   ASSERT_TRUE(reader->MoveToNextNode());
170   ASSERT_EQ(reader->GetDepth(), 2);
171   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
172   ASSERT_EQ(reader->GetLocalName(), "objB_1");
173   ASSERT_EQ(reader->GetPrefix(), "ns");
174   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB_1");
175   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
176   ASSERT_FALSE(reader->IsEmptyElement());
177   ASSERT_FALSE(reader->HasAttributes());
178   ASSERT_FALSE(reader->HasValue());
179 
180   // Move to the whitespace node.
181   ASSERT_TRUE(reader->MoveToNextNode());
182   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
183 
184   // Move to the ns:objB_2 element start node.
185   ASSERT_TRUE(reader->MoveToNextNode());
186   ASSERT_EQ(reader->GetDepth(), 2);
187   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
188   ASSERT_EQ(reader->GetLocalName(), "objB_2");
189   ASSERT_EQ(reader->GetPrefix(), "ns");
190   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB_2");
191   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
192   ASSERT_FALSE(reader->IsEmptyElement());
193   ASSERT_FALSE(reader->HasAttributes());
194   ASSERT_FALSE(reader->HasValue());
195 
196   // Move to the ns:objB_2 value node.
197   ASSERT_TRUE(reader->MoveToNextNode());
198   ASSERT_EQ(reader->GetDepth(), 3);
199   ASSERT_EQ(reader->GetType(), XML_NODE_CDATA);
200   ASSERT_TRUE(reader->HasValue());
201   ASSERT_EQ(reader->GetValue(), "some <br/> data");
202 
203   // Move to the ns:objB_2 element ending node.
204   ASSERT_TRUE(reader->MoveToNextNode());
205   ASSERT_EQ(reader->GetDepth(), 2);
206   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
207   ASSERT_EQ(reader->GetLocalName(), "objB_2");
208   ASSERT_EQ(reader->GetPrefix(), "ns");
209   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB_2");
210   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
211   ASSERT_FALSE(reader->IsEmptyElement());
212   ASSERT_FALSE(reader->HasAttributes());
213   ASSERT_FALSE(reader->HasValue());
214 
215   // Move to the whitespace node.
216   ASSERT_TRUE(reader->MoveToNextNode());
217   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
218 
219   // Move to the ns:objB_3 element start node.
220   ASSERT_TRUE(reader->MoveToNextNode());
221   ASSERT_EQ(reader->GetDepth(), 2);
222   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
223   ASSERT_EQ(reader->GetLocalName(), "objB_3");
224   ASSERT_EQ(reader->GetPrefix(), "ns");
225   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB_3");
226   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
227   ASSERT_FALSE(reader->IsEmptyElement());
228   ASSERT_FALSE(reader->HasAttributes());
229   ASSERT_FALSE(reader->HasValue());
230 
231   // Move to the EB entity reference node.
232   ASSERT_TRUE(reader->MoveToNextNode());
233   ASSERT_EQ(reader->GetDepth(), 3);
234   ASSERT_EQ(reader->GetType(), XML_NODE_ENTITY_REFERENCE);
235   ASSERT_EQ(reader->GetLocalName(), "EB");
236   ASSERT_EQ(reader->GetQualifiedName(), "EB");
237   ASSERT_TRUE(reader->HasValue());
238   ASSERT_EQ(reader->GetValue(), "EB Value");
239 
240   // Move to the ns:objB_3 element ending node.
241   ASSERT_TRUE(reader->MoveToNextNode());
242   ASSERT_EQ(reader->GetDepth(), 2);
243   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
244   ASSERT_EQ(reader->GetLocalName(), "objB_3");
245   ASSERT_EQ(reader->GetPrefix(), "ns");
246   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB_3");
247   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
248   ASSERT_FALSE(reader->IsEmptyElement());
249   ASSERT_FALSE(reader->HasAttributes());
250   ASSERT_FALSE(reader->HasValue());
251 
252   // Move to the whitespace node.
253   ASSERT_TRUE(reader->MoveToNextNode());
254   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
255 
256   // Move to the ns:objB_4 element start node.
257   ASSERT_TRUE(reader->MoveToNextNode());
258   ASSERT_EQ(reader->GetDepth(), 2);
259   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
260   ASSERT_EQ(reader->GetLocalName(), "objB_4");
261   ASSERT_EQ(reader->GetPrefix(), "ns");
262   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB_4");
263   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
264   ASSERT_FALSE(reader->IsEmptyElement());
265   ASSERT_FALSE(reader->HasAttributes());
266   ASSERT_FALSE(reader->HasValue());
267   ASSERT_EQ(reader->GetInnerXml(), "<b>this is</b> mixed content &EA;");
268   ASSERT_EQ(reader->GetOuterXml(),
269             "<ns:objB_4 xmlns:ns=\"http://www.example.org/ns\">"
270             "<b>this is</b> mixed content &EA;</ns:objB_4>");
271 
272   // Move to the <b> element node.
273   ASSERT_TRUE(reader->MoveToNextNode());
274   ASSERT_EQ(reader->GetDepth(), 3);
275   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
276   ASSERT_EQ(reader->GetLocalName(), "b");
277   ASSERT_EQ(reader->GetQualifiedName(), "b");
278   ASSERT_FALSE(reader->IsEmptyElement());
279   ASSERT_FALSE(reader->HasAttributes());
280   ASSERT_FALSE(reader->HasValue());
281 
282   // Move to the text node.
283   ASSERT_TRUE(reader->MoveToNextNode());
284   ASSERT_EQ(reader->GetDepth(), 4);
285   ASSERT_EQ(reader->GetType(), XML_NODE_TEXT);
286   ASSERT_EQ(reader->GetLocalName(), "#text");
287   ASSERT_EQ(reader->GetQualifiedName(), "#text");
288   ASSERT_TRUE(reader->HasValue());
289   ASSERT_EQ(reader->GetValue(), "this is");
290 
291   // Move to the </b> element node.
292   ASSERT_TRUE(reader->MoveToNextNode());
293   ASSERT_EQ(reader->GetDepth(), 3);
294   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
295   ASSERT_EQ(reader->GetLocalName(), "b");
296   ASSERT_EQ(reader->GetQualifiedName(), "b");
297 
298   // Move to the text node.
299   ASSERT_TRUE(reader->MoveToNextNode());
300   ASSERT_EQ(reader->GetDepth(), 3);
301   ASSERT_EQ(reader->GetType(), XML_NODE_TEXT);
302   ASSERT_EQ(reader->GetLocalName(), "#text");
303   ASSERT_EQ(reader->GetQualifiedName(), "#text");
304   ASSERT_TRUE(reader->HasValue());
305   ASSERT_EQ(reader->GetValue(), " mixed content ");
306 
307   // Move to the EA entity reference node.
308   ASSERT_TRUE(reader->MoveToNextNode());
309   ASSERT_EQ(reader->GetDepth(), 3);
310   ASSERT_EQ(reader->GetType(), XML_NODE_ENTITY_REFERENCE);
311   ASSERT_EQ(reader->GetLocalName(), "EA");
312   ASSERT_EQ(reader->GetQualifiedName(), "EA");
313   ASSERT_TRUE(reader->HasValue());
314   ASSERT_EQ(reader->GetValue(), "EA Value");
315 
316   // Move to the ns:objB_4 element ending node.
317   ASSERT_TRUE(reader->MoveToNextNode());
318   ASSERT_EQ(reader->GetDepth(), 2);
319   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
320   ASSERT_EQ(reader->GetLocalName(), "objB_4");
321   ASSERT_EQ(reader->GetPrefix(), "ns");
322   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB_4");
323   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
324   ASSERT_FALSE(reader->IsEmptyElement());
325   ASSERT_FALSE(reader->HasAttributes());
326   ASSERT_FALSE(reader->HasValue());
327 
328   // Move to the whitespace node.
329   ASSERT_TRUE(reader->MoveToNextNode());
330   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
331 
332   // Move to the ns:objB element ending node.
333   ASSERT_TRUE(reader->MoveToNextNode());
334   ASSERT_EQ(reader->GetDepth(), 1);
335   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
336   ASSERT_EQ(reader->GetLocalName(), "objB");
337   ASSERT_EQ(reader->GetPrefix(), "ns");
338   ASSERT_EQ(reader->GetQualifiedName(), "ns:objB");
339   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
340   ASSERT_FALSE(reader->IsEmptyElement());
341   ASSERT_FALSE(reader->HasAttributes());
342   ASSERT_FALSE(reader->HasValue());
343 
344   // Move to the whitespace node.
345   ASSERT_TRUE(reader->MoveToNextNode());
346   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
347 
348   // Move to the ns:objC element start node.
349   ASSERT_TRUE(reader->MoveToNextNode());
350   ASSERT_EQ(reader->GetDepth(), 1);
351   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
352   ASSERT_EQ(reader->GetLocalName(), "objC");
353   ASSERT_EQ(reader->GetPrefix(), "ns");
354   ASSERT_EQ(reader->GetQualifiedName(), "ns:objC");
355   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
356   ASSERT_TRUE(reader->IsEmptyElement());
357   ASSERT_TRUE(reader->HasAttributes());
358   ASSERT_FALSE(reader->HasValue());
359   ASSERT_EQ(reader->GetAttributeCount(), (size_t)2);
360   ASSERT_EQ(reader->GetAttribute(0), "value C1");
361   ASSERT_EQ(reader->GetAttribute("ns:attr1"), "value C1");
362   ASSERT_EQ(reader->GetAttribute("attr1", "http://www.example.org/ns"),
363             "value C1");
364   ASSERT_EQ(reader->GetAttribute(1), "value C2");
365   ASSERT_EQ(reader->GetAttribute("ns:attr2"), "value C2");
366   ASSERT_EQ(reader->GetAttribute("attr2", "http://www.example.org/ns"),
367             "value C2");
368 
369   // Move to the ns:attr1 attribute.
370   ASSERT_TRUE(reader->MoveToFirstAttribute());
371   ASSERT_EQ(reader->GetDepth(), 2);
372   ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
373   ASSERT_EQ(reader->GetLocalName(), "attr1");
374   ASSERT_EQ(reader->GetPrefix(), "ns");
375   ASSERT_EQ(reader->GetQualifiedName(), "ns:attr1");
376   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
377   ASSERT_TRUE(reader->HasValue());
378   ASSERT_FALSE(reader->IsEmptyElement());
379   ASSERT_FALSE(reader->HasAttributes());
380   ASSERT_EQ(reader->GetValue(), "value C1");
381 
382   // Move to the ns:attr2 attribute.
383   ASSERT_TRUE(reader->MoveToNextAttribute());
384   ASSERT_EQ(reader->GetDepth(), 2);
385   ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
386   ASSERT_EQ(reader->GetLocalName(), "attr2");
387   ASSERT_EQ(reader->GetPrefix(), "ns");
388   ASSERT_EQ(reader->GetQualifiedName(), "ns:attr2");
389   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
390   ASSERT_TRUE(reader->HasValue());
391   ASSERT_FALSE(reader->IsEmptyElement());
392   ASSERT_FALSE(reader->HasAttributes());
393   ASSERT_EQ(reader->GetValue(), "value C2");
394 
395   // No more attributes.
396   ASSERT_FALSE(reader->MoveToNextAttribute());
397 
398   // Return to the ns:objC element start node.
399   ASSERT_TRUE(reader->MoveToCarryingElement());
400   ASSERT_EQ(reader->GetDepth(), 1);
401   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
402   ASSERT_EQ(reader->GetQualifiedName(), "ns:objC");
403 
404   // Move to the ns:attr1 attribute.
405   ASSERT_TRUE(reader->MoveToAttribute(0));
406   ASSERT_EQ(reader->GetDepth(), 2);
407   ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
408   ASSERT_EQ(reader->GetLocalName(), "attr1");
409   ASSERT_EQ(reader->GetPrefix(), "ns");
410   ASSERT_EQ(reader->GetQualifiedName(), "ns:attr1");
411   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
412   ASSERT_TRUE(reader->HasValue());
413   ASSERT_FALSE(reader->IsEmptyElement());
414   ASSERT_FALSE(reader->HasAttributes());
415   ASSERT_EQ(reader->GetValue(), "value C1");
416 
417   // Return to the ns:objC element start node.
418   ASSERT_TRUE(reader->MoveToCarryingElement());
419   ASSERT_EQ(reader->GetDepth(), 1);
420   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
421   ASSERT_EQ(reader->GetQualifiedName(), "ns:objC");
422 
423   // Move to the ns:attr2 attribute.
424   ASSERT_TRUE(reader->MoveToAttribute("ns:attr2"));
425   ASSERT_EQ(reader->GetDepth(), 2);
426   ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
427   ASSERT_EQ(reader->GetLocalName(), "attr2");
428   ASSERT_EQ(reader->GetPrefix(), "ns");
429   ASSERT_EQ(reader->GetQualifiedName(), "ns:attr2");
430   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
431   ASSERT_TRUE(reader->HasValue());
432   ASSERT_FALSE(reader->IsEmptyElement());
433   ASSERT_FALSE(reader->HasAttributes());
434   ASSERT_EQ(reader->GetValue(), "value C2");
435 
436   // Move to the ns:attr1 attribute without returning to the ns:objC element.
437   ASSERT_TRUE(reader->MoveToAttribute("attr1", "http://www.example.org/ns"));
438   ASSERT_EQ(reader->GetDepth(), 2);
439   ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
440   ASSERT_EQ(reader->GetLocalName(), "attr1");
441   ASSERT_EQ(reader->GetPrefix(), "ns");
442   ASSERT_EQ(reader->GetQualifiedName(), "ns:attr1");
443   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
444   ASSERT_TRUE(reader->HasValue());
445   ASSERT_FALSE(reader->IsEmptyElement());
446   ASSERT_FALSE(reader->HasAttributes());
447   ASSERT_EQ(reader->GetValue(), "value C1");
448 
449   // Move to the ns:objD element start node.
450   ASSERT_TRUE(reader->MoveToNextNode());
451   ASSERT_EQ(reader->GetDepth(), 1);
452   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
453   ASSERT_EQ(reader->GetLocalName(), "objD");
454   ASSERT_EQ(reader->GetPrefix(), "ns");
455   ASSERT_EQ(reader->GetQualifiedName(), "ns:objD");
456   ASSERT_FALSE(reader->IsEmptyElement());
457   ASSERT_FALSE(reader->HasAttributes());
458   ASSERT_FALSE(reader->HasValue());
459 
460   // Move to the ns:objD element end node.
461   ASSERT_TRUE(reader->MoveToNextNode());
462   ASSERT_EQ(reader->GetDepth(), 1);
463   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
464   ASSERT_EQ(reader->GetLocalName(), "objD");
465   ASSERT_EQ(reader->GetPrefix(), "ns");
466   ASSERT_EQ(reader->GetQualifiedName(), "ns:objD");
467   ASSERT_FALSE(reader->IsEmptyElement());
468   ASSERT_FALSE(reader->HasAttributes());
469   ASSERT_FALSE(reader->HasValue());
470 
471   // Move to the whitespace node without returning to the ns:objC element.
472   ASSERT_TRUE(reader->MoveToNextNode());
473   ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
474 
475   // Move to ns:obj element ending node.
476   ASSERT_TRUE(reader->MoveToNextNode());
477   ASSERT_EQ(reader->GetDepth(), 0);
478   ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
479   ASSERT_EQ(reader->GetLocalName(), "obj");
480   ASSERT_EQ(reader->GetPrefix(), "ns");
481   ASSERT_EQ(reader->GetQualifiedName(), "ns:obj");
482   ASSERT_EQ(reader->GetNamespaceURI(), "http://www.example.org/ns");
483   ASSERT_FALSE(reader->IsEmptyElement());
484   ASSERT_TRUE(reader->HasAttributes());
485   ASSERT_FALSE(reader->HasValue());
486   // Strangely, the end node will report if the starting node has attributes
487   // but will not provide access to them.
488   ASSERT_TRUE(reader->HasAttributes());
489   ASSERT_EQ(reader->GetAttributeCount(), (size_t)0);
490 
491   // And we're done.
492   ASSERT_FALSE(reader->MoveToNextNode());
493 
494   ASSERT_TRUE(reader->Close());
495 }
496 
497 // Test XML read error handling.
TEST(XmlReaderTest,ReadError)498 TEST(XmlReaderTest, ReadError) {
499   char test_str[] =
500       "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
501       "<!ATTRIBUTE foo bar>\n";
502 
503   // Create the stream reader.
504   CefRefPtr<CefStreamReader> stream(
505       CefStreamReader::CreateForData(test_str, sizeof(test_str) - 1));
506   ASSERT_TRUE(stream.get() != nullptr);
507 
508   // Create the XML reader.
509   CefRefPtr<CefXmlReader> reader(CefXmlReader::Create(
510       stream, XML_ENCODING_NONE, "http://www.example.org/example.xml"));
511   ASSERT_TRUE(reader.get() != nullptr);
512 
513   // Move to the processing instruction node and generate parser error.
514   ASSERT_FALSE(reader->MoveToNextNode());
515   ASSERT_TRUE(reader->HasError());
516 }
517 
518 // Test XmlObject load behavior.
TEST(XmlReaderTest,ObjectLoad)519 TEST(XmlReaderTest, ObjectLoad) {
520   // Create the stream reader.
521   CefRefPtr<CefStreamReader> stream(
522       CefStreamReader::CreateForData(g_test_xml, sizeof(g_test_xml) - 1));
523   ASSERT_TRUE(stream.get() != nullptr);
524 
525   // Create the XML reader.
526   CefRefPtr<CefXmlObject> object(new CefXmlObject("object"));
527   ASSERT_TRUE(object->Load(stream, XML_ENCODING_NONE,
528                            "http://www.example.org/example.xml", nullptr));
529 
530   ASSERT_FALSE(object->HasAttributes());
531   ASSERT_TRUE(object->HasChildren());
532   ASSERT_EQ(object->GetChildCount(), (size_t)1);
533 
534   CefRefPtr<CefXmlObject> obj(object->FindChild("ns:obj"));
535   ASSERT_TRUE(obj.get());
536   ASSERT_TRUE(obj->HasChildren());
537   ASSERT_EQ(obj->GetChildCount(), (size_t)4);
538 
539   CefRefPtr<CefXmlObject> obj_child(obj->FindChild("ns:objC"));
540   ASSERT_TRUE(obj_child.get());
541   ASSERT_EQ(obj_child->GetName(), "ns:objC");
542   ASSERT_FALSE(obj_child->HasChildren());
543   ASSERT_FALSE(obj_child->HasValue());
544   ASSERT_TRUE(obj_child->HasAttributes());
545 
546   CefXmlObject::ObjectVector obj_children;
547   ASSERT_EQ(obj->GetChildren(obj_children), (size_t)4);
548   ASSERT_EQ(obj_children.size(), (size_t)4);
549 
550   CefXmlObject::ObjectVector::const_iterator it = obj_children.begin();
551   for (int ct = 0; it != obj_children.end(); ++it, ++ct) {
552     obj_child = *it;
553     ASSERT_TRUE(obj_child.get());
554     if (ct == 0) {
555       // ns:objA
556       ASSERT_EQ(obj_child->GetName(), "ns:objA");
557       ASSERT_FALSE(obj_child->HasChildren());
558       ASSERT_TRUE(obj_child->HasValue());
559       ASSERT_FALSE(obj_child->HasAttributes());
560       ASSERT_EQ(obj_child->GetValue(), "value A");
561     } else if (ct == 1) {
562       // ns:objB
563       ASSERT_EQ(obj_child->GetName(), "ns:objB");
564       ASSERT_TRUE(obj_child->HasChildren());
565       ASSERT_FALSE(obj_child->HasValue());
566       ASSERT_FALSE(obj_child->HasAttributes());
567       ASSERT_EQ(obj_child->GetChildCount(), (size_t)4);
568       obj_child = obj_child->FindChild("ns:objB_4");
569       ASSERT_TRUE(obj_child.get());
570       ASSERT_TRUE(obj_child->HasValue());
571       ASSERT_EQ(obj_child->GetValue(), "<b>this is</b> mixed content EA Value");
572     } else if (ct == 2) {
573       // ns:objC
574       ASSERT_EQ(obj_child->GetName(), "ns:objC");
575       ASSERT_FALSE(obj_child->HasChildren());
576       ASSERT_FALSE(obj_child->HasValue());
577       ASSERT_TRUE(obj_child->HasAttributes());
578 
579       CefXmlObject::AttributeMap attribs;
580       ASSERT_EQ(obj_child->GetAttributes(attribs), (size_t)2);
581       ASSERT_EQ(attribs.size(), (size_t)2);
582       ASSERT_EQ(attribs["ns:attr1"], "value C1");
583       ASSERT_EQ(attribs["ns:attr2"], "value C2");
584 
585       ASSERT_EQ(obj_child->GetAttributeCount(), (size_t)2);
586       ASSERT_TRUE(obj_child->HasAttribute("ns:attr1"));
587       ASSERT_EQ(obj_child->GetAttributeValue("ns:attr1"), "value C1");
588       ASSERT_TRUE(obj_child->HasAttribute("ns:attr2"));
589       ASSERT_EQ(obj_child->GetAttributeValue("ns:attr2"), "value C2");
590     } else if (ct == 3) {
591       // ns:objD
592       ASSERT_EQ(obj_child->GetName(), "ns:objD");
593       ASSERT_FALSE(obj_child->HasChildren());
594       ASSERT_FALSE(obj_child->HasValue());
595       ASSERT_FALSE(obj_child->HasAttributes());
596     }
597   }
598 }
599 
600 // Test XmlObject load error handling behavior.
TEST(XmlReaderTest,ObjectLoadError)601 TEST(XmlReaderTest, ObjectLoadError) {
602   // Test start/end tag mismatch error.
603   {
604     char error_xml[] = "<obj>\n<foo>\n</obj>\n</foo>";
605 
606     // Create the stream reader.
607     CefRefPtr<CefStreamReader> stream(
608         CefStreamReader::CreateForData(error_xml, sizeof(error_xml) - 1));
609     ASSERT_TRUE(stream.get() != nullptr);
610 
611     CefString error_str;
612 
613     // Create the XML reader.
614     CefRefPtr<CefXmlObject> object(new CefXmlObject("object"));
615     ASSERT_FALSE(object->Load(stream, XML_ENCODING_NONE,
616                               "http://www.example.org/example.xml",
617                               &error_str));
618     ASSERT_EQ(error_str,
619               "Opening and ending tag mismatch: foo line 2 and obj, line 3");
620   }
621 
622   // Test value following child error.
623   {
624     char error_xml[] = "<obj>\n<foo>\n</foo>disallowed value\n</obj>";
625 
626     // Create the stream reader.
627     CefRefPtr<CefStreamReader> stream(
628         CefStreamReader::CreateForData(error_xml, sizeof(error_xml) - 1));
629     ASSERT_TRUE(stream.get() != nullptr);
630 
631     CefString error_str;
632 
633     // Create the XML reader.
634     CefRefPtr<CefXmlObject> object(new CefXmlObject("object"));
635     ASSERT_FALSE(object->Load(stream, XML_ENCODING_NONE,
636                               "http://www.example.org/example.xml",
637                               &error_str));
638     ASSERT_EQ(error_str, "Value following child element, line 4");
639   }
640 }
641