* xslttest.cs : wrap streams with using {...} so the file descriptors
[mono.git] / mcs / class / System.XML / Test / System.Xml.Xsl / XslTransformTests.cs
1 //
2 // System.Xml.Xsl.XslTransformTests.cs
3 //
4 // Author:
5 //   Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 //
7 // (C) 2002 Atsushi Enomoto
8 //
9
10 using System;
11 using System.Globalization;
12 using System.IO;
13 using System.Text;
14 using System.Xml;
15 using System.Xml.XPath;
16 using System.Xml.Xsl;
17 using NUnit.Framework;
18
19 namespace MonoTests.System.Xml.Xsl
20 {
21         [TestFixture]
22         public class XslTransformTests : Assertion
23         {
24                 XmlDocument doc;
25                 XslTransform xslt;
26                 XmlDocument result;
27
28                 [SetUp]
29                 public void GetReady()
30                 {
31                         doc = new XmlDocument ();
32                         xslt = new XslTransform ();
33                         result = new XmlDocument ();
34                 }
35
36                 [Test]
37                 public void TestBasicTransform ()
38                 {
39                         doc.LoadXml ("<root/>");
40                         xslt.Load ("Test/XmlFiles/xsl/empty.xsl");
41                         xslt.Transform ("Test/XmlFiles/xsl/empty.xsl", "Test/XmlFiles/xsl/result.xml");
42                         result.Load ("Test/XmlFiles/xsl/result.xml");
43                         AssertEquals ("count", 2, result.ChildNodes.Count);
44                 }
45
46                 [Test]
47                 [ExpectedException (typeof (XsltCompileException))]
48                 public void InvalidStylesheet ()
49                 {
50                         XmlDocument doc = new XmlDocument ();
51                         doc.LoadXml ("<xsl:element xmlns:xsl='http://www.w3.org/1999/XSL/Transform' />");
52                         XslTransform t = new XslTransform ();
53                         t.Load (doc);
54                 }
55
56                 [Test]
57                 [ExpectedException (typeof (XsltCompileException))]
58                 public void EmptyStylesheet ()
59                 {
60                         XmlDocument doc = new XmlDocument ();
61                         XslTransform t = new XslTransform ();
62                         t.Load (doc);
63                 }
64
65                 [Test]
66                 [ExpectedException (typeof (XsltCompileException))]
67                 public void InvalidStylesheet2 ()
68                 {
69                         string xml = @"<root>text</root>";
70                         string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
71         <xsl:template match='/root'>
72                 <xsl:call-template name='foo'>
73                         <xsl:with-param name='name' value='text()' />
74                 </xsl:call-template>
75         </xsl:template>
76         <xsl:template name='foo'>
77                 <xsl:param name='name' />
78                 <result>
79                         <xsl:if test='1'>
80                                 <xsl:variable name='last' value='text()' />
81                                 <xsl:value-of select='$last' />
82                         </xsl:if>
83                 </result>
84         </xsl:template>
85 </xsl:stylesheet>
86 ";
87                         XslTransform xslt = new XslTransform ();
88                         xslt.Load (new XPathDocument (new XmlTextReader (xsl, XmlNodeType.Document, null)));
89                 }
90
91                 [Test()]\r
92                 [Category ("NotWorking")] // it depends on "mcs" existence
93                 public void MsxslTest() {\r
94                         string _styleSheet = @"\r
95                         <xslt:stylesheet xmlns:xslt=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"" xmlns:msxsl=""urn:schemas-microsoft-com:xslt"" xmlns:stringutils=""urn:schemas-sourceforge.net-blah"">\r
96                                 <xslt:output method=""text"" />\r
97                                 <msxsl:script language=""C#"" implements-prefix=""stringutils"">\r
98                                         <![CDATA[\r
99                                                 string PadRight( string str, int padding) {\r
100                                                     return str.PadRight(padding);\r
101                                                 }\r
102                                         ]]>\r
103                                 </msxsl:script>\r
104                                 <xslt:template match=""test"">\r
105                                         <xslt:value-of select=""stringutils:PadRight(@name, 20)"" />\r
106                                 </xslt:template>\r
107                         </xslt:stylesheet>";\r
108 \r
109                         StringReader stringReader = new StringReader(_styleSheet);\r
110                         \r
111                         XslTransform transform = new XslTransform();\r
112                         XmlTextReader reader = new XmlTextReader(stringReader);\r
113                         transform.Load(reader, new XmlUrlResolver(), AppDomain.CurrentDomain.Evidence);\r
114 \r
115                         StringBuilder sb = new StringBuilder();\r
116                         StringWriter writer = new StringWriter(sb, CultureInfo.InvariantCulture);\r
117                         XsltArgumentList arguments = new XsltArgumentList();\r
118 \r
119                         XmlDocument xmlDoc = new XmlDocument();\r
120                         xmlDoc.LoadXml("<test name=\"test\" />");\r
121 \r
122                         // Do transformation\r
123                         transform.Transform(xmlDoc, new XsltArgumentList(), writer, new XmlUrlResolver());\r
124 \r
125 \r
126                         AssertEquals("test".PadRight(20), sb.ToString());\r
127                 }\r
128 \r
129                 [Test]\r
130                 public void MSXslNodeSet ()
131                 {
132                         string xsl = @"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
133 <xsl:template match='/'>
134 <root>
135         <xsl:variable name='var'>
136                 <xsl:copy-of select='root/foo' />
137         </xsl:variable>
138         <xsl:for-each select='msxsl:node-set($var)/foo'>
139                 <xsl:value-of select='name(.)' />: <xsl:value-of select='@attr' />
140         </xsl:for-each>
141 </root>
142 </xsl:template>
143 </xsl:stylesheet>";
144                         StringWriter sw = new StringWriter ();
145                         XslTransform t = new XslTransform ();
146                         t.Load (new XPathDocument (new StringReader (xsl)));
147                         t.Transform (new XPathDocument (new XmlTextReader (new StringReader ("<root><foo attr='A'/><foo attr='B'/><foo attr='C'/></root>"))), null, sw);
148                         AssertEquals (@"<?xml version=""1.0"" encoding=""utf-16""?><root xmlns:msxsl=""urn:schemas-microsoft-com:xslt"">foo: Afoo: Bfoo: C</root>", sw.ToString ());
149                 }
150 \r
151                 [Test]
152                 [Category ("NotDotNet")]\r
153                 // Actually MS.NET here throws XsltException, but Mono returns\r
154                 // XPathException (since XPath evaluation engine generally
155                 // catches (should catch) static error. It is implementation \r
156                 // dependent matter.\r
157                 [ExpectedException (typeof (XPathException))]\r
158                 public void MSXslNodeSetRejectsNodeSet ()
159                 {
160                         string xsl = @"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
161 <xsl:template match='/'>
162 <root>
163         <!-- msxsl:node-set() does not accept a node set -->
164         <xsl:for-each select='msxsl:node-set(root/foo)'>
165                 <xsl:value-of select='name(.)' />: <xsl:value-of select='@attr' />
166         </xsl:for-each>
167 </root>
168 </xsl:template>
169 </xsl:stylesheet>";
170                         StringWriter sw = new StringWriter ();
171                         XslTransform t = new XslTransform ();
172                         t.Load (new XPathDocument (new StringReader (xsl)));
173                         t.Transform (new XPathDocument (new XmlTextReader (new StringReader ("<root><foo attr='A'/><foo attr='B'/><foo attr='C'/></root>"))), null, sw);
174                 }
175
176                 [Test]
177                 public void EvaluateEmptyVariableAsBoolean ()
178                 {
179                         string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
180 <xsl:template match='/'>
181 <xsl:variable name='var'><empty /></xsl:variable>
182   <root><xsl:if test='$var'>true</xsl:if></root>
183 </xsl:template>
184 </xsl:stylesheet>";
185                         XslTransform t = new XslTransform ();
186                         t.Load (new XPathDocument (new StringReader (xsl)));
187                         StringWriter sw = new StringWriter ();
188                         t.Transform (
189                                 new XPathDocument (new StringReader ("<root/>")),
190                                 null,
191                                 sw);
192                         Assert (sw.ToString ().IndexOf ("true") > 0);
193                 }
194
195                 [Test]
196                 [ExpectedException (typeof (XsltCompileException))]
197                 public void NotAllowedPatternAxis ()
198                 {
199                         string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
200 <xsl:template match='/descendant-or-self::node()/elem'>
201 <ERROR/>
202 </xsl:template>
203 </xsl:stylesheet>";
204                         new XslTransform ().Load (new XPathDocument (
205                                 new StringReader (xsl)));
206                 }
207
208                 [Test]
209                 [ExpectedException (typeof (XsltCompileException))]
210                 public void ImportIncorrectlyLocated ()
211                 {
212                         string xsl = @"<xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
213 <xsl:template match='/'></xsl:template>
214 <xsl:import href='dummy.xsl' />
215 </xsl:transform>";
216                         new XslTransform ().Load (new XPathDocument (
217                                 new StringReader (xsl)));
218                 }
219
220                 [Test]
221                 [Category ("NotDotNet")]
222                 public void DontHoldStylesheetReference ()
223                 {
224                         // This test is optional. Examines whether Load() does
225                         // not hold loaded stylesheet XPathNavigator internally.
226                         XslTransform t = new XslTransform ();
227                         WeakReference wr = StylesheetLoad (t, "<xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'/>");
228                         GC.Collect (0);
229                         GC.Collect (2);
230                         Assert ("load", !wr.IsAlive);
231                         wr = StylesheetTransform (t, "<root/>");
232                         GC.Collect (0);
233                         GC.Collect (2);
234                         Assert ("transform", !wr.IsAlive);
235                 }
236
237                 private WeakReference StylesheetLoad (XslTransform t, string xsl)
238                 {
239                         XPathDocument doc = new XPathDocument (
240                                 new StringReader (xsl));
241                         WeakReference wr = new WeakReference (doc);
242                         t.Load (doc);
243                         return wr;
244                 }
245
246                 private WeakReference StylesheetTransform (XslTransform t, string xml)
247                 {
248                         XPathDocument doc = new XPathDocument (
249                                 new StringReader (xml));
250                         WeakReference wr = new WeakReference (doc);
251                         t.Transform (doc, null, TextWriter.Null, null);
252                         return wr;
253                 }
254         }
255 }