[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunitlite / OutputWriters / NUnit2XmlOutputWriter.cs
1 // ***********************************************************************
2 // Copyright (c) 2011 Charlie Poole
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 using System;
30 using System.Collections;
31 using System.Collections.Generic;
32 using System.Globalization;
33 using System.Reflection;
34 using System.Xml;
35 using System.IO;
36 using NUnit.Common;
37 using NUnit.Framework.Interfaces;
38 using NUnit.Framework.Internal;
39
40 namespace NUnitLite
41 {
42     /// <summary>
43     /// NUnit2XmlOutputWriter is able to create an xml file representing
44     /// the result of a test run in NUnit 2.x format.
45     /// </summary>
46     public class NUnit2XmlOutputWriter : OutputWriter
47     {
48         private XmlWriter xmlWriter;
49
50         /// <summary>
51         /// Write info about a test
52         /// </summary>
53         /// <param name="test">The test</param>
54         /// <param name="writer">A TextWriter</param>
55         public override void WriteTestFile(ITest test, TextWriter writer)
56         {
57             throw new NotImplementedException("Explore test output is not supported by the NUnit2 format.");
58         }
59
60         /// <summary>
61         /// Writes the result of a test run to a specified TextWriter.
62         /// </summary>
63         /// <param name="result">The test result for the run</param>
64         /// <param name="writer">The TextWriter to which the xml will be written</param>
65         /// <param name="runSettings"></param>
66         /// <param name="filter"></param>
67         public override void WriteResultFile(ITestResult result, TextWriter writer, IDictionary<string, object> runSettings, TestFilter filter)
68         {
69             // NOTE: Under .NET 1.1, XmlTextWriter does not implement IDisposable,
70             // but does implement Close(). Hence we cannot use a 'using' clause.
71             //using (XmlTextWriter xmlWriter = new XmlTextWriter(writer))
72 #if SILVERLIGHT
73             XmlWriter xmlWriter = XmlWriter.Create(writer);
74 #else
75             //XmlW xmlWriter = new XmlTextWriter(writer);
76             //xmlWriter.Formatting = Formatting.Indented;
77             XmlWriter xmlWriter = XmlWriter.Create(writer);
78 #endif
79
80             try
81             {
82                 WriteXmlOutput(result, xmlWriter);
83             }
84             finally
85             {
86                 //writer.Close();
87             }
88         }
89
90         private void WriteXmlOutput(ITestResult result, XmlWriter xmlWriter)
91         {
92             this.xmlWriter = xmlWriter;
93
94             InitializeXmlFile(result);
95             WriteResultElement(result);
96             TerminateXmlFile();
97         }
98
99         private void InitializeXmlFile(ITestResult result)
100         {
101             ResultSummary summary = new ResultSummary(result);
102
103             xmlWriter.WriteStartDocument(false);
104             xmlWriter.WriteComment("This file represents the results of running a test suite");
105
106             xmlWriter.WriteStartElement("test-results");
107
108             xmlWriter.WriteAttributeString("name", result.FullName);
109             xmlWriter.WriteAttributeString("total", summary.TestCount.ToString());
110             xmlWriter.WriteAttributeString("errors", summary.ErrorCount.ToString());
111             xmlWriter.WriteAttributeString("failures", summary.FailureCount.ToString());
112             var notRunTotal = summary.SkipCount + summary.FailureCount + summary.InvalidCount;
113             xmlWriter.WriteAttributeString("not-run", notRunTotal.ToString());
114             xmlWriter.WriteAttributeString("inconclusive", summary.InconclusiveCount.ToString());
115             xmlWriter.WriteAttributeString("ignored", summary.IgnoreCount.ToString());
116             xmlWriter.WriteAttributeString("skipped", summary.SkipCount.ToString());
117             xmlWriter.WriteAttributeString("invalid", summary.InvalidCount.ToString());
118
119             xmlWriter.WriteAttributeString("date", result.StartTime.ToString("yyyy-MM-dd"));
120             xmlWriter.WriteAttributeString("time", result.StartTime.ToString("HH:mm:ss"));
121             WriteEnvironment();
122             WriteCultureInfo();
123         }
124
125         private void WriteCultureInfo()
126         {
127             xmlWriter.WriteStartElement("culture-info");
128             xmlWriter.WriteAttributeString("current-culture",
129                                            CultureInfo.CurrentCulture.ToString());
130             xmlWriter.WriteAttributeString("current-uiculture",
131                                            CultureInfo.CurrentUICulture.ToString());
132             xmlWriter.WriteEndElement();
133         }
134
135         private void WriteEnvironment()
136         {
137 //            xmlWriter.WriteStartElement("environment");
138 //            var assemblyName = AssemblyHelper.GetAssemblyName(Assembly.GetExecutingAssembly());
139 //            xmlWriter.WriteAttributeString("nunit-version",
140 //                                           assemblyName.Version.ToString());
141 //            xmlWriter.WriteAttributeString("clr-version",
142 //                                           Environment.Version.ToString());
143 //            xmlWriter.WriteAttributeString("os-version",
144 //                                           Environment.OSVersion.ToString());
145 //            xmlWriter.WriteAttributeString("platform",
146 //                Environment.OSVersion.Platform.ToString());
147 //#if !NETCF
148 //            xmlWriter.WriteAttributeString("cwd",
149 //                                           Environment.CurrentDirectory);
150 //#if !SILVERLIGHT
151 //            xmlWriter.WriteAttributeString("machine-name",
152 //                                           Environment.MachineName);
153 //            xmlWriter.WriteAttributeString("user",
154 //                                           Environment.UserName);
155 //            xmlWriter.WriteAttributeString("user-domain",
156 //                                           Environment.UserDomainName);
157 //#endif
158 //#endif
159 //            xmlWriter.WriteEndElement();
160         }
161
162         private void WriteResultElement(ITestResult result)
163         {
164             StartTestElement(result);
165
166             WriteCategories(result);
167             WriteProperties(result);
168
169             switch (result.ResultState.Status)
170             {
171                 case TestStatus.Skipped:
172                     if (result.Message != null)
173                         WriteReasonElement(result.Message);
174                     break;
175                 case TestStatus.Failed:
176                     WriteFailureElement(result.Message, result.StackTrace);
177                     break;
178             }
179             
180             if (result.Test is TestSuite)
181                 WriteChildResults(result);
182
183             xmlWriter.WriteEndElement(); // test element
184         }
185
186         private void TerminateXmlFile()
187         {
188             xmlWriter.WriteEndElement(); // test-results
189             xmlWriter.WriteEndDocument();
190             xmlWriter.Flush();
191             //xmlWriter.Close();
192         }
193
194
195         #region Element Creation Helpers
196
197         private void StartTestElement(ITestResult result)
198         {
199             ITest test = result.Test;
200             TestSuite suite = test as TestSuite;
201
202             if (suite != null)
203             {
204                 xmlWriter.WriteStartElement("test-suite");
205                 xmlWriter.WriteAttributeString("type", suite.TestType == "ParameterizedMethod" ? "ParameterizedTest" : suite.TestType);
206                 xmlWriter.WriteAttributeString("name", suite.TestType == "Assembly" || suite.TestType == "Project"
207                     ? result.Test.FullName
208                     : result.Test.Name);
209             }
210             else
211             {
212                 xmlWriter.WriteStartElement("test-case");
213                 xmlWriter.WriteAttributeString("name", result.Name);
214             }
215
216             if (test.Properties.ContainsKey(PropertyNames.Description))
217             {
218                 string description = (string)test.Properties.Get(PropertyNames.Description);
219                 xmlWriter.WriteAttributeString("description", description);
220             }
221
222             TestStatus status = result.ResultState.Status;
223             string translatedResult = TranslateResult(result.ResultState);
224
225             if (status != TestStatus.Skipped)
226             {
227                 xmlWriter.WriteAttributeString("executed", "True");
228                 xmlWriter.WriteAttributeString("result", translatedResult);
229                 xmlWriter.WriteAttributeString("success", status == TestStatus.Passed ? "True" : "False");
230                 xmlWriter.WriteAttributeString("time", result.Duration.ToString("0.000", NumberFormatInfo.InvariantInfo));
231                 xmlWriter.WriteAttributeString("asserts", result.AssertCount.ToString());
232             }
233             else
234             {
235                 xmlWriter.WriteAttributeString("executed", "False");
236                 xmlWriter.WriteAttributeString("result", translatedResult);
237             }
238         }
239
240         private string TranslateResult(ResultState resultState)
241         {
242             switch (resultState.Status)
243             {
244                 default:
245                 case TestStatus.Passed:
246                     return "Success";
247                 case TestStatus.Inconclusive:
248                     return "Inconclusive";
249                 case TestStatus.Failed:
250                     switch (resultState.Label)
251                     {
252                         case "Error":
253                         case "Cancelled":
254                             return resultState.Label;
255                         default:
256                             return "Failure";
257                     }
258                 case TestStatus.Skipped:
259                     switch (resultState.Label)
260                     {
261                         case "Ignored":
262                             return "Ignored";
263                         case "Invalid":
264                             return "NotRunnable";
265                         default:
266                             return "Skipped";
267                     }
268             }
269         }
270
271         private void WriteCategories(ITestResult result)
272         {
273             IPropertyBag properties = result.Test.Properties;
274
275             if (properties.ContainsKey(PropertyNames.Category))
276             {
277                 xmlWriter.WriteStartElement("categories");
278
279                 foreach (string category in properties[PropertyNames.Category])
280                 {
281                     xmlWriter.WriteStartElement("category");
282                     xmlWriter.WriteAttributeString("name", category);
283                     xmlWriter.WriteEndElement();
284                 }
285
286                 xmlWriter.WriteEndElement();
287             }
288         }
289
290         private void WriteProperties(ITestResult result)
291         {
292             IPropertyBag properties = result.Test.Properties;
293             int nprops = 0;
294
295             foreach (string key in properties.Keys)
296             {
297                 if (key != PropertyNames.Category)
298                 {
299                     if (nprops++ == 0)
300                         xmlWriter.WriteStartElement("properties");
301
302                     foreach (object prop in properties[key])
303                     {
304                         xmlWriter.WriteStartElement("property");
305                         xmlWriter.WriteAttributeString("name", key);
306                         xmlWriter.WriteAttributeString("value", prop.ToString());
307                         xmlWriter.WriteEndElement();
308                     }
309                 }
310             }
311
312             if (nprops > 0)
313                 xmlWriter.WriteEndElement();
314         }
315
316         private void WriteReasonElement(string message)
317         {
318             xmlWriter.WriteStartElement("reason");
319             xmlWriter.WriteStartElement("message");
320             WriteCData(message);
321             xmlWriter.WriteEndElement();
322             xmlWriter.WriteEndElement();
323         }
324
325         private void WriteFailureElement(string message, string stackTrace)
326         {
327             xmlWriter.WriteStartElement("failure");
328             xmlWriter.WriteStartElement("message");
329             WriteCData(message);
330             xmlWriter.WriteEndElement();
331             xmlWriter.WriteStartElement("stack-trace");
332             if (stackTrace != null)
333                 WriteCData(stackTrace);
334             xmlWriter.WriteEndElement();
335             xmlWriter.WriteEndElement();
336         }
337
338         private void WriteChildResults(ITestResult result)
339         {
340             xmlWriter.WriteStartElement("results");
341
342             foreach (ITestResult childResult in result.Children)
343                 WriteResultElement(childResult);
344
345             xmlWriter.WriteEndElement();
346         }
347
348         #endregion
349
350         #region Output Helpers
351         ///// <summary>
352         ///// Makes string safe for xml parsing, replacing control chars with '?'
353         ///// </summary>
354         ///// <param name="encodedString">string to make safe</param>
355         ///// <returns>xml safe string</returns>
356         //private static string CharacterSafeString(string encodedString)
357         //{
358         //    /*The default code page for the system will be used.
359         //    Since all code pages use the same lower 128 bytes, this should be sufficient
360         //    for finding unprintable control characters that make the xslt processor error.
361         //    We use characters encoded by the default code page to avoid mistaking bytes as
362         //    individual characters on non-latin code pages.*/
363         //    char[] encodedChars = System.Text.Encoding.Default.GetChars(System.Text.Encoding.Default.GetBytes(encodedString));
364
365         //    System.Collections.ArrayList pos = new System.Collections.ArrayList();
366         //    for (int x = 0; x < encodedChars.Length; x++)
367         //    {
368         //        char currentChar = encodedChars[x];
369         //        //unprintable characters are below 0x20 in Unicode tables
370         //        //some control characters are acceptable. (carriage return 0x0D, line feed 0x0A, horizontal tab 0x09)
371         //        if (currentChar < 32 && (currentChar != 9 && currentChar != 10 && currentChar != 13))
372         //        {
373         //            //save the array index for later replacement.
374         //            pos.Add(x);
375         //        }
376         //    }
377         //    foreach (int index in pos)
378         //    {
379         //        encodedChars[index] = '?';//replace unprintable control characters with ?(3F)
380         //    }
381         //    return System.Text.Encoding.Default.GetString(System.Text.Encoding.Default.GetBytes(encodedChars));
382         //}
383
384         private void WriteCData(string text)
385         {
386             int start = 0;
387             while (true)
388             {
389                 int illegal = text.IndexOf("]]>", start);
390                 if (illegal < 0)
391                     break;
392                 xmlWriter.WriteCData(text.Substring(start, illegal - start + 2));
393                 start = illegal + 2;
394                 if (start >= text.Length)
395                     return;
396             }
397
398             if (start > 0)
399                 xmlWriter.WriteCData(text.Substring(start));
400             else
401                 xmlWriter.WriteCData(text);
402         }
403
404         #endregion
405     }
406 }