2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System.XML / Test / System.Xml.Xsl / standalone_tests / xslttest.cs
1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Text;
5 using System.Xml;
6 using System.Xml.XPath;
7 using System.Xml.Xsl;
8
9 namespace XsltTest
10 {
11         public class XsltTest
12         {
13                 static bool reportDetails;
14                 static bool reportAsXml;
15                 static bool useDomStyle;
16                 static bool useDomInstance;
17                 static bool generateOutput;
18                 static bool whitespaceStyle;
19                 static bool whitespaceInstance;
20                 static bool stopImmediately;
21                 static bool outputAll;
22                 static readonly ArrayList skipTargets;
23                 static string explicitTarget;
24                 static TextWriter reportOutput = Console.Out;
25                 static XmlTextWriter reportXmlWriter;
26
27                 static XsltTest ()
28                 {
29                         skipTargets = new ArrayList (new string [] {
30 "attribset15.xsl",
31 "lre12.xsl", 
32 "namespace23.xsl", // under .NET, XPathDocument behavior is different from dom
33 "namespace40.xsl", 
34 "namespace42.xsl", 
35 "namespace43.xsl",
36 "namespace48.xsl", 
37 "namespace60.xsl", 
38 "namespace73.xsl", 
39 "namespace106.xsl",
40 // output22,77: not-supported encoding, but MS passes...?
41 // output72.xsl: should not pass
42 "output22.xsl", 
43 "output72.xsl",
44 "output77.xsl"
45                         }); 
46                 }
47
48                 static void Usage ()
49                 {
50                         Console.WriteLine (@"mono xslttest.exe [options] [targetFileMatch] -report:reportfile
51
52         Options:
53                 --details : Output detailed output differences.
54                 --dom : use XmlDocument for both stylesheet and input source.
55                 --domxsl : use XmlDocument for stylesheet.
56                 --domsrc : use XmlDocument for input source.
57                 --generate : generate output files specified in catalog.
58                                 Use this feature only when you want to update
59                                 reference output.
60                 --outall : Output fine results as OK (omitted by default).
61                 --stoponerror : stops the test process and throw detailed
62                         error if happened.
63                 --ws : preserve spaces for both stylesheet and input source.
64                 --wsxsl : preserve spaces for stylesheet.
65                 --wssrc : preserve spaces for input source.
66                 --xml : report into xml output.
67                 --report : write reports into specified file.
68
69         FileMatch:
70                 arbitrary string that specifies part of file name.
71                 (no * or ? available)
72 ");
73                 }
74
75                 public static void Main (string [] args)
76                 {
77                         try {
78                                 RunMain (args);
79                         } catch (Exception ex) {
80                                 reportOutput.WriteLine (ex);
81                         } finally {
82                                 reportOutput.Close ();
83                         }
84                 }
85
86                 static void RunMain (string [] args)
87                 {
88                         foreach (string arg in args) {
89                                 switch (arg) {
90                                 case "-?":
91                                         Usage ();
92                                         return;
93                                 case "--dom":
94                                         useDomStyle = true;
95                                         useDomInstance = true;
96                                         break;
97                                 case "--domxsl":
98                                         useDomStyle = true;
99                                         break;
100                                 case "--domsrc":
101                                         useDomInstance = true;
102                                         break;
103                                 case "--details":
104                                         reportDetails = true;
105                                         break;
106                                 case "--generate":
107                                         generateOutput = true;
108                                         break;
109                                 case "--outall":
110                                         outputAll = true;
111                                         break;
112                                 case "--stoponerror":
113                                         stopImmediately = true;
114                                         break;
115                                 case "--ws":
116                                         whitespaceStyle = true;
117                                         whitespaceInstance = true;
118                                         break;
119                                 case "--wsxsl":
120                                         whitespaceStyle = true;
121                                         break;
122                                 case "--wssrc":
123                                         whitespaceInstance = true;
124                                         break;
125                                 case "--xml":
126                                         reportAsXml = true;
127                                         break;
128                                 default:
129                                         if (arg.StartsWith ("--report:")) {
130                                                 string reportFile = arg.Substring (9);
131                                                 if (reportFile.Length < 0) {
132                                                         Usage ();
133                                                         Console.WriteLine ("Error: --report option requires filename.");
134                                                         return;
135                                                 }
136                                                 reportOutput = new StreamWriter (reportFile);
137                                                 break;
138                                         }
139                                         if (arg.StartsWith ("--")) {
140                                                 Usage ();
141                                                 return;
142                                         }
143                                         explicitTarget = arg;
144                                         break;
145                                 }
146                         }
147
148                         if (reportAsXml) {
149                                 reportXmlWriter = new XmlTextWriter (reportOutput);
150                                 reportXmlWriter.Formatting = Formatting.Indented;
151                                 reportXmlWriter.WriteStartElement ("test-results");
152                         }
153
154                         if (explicitTarget != null)
155                                 Console.WriteLine ("The specified target is "
156                                         + explicitTarget);
157
158                         XmlDocument whole = new XmlDocument ();
159                         whole.Load (@"testsuite/TESTS/Xalan_Conformance_Tests/catalog.xml");
160
161                         Console.WriteLine ("Started: " + 
162                                 DateTime.Now.ToString ("yyyyMMdd-HHmmss.fff"));
163
164                         foreach (XmlElement testCase in whole.SelectNodes (
165                                 "test-suite/test-catalog/test-case")) {
166                                 string stylesheetBase = null;
167                                 try {
168                                         string filePath = testCase.SelectSingleNode ("file-path").InnerText;
169                                         string path = @"testsuite/TESTS/Xalan_Conformance_Tests/" + filePath + "/";
170                                         foreach (XmlElement scenario in 
171                                                 testCase.SelectNodes ("scenario")) {
172                                                 RunTest (scenario, path, stylesheetBase);
173                                         }
174                                 } catch (Exception ex) {
175                                         if (skipTargets.Contains (stylesheetBase))
176                                                 continue;
177                                         if (stopImmediately)
178                                                 throw;
179                                         Report (testCase, "Exception: " + testCase.GetAttribute ("id") + ": " + ex.Message);
180                                 }
181                         }
182 Console.WriteLine ("Finished: " + DateTime.Now.ToString ("yyyyMMdd-HHmmss.fff"));
183
184                         if (reportAsXml)
185                                 reportXmlWriter.WriteEndElement (); // test-results
186                 }
187
188                 static void RunTest (XmlElement scenario, string path, string stylesheetBase)
189                 {
190                         XslTransform trans = new XslTransform ();
191                         stylesheetBase = scenario.SelectSingleNode ("input-file[@role='principal-stylesheet']").InnerText;
192                         string stylesheet = path + stylesheetBase;
193                         string srcxml = path + scenario.SelectSingleNode ("input-file[@role='principal-data']").InnerText;
194
195                         if (explicitTarget != null && stylesheetBase.IndexOf (explicitTarget) < 0)
196                                 return;
197                         if (skipTargets.Contains (stylesheetBase))
198                                 return;
199
200                         XmlTextReader stylextr = new XmlTextReader (stylesheet);
201                         XmlValidatingReader stylexvr = new XmlValidatingReader (stylextr);
202                         if (useDomStyle) {
203                                 XmlDocument styledoc = new XmlDocument ();
204                                 if (whitespaceStyle)
205                                         styledoc.PreserveWhitespace = true;
206                                 styledoc.Load (stylesheet);
207                                 trans.Load (styledoc);
208                         } else
209                                 trans.Load (new XPathDocument (
210                                         stylesheet,
211                                         whitespaceStyle ? XmlSpace.Preserve :
212                                         XmlSpace.Default));
213
214                         string outfile = path + scenario.SelectSingleNode ("output-file[@role='principal']").InnerText;
215
216                         XmlTextReader xtr = new XmlTextReader (srcxml);
217                         XmlValidatingReader xvr = new XmlValidatingReader (xtr);
218                         xvr.ValidationType = ValidationType.None;
219                         IXPathNavigable input = null;
220                         if (useDomInstance) {
221                                 XmlDocument dom = new XmlDocument ();
222                                 if (whitespaceInstance)
223                                         dom.PreserveWhitespace = true;
224                                 dom.Load (xvr);
225                                 input = dom;
226                         } else {
227                                 input = new XPathDocument (xvr,
228                                         whitespaceStyle ? XmlSpace.Preserve :
229                                         XmlSpace.Default);
230                         }
231                         StringWriter sw = new StringWriter ();
232                         trans.Transform (input, null, sw);
233                         if (generateOutput) {
234                                 StreamWriter fw = new StreamWriter (outfile,
235                                         false, Encoding.UTF8);
236                                 fw.Write (sw.ToString ());
237                                 fw.Close ();
238                                 // ... and don't run comparison
239                                 return;
240                         }
241
242                         if (!File.Exists (outfile)) {
243                                 // Reference output file does not exist.
244                                 return;
245                         }
246                         StreamReader sr = new StreamReader (outfile);
247                         string reference_out = sr.ReadToEnd ();
248                         string actual_out = sw.ToString ();
249                         if (reference_out != actual_out)
250                                 Report (scenario.ParentNode as XmlElement, 
251                                         reference_out, actual_out);
252                         else if (outputAll)
253                                 Report (scenario.ParentNode as XmlElement,
254                                         "OK");
255                 }
256
257                 static void Report (XmlElement testcase, string message)
258                 {
259                         if (reportAsXml) {
260                                 reportXmlWriter.WriteStartElement ("testcase");
261                                 reportXmlWriter.WriteAttributeString ("id",
262                                         testcase.GetAttribute ("id"));
263                                 reportXmlWriter.WriteString (message);
264                                 reportXmlWriter.WriteEndElement ();
265                         }
266                         else
267                                 reportOutput.WriteLine (message);
268                 }
269
270                 static void Report (XmlElement testCase,
271                         string reference_out, string actual_out)
272                 {
273                         string baseMessage = reportAsXml ? "Different." :
274                                 "Different: " + testCase.GetAttribute ("id");
275                         if (!reportDetails)
276                                 Report (testCase, baseMessage);
277                         else
278                                 Report (testCase, baseMessage +
279                                         "\n Actual*****\n" + 
280                                         actual_out + 
281                                         "\n-------------------\nReference*****\n" + 
282                                         reference_out + 
283                                         "\n");
284                 }
285         }
286 }