Merge pull request #1304 from slluis/mac-proxy-autoconfig
[mono.git] / mcs / class / System / Test / System / StringTester.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Globalization;
5 using System.IO;
6 using System.Reflection;
7 using System.Text;
8 using System.Text.RegularExpressions;
9 using NUnit.Framework;
10
11 namespace MonoTests.System {
12         public class StringTester {
13                 private const string ext = ".txt";
14                 public static string Location = "./StringTests/";
15                 public static bool CreateMode = false;
16
17                 private static readonly Dictionary<string, Asserts> asserts = new Dictionary<string, Asserts> ();
18
19                 public static void Assert (string id, string actual, string message = "")
20                 {
21                         string testFullName = GetTestMethodName ();
22
23                         Asserts testAsserts;
24                         if (!asserts.TryGetValue (testFullName, out testAsserts)) {
25                                 testAsserts = new Asserts ();
26
27                                 if (!CreateMode) {
28                                         string filePath = Path.GetFullPath (Path.Combine (Location, testFullName + ext));
29                                         if (!File.Exists (filePath)) {
30                                                 NUnit.Framework.Assert.Ignore (filePath + " does not exist. \n" +
31                                                                                                            "The file should be generated by running on .NET the same test with StringTester.CreateMode = true.");
32                                         }
33
34                                         testAsserts.Load (filePath);
35                                 }
36
37                                 asserts.Add (testFullName, testAsserts);
38                         }
39
40                         if (CreateMode) {
41                                 testAsserts.AddExpected (id, actual);
42                                 return;
43                         }
44
45                         if (string.IsNullOrEmpty(message))
46                                 message = id;
47
48                         string expected = testAsserts.GetExpected (id);
49                         NUnit.Framework.Assert.AreEqual (expected, actual, message);
50                 }
51
52                 public static void Save ()
53                 {
54                         if (!CreateMode)
55                                 return;
56
57                         foreach (var test in asserts)
58                                 test.Value.Save (Path.Combine (Location, test.Key + ext));
59                 }
60
61                 public static string GetTestMethodName ()
62                 {
63                         var stackTrace = new StackTrace ();
64                         foreach (StackFrame stackFrame in stackTrace.GetFrames ()) {
65                                 MethodBase methodBase = stackFrame.GetMethod ();
66                                 Object [] attributes = methodBase.GetCustomAttributes (typeof (TestAttribute), false);
67                                 if (attributes.Length >= 1)
68                                         return methodBase.DeclaringType.FullName + "." + methodBase.Name;
69                         }
70                         return "Not called from a test method";
71                 }
72
73                 public class Asserts {
74                         private const string escapes = "\n\t\0\r\\";
75                         private const string unescapes = @"\n\t\0\r\\";
76                         private static readonly Regex regex = new Regex (@"\\u(?<Value>[a-zA-Z0-9]{4})", RegexOptions.Compiled);
77                         private readonly Dictionary<string, string> values = new Dictionary<string, string> ();
78
79                         public void AddExpected (string id, string value)
80                         {
81                                 values.Add (id, value);
82                         }
83
84                         public string GetExpected (string id)
85                         {
86                                 return values [id];
87                         }
88
89                         public void Save (string filePath)
90                         {
91                                 string dir = Path.GetDirectoryName (filePath);
92                                 if (!Directory.Exists (dir))
93                                         Directory.CreateDirectory (dir);
94
95                                 var sw = new StreamWriter (filePath, false, Encoding.UTF8);
96
97                                 foreach (var kv in values) {
98                                         sw.WriteLine (Escape (kv.Key));
99                                         sw.WriteLine (Escape (kv.Value));
100                                 }
101
102                                 sw.Close ();
103                         }
104
105                         public void Load (string filePath)
106                         {
107                                 if (!File.Exists (filePath))
108                                         return;
109
110                                 var sr = new StreamReader (filePath, Encoding.UTF8);
111
112                                 while (sr.Peek () > 0) {
113                                         string id = Unescape (sr.ReadLine ());
114
115                                         if (sr.Peek () == 0)
116                                                 break;
117
118                                         string value = Unescape (sr.ReadLine ());
119                                         values.Add (id, value);
120                                 }
121
122                                 sr.Close ();
123                         }
124
125                         private static string Escape (string str)
126                         {
127                                 var sb = new StringBuilder ();
128                                 foreach (char c in str) {
129                                         int i = escapes.IndexOf (c);
130                                         if (i != -1) {
131                                                 sb.Append (unescapes.Substring (i*2, 2));
132                                                 continue;
133                                         }
134
135                                         if (c >= 0x7f || c < 0x20) {
136                                                 sb.Append (string.Format (@"\u{0:x4}", (int) c));
137                                                 continue;
138                                         }
139
140                                         sb.Append (c);
141                                 }
142                                 return sb.ToString ();
143                         }
144
145                         private static string Unescape (string str)
146                         {
147                                 for (int i = 0; i < escapes.Length; i++)
148                                         str = str.Replace (unescapes.Substring (i*2, 2), "" + escapes [i]);
149
150                                 return regex.Replace (str,
151                                         m => ((char) int.Parse (m.Groups ["Value"].Value, NumberStyles.HexNumber)).ToString ());
152                         }
153                 }
154         }
155 }