1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.IO;
7 using System.Xml;
8 using Microsoft.Test.ModuleCore;
9 
10 namespace CoreXml.Test.XLinq
11 {
12     public partial class FunctionalTests : TestModule
13     {
14         public partial class XNodeReaderTests : XLinqTestCase
15         {
16             public partial class TCReadSubtree : BridgeHelpers
17             {
18                 //[Variation("ReadSubtree only works on Element Node")]
ReadSubtreeOnlyWorksOnElementNode()19                 public void ReadSubtreeOnlyWorksOnElementNode()
20                 {
21                     XmlReader DataReader = GetReader();
22 
23                     while (DataReader.Read())
24                     {
25                         if (DataReader.NodeType != XmlNodeType.Element)
26                         {
27                             string nodeType = DataReader.NodeType.ToString();
28                             bool flag = true;
29                             try
30                             {
31                                 DataReader.ReadSubtree();
32                             }
33                             catch (InvalidOperationException)
34                             {
35                                 flag = false;
36                             }
37 
38                             if (flag)
39                             {
40                                 TestLog.WriteLine("ReadSubtree doesn't throw InvalidOp Exception on NodeType : " + nodeType);
41                                 throw new TestException(TestResult.Failed, "");
42                             }
43 
44                             // now try next read
45                             try
46                             {
47                                 DataReader.Read();
48                             }
49                             catch (XmlException)
50                             {
51                                 TestLog.WriteLine("Cannot Read after an invalid operation exception");
52                                 throw new TestException(TestResult.Failed, "");
53                             }
54                         }
55                         else
56                         {
57                             if (DataReader.HasAttributes)
58                             {
59                                 bool flag = true;
60                                 DataReader.MoveToFirstAttribute();
61                                 try
62                                 {
63                                     DataReader.ReadSubtree();
64                                 }
65                                 catch (InvalidOperationException)
66                                 {
67                                     flag = false;
68                                 }
69                                 if (flag)
70                                 {
71                                     TestLog.WriteLine("ReadSubtree doesn't throw InvalidOp Exception on Attribute Node Type");
72                                     throw new TestException(TestResult.Failed, "");
73                                 }
74 
75                                 //now try next read.
76                                 try
77                                 {
78                                     DataReader.Read();
79                                 }
80                                 catch (XmlException)
81                                 {
82                                     TestLog.WriteLine("Cannot Read after an invalid operation exception");
83                                     throw new TestException(TestResult.Failed, "");
84                                 }
85                             }
86                         }
87                     }//end while
88                 }
89 
90                 private string _xml = "<root><elem1><elempi/><?pi target?><elem2 xmlns='xyz'><elem/><!--Comment--><x:elem3 xmlns:x='pqr'><elem4 attr4='4'/></x:elem3></elem2></elem1><elem5/><elem6/></root>";
91 
92                 //[Variation("ReadSubtree Test on Root", Priority = 0, Params = new object[] { "root", "", "ELEMENT", "", "", "NONE" })]
93                 //[Variation("ReadSubtree Test depth=1", Priority = 0, Params = new object[] { "elem1", "", "ELEMENT", "elem5", "", "ELEMENT" })]
94                 //[Variation("ReadSubtree Test depth=2", Priority = 0, Params = new object[] { "elem2", "", "ELEMENT", "elem1", "", "ENDELEMENT" })]
95                 //[Variation("ReadSubtree Test depth=3", Priority = 0, Params = new object[] { "x:elem3", "", "ELEMENT", "elem2", "", "ENDELEMENT" })]
96                 //[Variation("ReadSubtree Test depth=4", Priority = 0, Params = new object[] { "elem4", "", "ELEMENT", "x:elem3", "", "ENDELEMENT" })]
97                 //[Variation("ReadSubtree Test empty element", Priority = 0, Params = new object[] { "elem5", "", "ELEMENT", "elem6", "", "ELEMENT" })]
98                 //[Variation("ReadSubtree Test empty element before root", Priority = 0, Params = new object[] { "elem6", "", "ELEMENT", "root", "", "ENDELEMENT" })]
99                 //[Variation("ReadSubtree Test PI after element", Priority = 0, Params = new object[] { "elempi", "", "ELEMENT", "pi", "target", "PROCESSINGINSTRUCTION" })]
100                 //[Variation("ReadSubtree Test Comment after element", Priority = 0, Params = new object[] { "elem", "", "ELEMENT", "", "Comment", "COMMENT" })]
v2()101                 public void v2()
102                 {
103                     int count = 0;
104                     string name = Variation.Params[count++].ToString();
105                     string value = Variation.Params[count++].ToString();
106                     string type = Variation.Params[count++].ToString();
107 
108                     string oname = Variation.Params[count++].ToString();
109                     string ovalue = Variation.Params[count++].ToString();
110                     string otype = Variation.Params[count++].ToString();
111 
112                     XmlReader DataReader = GetReader(new StringReader(_xml));
113                     PositionOnElement(DataReader, name);
114 
115                     XmlReader r = DataReader.ReadSubtree();
116                     TestLog.Compare(r.ReadState, ReadState.Initial, "Reader state is not Initial");
117                     TestLog.Compare(r.Name, String.Empty, "Name is not empty");
118                     TestLog.Compare(r.NodeType, XmlNodeType.None, "Nodetype is not empty");
119                     TestLog.Compare(r.Depth, 0, "Depth is not zero");
120 
121                     r.Read();
122 
123                     TestLog.Compare(r.ReadState, ReadState.Interactive, "Reader state is not Interactive");
124                     TestLog.Compare(r.Name, name, "Subreader name doesn't match");
125                     TestLog.Compare(r.Value, value, "Subreader value doesn't match");
126                     TestLog.Compare(r.NodeType.ToString().ToUpperInvariant(), type, "Subreader nodetype doesn't match");
127                     TestLog.Compare(r.Depth, 0, "Subreader Depth is not zero");
128 
129                     while (r.Read()) ;
130                     r.Dispose();
131 
132                     TestLog.Compare(r.ReadState, ReadState.Closed, "Reader state is not Initial");
133                     TestLog.Compare(r.Name, String.Empty, "Name is not empty");
134                     TestLog.Compare(r.NodeType, XmlNodeType.None, "Nodetype is not empty");
135 
136                     DataReader.Read();
137 
138                     TestLog.Compare(DataReader.Name, oname, "Main name doesn't match");
139                     TestLog.Compare(DataReader.Value, ovalue, "Main value doesn't match");
140                     TestLog.Compare(DataReader.NodeType.ToString().ToUpperInvariant(), otype, "Main nodetype doesn't match");
141 
142                     DataReader.Dispose();
143                 }
144 
145                 //[Variation("Read with entities", Priority = 1)]
v3()146                 public void v3()
147                 {
148                     XmlReader DataReader = GetReader();
149                     PositionOnElement(DataReader, "PLAY");
150 
151                     XmlReader r = DataReader.ReadSubtree();
152 
153                     while (r.Read())
154                     {
155                         if (r.NodeType == XmlNodeType.EntityReference)
156                         {
157                             if (r.CanResolveEntity)
158                                 r.ResolveEntity();
159                         }
160                     }
161 
162                     r.Dispose();
163                     DataReader.Dispose();
164                 }
165 
166                 //[Variation("Inner XML on Subtree reader", Priority = 1)]
v4()167                 public void v4()
168                 {
169                     string xmlStr = "<elem1><elem2/></elem1>";
170                     XmlReader DataReader = GetReaderStr(xmlStr);
171                     PositionOnElement(DataReader, "elem1");
172                     XmlReader r = DataReader.ReadSubtree();
173                     r.Read();
174                     TestLog.Compare(r.ReadInnerXml(), "<elem2 />", "Inner Xml Fails");
175                     TestLog.Compare(r.Read(), false, "Read returns false");
176                     r.Dispose();
177                     DataReader.Dispose();
178                 }
179 
180                 //[Variation("Outer XML on Subtree reader", Priority = 1)]
v5()181                 public void v5()
182                 {
183                     string xmlStr = "<elem1><elem2/></elem1>";
184                     XmlReader DataReader = GetReaderStr(xmlStr);
185                     PositionOnElement(DataReader, "elem1");
186                     XmlReader r = DataReader.ReadSubtree();
187                     r.Read();
188                     TestLog.Compare(r.ReadOuterXml(), "<elem1><elem2 /></elem1>", "Outer Xml Fails");
189                     TestLog.Compare(r.Read(), false, "Read returns true");
190                     r.Dispose();
191                     DataReader.Dispose();
192                 }
193 
194                 //[Variation("ReadString on Subtree reader", Priority = 1)]
v6()195                 public void v6()
196                 {
197                     string xmlStr = "<elem1><elem2/></elem1>";
198                     XmlReader DataReader = GetReaderStr(xmlStr);
199                     PositionOnElement(DataReader, "elem1");
200                     XmlReader r = DataReader.ReadSubtree();
201                     r.Read();
202                     TestLog.Compare(r.Read(), true, "Read returns false");
203 
204                     r.Dispose();
205                     DataReader.Dispose();
206                 }
207 
208                 //[Variation("Close on inner reader with CloseInput should not close the outer reader", Priority = 1, Params = new object[] { "true" })]
209                 //[Variation("Close on inner reader with CloseInput should not close the outer reader", Priority = 1, Params = new object[] { "false" })]
210 
v7()211                 public void v7()
212                 {
213                     XmlReader DataReader = GetReader();
214                     bool ci = Boolean.Parse(Variation.Params[0].ToString());
215                     XmlReaderSettings settings = new XmlReaderSettings();
216                     settings.CloseInput = ci;
217 
218                     PositionOnElement(DataReader, "elem2");
219                     XmlReader r = DataReader.ReadSubtree();
220                     r.Dispose();
221 
222                     TestLog.Compare(DataReader.ReadState, ReadState.Interactive, "ReadState not interactive");
223 
224                     DataReader.Dispose();
225                 }
226 
NestRead(XmlReader r)227                 private XmlReader NestRead(XmlReader r)
228                 {
229                     r.Read();
230                     r.Read();
231                     if (!(r.Name == "elem0" && r.NodeType == XmlNodeType.Element))
232                     {
233                         NestRead(r.ReadSubtree());
234                     }
235                     r.Dispose();
236                     return r;
237                 }
238 
239                 //[Variation("Nested Subtree reader calls", Priority = 2)]
v8()240                 public void v8()
241                 {
242                     string xmlStr = "<elem1><elem2><elem3><elem4><elem5><elem6><elem7><elem8><elem9><elem0></elem0></elem9></elem8></elem7></elem6></elem5></elem4></elem3></elem2></elem1>";
243                     XmlReader r = GetReader(new StringReader(xmlStr));
244 
245                     NestRead(r);
246                     TestLog.Compare(r.ReadState, ReadState.Closed, "Reader Read State is not closed");
247                 }
248 
249                 //[Variation("ReadSubtree for element depth more than 4K chars", Priority = 2)]
v100()250                 public void v100()
251                 {
252                     ManagedNodeWriter mnw = new ManagedNodeWriter();
253                     mnw.PutPattern("X");
254                     do
255                     {
256                         mnw.OpenElement();
257                         mnw.CloseElement();
258                     }
259                     while (mnw.GetNodes().Length < 4096);
260 
261                     mnw.Finish();
262 
263                     XmlReader DataReader = GetReader(new StringReader(mnw.GetNodes()));
264 
265                     PositionOnElement(DataReader, "ELEMENT_2");
266 
267                     XmlReader r = DataReader.ReadSubtree();
268                     while (r.Read()) ;
269                     r.Dispose();
270 
271                     DataReader.Read();
272 
273                     TestLog.Compare(DataReader.Name, "ELEMENT_1", "Main name doesn't match");
274                     TestLog.Compare(DataReader.Value, "", "Main value doesn't match");
275                     TestLog.Compare(DataReader.NodeType.ToString().ToUpperInvariant(), "ENDELEMENT", "Main nodetype doesn't match");
276 
277                     DataReader.Dispose();
278                 }
279 
280                 //[Variation("Multiple Namespaces on Subtree reader", Priority = 1)]
MultipleNamespacesOnSubtreeReader()281                 public void MultipleNamespacesOnSubtreeReader()
282                 {
283                     string xmlStr = "<root xmlns:p1='a' xmlns:p2='b'><e p1:a='' p2:a=''></e></root>";
284                     XmlReader DataReader = GetReader(new StringReader(xmlStr));
285                     PositionOnElement(DataReader, "e");
286                     XmlReader r = DataReader.ReadSubtree();
287                     while (r.Read()) ;
288                     r.Dispose();
289                     DataReader.Dispose();
290                 }
291 
292                 //[Variation("Subtree Reader caches the NodeType and reports node type of Attribute on subsequent reads.", Priority = 1)]
SubtreeReaderCachesNodeTypeAndReportsNodeTypeOfAttributeOnSubsequentReads()293                 public void SubtreeReaderCachesNodeTypeAndReportsNodeTypeOfAttributeOnSubsequentReads()
294                 {
295                     string xmlStr = "<root xmlns='foo'><b blah='blah'/><b/></root>";
296                     XmlReader DataReader = GetReader(new StringReader(xmlStr));
297                     PositionOnElement(DataReader, "root");
298                     XmlReader xxr = DataReader.ReadSubtree();
299 
300                     //Now on root.
301                     xxr.Read();
302                     TestLog.Compare(xxr.Name, "root", "Root Elem");
303                     TestLog.Compare(xxr.MoveToNextAttribute(), true, "MTNA 1");
304 
305                     TestLog.Compare(xxr.NodeType, XmlNodeType.Attribute, "XMLNS NT");
306                     TestLog.Compare(xxr.Name, "xmlns", "XMLNS Attr");
307                     TestLog.Compare(xxr.Value, "foo", "XMLNS Value");
308                     TestLog.Compare(xxr.MoveToNextAttribute(), false, "MTNA 2");
309 
310                     //Now on b.
311                     xxr.Read();
312                     TestLog.Compare(xxr.Name, "b", "b Elem");
313                     TestLog.Compare(xxr.MoveToNextAttribute(), true, "MTNA 3");
314 
315                     TestLog.Compare(xxr.NodeType, XmlNodeType.Attribute, "blah NT");
316                     TestLog.Compare(xxr.Name, "blah", "blah Attr");
317                     TestLog.Compare(xxr.Value, "blah", "blah Value");
318                     TestLog.Compare(xxr.MoveToNextAttribute(), false, "MTNA 4");
319 
320                     // Now on /b.
321                     xxr.Read();
322                     TestLog.Compare(xxr.Name, "b", "b EndElem");
323                     TestLog.Compare(xxr.NodeType, XmlNodeType.Element, "b Elem NT");
324                     TestLog.Compare(xxr.MoveToNextAttribute(), false, "MTNA 5");
325 
326                     xxr.Read();
327                     TestLog.Compare(xxr.Name, "root", "root EndElem");
328                     TestLog.Compare(xxr.NodeType, XmlNodeType.EndElement, "root EndElem NT");
329                     TestLog.Compare(xxr.MoveToNextAttribute(), false, "MTNA 6");
330 
331                     xxr.Dispose();
332 
333                     DataReader.Dispose();
334                 }
335             }
336         }
337     }
338 }
339