eeb4c49fabbb5ac6fa694d638bb01d65d9fbb7ba
[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 noExclude;
14                 static bool reportDetails;
15                 static bool reportAsXml;
16                 static bool useDomStyle;
17                 static bool useDomInstance;
18                 static bool generateOutput;
19                 static bool listOutput;
20                 static bool whitespaceStyle;
21                 static bool whitespaceInstance;
22                 static bool stopImmediately;
23                 static bool outputAll;
24                 static readonly ArrayList skipTargets;
25                 static string explicitTarget;
26                 static TextWriter reportOutput = Console.Out;
27                 static XmlTextWriter reportXmlWriter;
28
29                 static XsltTest ()
30                 {
31                         skipTargets = new ArrayList (new string [] {
32 "Keys__91836",
33 "Keys__91859",
34 "Keys_PerfRepro2",
35 "Keys_PerfRepro3",
36                         }); 
37                 }
38
39                 static void Usage ()
40                 {
41                         Console.WriteLine (@"
42 mono xslttest.exe [options] [targetFileMatch] -report:reportfile
43
44 Options:
45         --details       Output detailed output differences.
46         --dom           Use XmlDocument for both stylesheet and input source.
47         --domxsl        Use XmlDocument for stylesheet.
48         --domsrc        Use XmlDocument for input source.
49         --generate      Generate output files specified in catalog.
50                         Use this feature only when you want to update
51                         reference output.
52         --list          Print output list to console.
53         --noExclude     Don't exclude meaningless comparison testcases.
54         --outall        Output fine results as OK (omitted by default).
55         --stoponerror   Stops the test process and throw detailed
56                         error if happened.
57         --ws            Preserve spaces for both stylesheet and input source.
58         --wsxsl         Preserve spaces for stylesheet.
59         --wssrc         Preserve spaces for input source.
60         --xml           Report into xml output.
61         --report        Write reports into specified file.
62
63 FileMatch:
64         arbitrary string that specifies part of file name.
65         (no * or ? available)
66 ");
67                 }
68
69                 public static void Main (string [] args)
70                 {
71                         try {
72                                 RunMain (args);
73                         } catch (Exception ex) {
74                                 reportOutput.WriteLine (ex);
75                         } finally {
76                                 reportOutput.Close ();
77                         }
78                 }
79
80                 static void RunMain (string [] args)
81                 {
82                         foreach (string arg in args) {
83                                 switch (arg) {
84                                 case "-?":
85                                         Usage ();
86                                         return;
87                                 case "--dom":
88                                         useDomStyle = true;
89                                         useDomInstance = true;
90                                         break;
91                                 case "--domxsl":
92                                         useDomStyle = true;
93                                         break;
94                                 case "--domsrc":
95                                         useDomInstance = true;
96                                         break;
97                                 case "--details":
98                                         reportDetails = true;
99                                         break;
100                                 case "--generate":
101                                         generateOutput = true;
102                                         break;
103                                 case "--list":
104                                         listOutput = true;
105                                         break;
106                                 case "--noExclude":
107                                         noExclude = 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 (!noExclude) {
149                                 foreach (string s_ in new StreamReader ("ignore.lst").ReadToEnd ().Split ("\n".ToCharArray ())) {
150                                         string s = s_.Trim ();
151                                         if (s.Length > 0)
152                                                 skipTargets.Add (s);
153                                 }
154                         }
155
156                         if (reportAsXml) {
157                                 reportXmlWriter = new XmlTextWriter (reportOutput);
158                                 reportXmlWriter.Formatting = Formatting.Indented;
159                                 reportXmlWriter.WriteStartElement ("test-results");
160                         }
161
162                         if (explicitTarget != null)
163                                 Console.WriteLine ("The specified target is "
164                                         + explicitTarget);
165
166                         XmlDocument whole = new XmlDocument ();
167                         whole.Load (@"testsuite/TESTS/catalog.xml");
168
169                         if (!listOutput)
170                                 Console.WriteLine ("Started: " + DateTime.Now.ToString ("yyyyMMdd-HHmmss.fff"));
171
172                         foreach (XmlElement testCase in whole.SelectNodes (
173                                 "test-suite/test-catalog/test-case")) {
174                                 string stylesheetBase = null;
175                                 string testid = testCase.GetAttribute ("id");
176                                 if (skipTargets.Contains (testid))
177                                         continue;
178                                 try {
179                                         string filePath = testCase.SelectSingleNode ("file-path").InnerText;
180                                         // hack hack
181                                         string testAuthorDir =
182                                                 filePath [0] >= 'a' ?
183                                                 "Xalan_Conformance_Tests" :
184                                                 "MSFT_Conformance_Tests";
185                                         string path = @"testsuite/TESTS/" + testAuthorDir + "/" + filePath + "/";
186                                         foreach (XmlElement scenario in 
187                                                 testCase.SelectNodes ("scenario")) {
188                                                 RunTest (scenario, path, stylesheetBase);
189                                         }
190                                 } catch (Exception ex) {
191                                         if (stopImmediately)
192                                                 throw;
193                                         Report (testCase, "Exception: " + testCase.GetAttribute ("id") + ": " + ex.Message);
194                                 }
195                         }
196                         if (!listOutput)
197                                 Console.WriteLine ("Finished: " + DateTime.Now.ToString ("yyyyMMdd-HHmmss.fff"));
198
199                         if (reportAsXml)
200                                 reportXmlWriter.WriteEndElement (); // test-results
201                 }
202
203                 static void RunTest (XmlElement scenario, string path, string stylesheetBase)
204                 {
205                         stylesheetBase = scenario.SelectSingleNode ("input-file[@role='principal-stylesheet']").InnerText;
206                         string id = scenario.ParentNode.Attributes ["id"].Value;
207                         string stylesheet = path + stylesheetBase;
208                         string srcxml = path + scenario.SelectSingleNode ("input-file[@role='principal-data']").InnerText;
209                         XmlNode outputNode = scenario.SelectSingleNode ("output-file[@role='principal']");
210                         string outfile = outputNode != null ? path + outputNode.InnerText : null;
211
212                         if (listOutput) {
213                                 if (outfile != null)
214                                         Console.WriteLine (outfile);
215                                 return;
216                         }
217
218                         XslTransform trans = new XslTransform ();
219
220                         if (explicitTarget != null && id.IndexOf (explicitTarget) < 0)
221                                 return;
222                         if (skipTargets.Contains (stylesheetBase))
223                                 return;
224
225                         XmlTextReader stylextr = new XmlTextReader (stylesheet);
226                         XmlValidatingReader stylexvr = new XmlValidatingReader (stylextr);
227                         if (useDomStyle) {
228                                 XmlDocument styledoc = new XmlDocument ();
229                                 if (whitespaceStyle)
230                                         styledoc.PreserveWhitespace = true;
231                                 styledoc.Load (stylesheet);
232                                 trans.Load (styledoc);
233                         } else
234                                 trans.Load (new XPathDocument (
235                                         stylesheet,
236                                         whitespaceStyle ? XmlSpace.Preserve :
237                                         XmlSpace.Default));
238
239                         XmlTextReader xtr = new XmlTextReader (srcxml);
240                         XmlValidatingReader xvr = new XmlValidatingReader (xtr);
241                         xvr.ValidationType = ValidationType.None;
242                         IXPathNavigable input = null;
243                         if (useDomInstance) {
244                                 XmlDocument dom = new XmlDocument ();
245                                 if (whitespaceInstance)
246                                         dom.PreserveWhitespace = true;
247                                 dom.Load (xvr);
248                                 input = dom;
249                         } else {
250                                 input = new XPathDocument (xvr,
251                                         whitespaceStyle ? XmlSpace.Preserve :
252                                         XmlSpace.Default);
253                         }
254                         StringWriter sw = new StringWriter ();
255                         trans.Transform (input, null, sw);
256                         if (generateOutput) {
257                                 StreamWriter fw = new StreamWriter (outfile,
258                                         false, Encoding.UTF8);
259                                 fw.Write (sw.ToString ());
260                                 fw.Close ();
261                                 // ... and don't run comparison
262                                 return;
263                         }
264
265                         if (!File.Exists (outfile)) {
266                                 // Reference output file does not exist.
267                                 return;
268                         }
269                         StreamReader sr = new StreamReader (outfile);
270                         string reference_out = sr.ReadToEnd ();
271                         string actual_out = sw.ToString ();
272                         if (reference_out != actual_out)
273                                 Report (scenario.ParentNode as XmlElement, 
274                                         reference_out, actual_out);
275                         else if (outputAll)
276                                 Report (scenario.ParentNode as XmlElement,
277                                         "OK");
278                 }
279
280                 static void Report (XmlElement testcase, string message)
281                 {
282                         if (reportAsXml) {
283                                 reportXmlWriter.WriteStartElement ("testcase");
284                                 reportXmlWriter.WriteAttributeString ("id",
285                                         testcase.GetAttribute ("id"));
286                                 reportXmlWriter.WriteString (message);
287                                 reportXmlWriter.WriteEndElement ();
288                         }
289                         else
290                                 reportOutput.WriteLine (message);
291                 }
292
293                 static void Report (XmlElement testCase,
294                         string reference_out, string actual_out)
295                 {
296                         string baseMessage = reportAsXml ? "Different." :
297                                 "Different: " + testCase.GetAttribute ("id");
298                         if (!reportDetails)
299                                 Report (testCase, baseMessage);
300                         else
301                                 Report (testCase, baseMessage +
302                                         "\n Actual*****\n" + 
303                                         actual_out + 
304                                         "\n-------------------\nReference*****\n" + 
305                                         reference_out + 
306                                         "\n");
307                 }
308         }
309 }