Jo Shields 8b9b85e7f5 Imported Upstream version 3.10.0
Former-commit-id: 172c8e3c300b39d5785c7a3e8dfb08ebdbc1a99b
2014-10-04 11:27:48 +01:00

155 lines
3.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using NUnit.Framework;
namespace MonoTests.System {
public class StringTester {
private const string ext = ".txt";
public static string Location = "./StringTests/";
public static bool CreateMode = false;
private static readonly Dictionary<string, Asserts> asserts = new Dictionary<string, Asserts> ();
public static void Assert (string id, string actual, string message = "")
{
string testFullName = GetTestMethodName ();
Asserts testAsserts;
if (!asserts.TryGetValue (testFullName, out testAsserts)) {
testAsserts = new Asserts ();
if (!CreateMode) {
string filePath = Path.GetFullPath (Path.Combine (Location, testFullName + ext));
if (!File.Exists (filePath)) {
NUnit.Framework.Assert.Ignore (filePath + " does not exist. \n" +
"The file should be generated by running on .NET the same test with StringTester.CreateMode = true.");
}
testAsserts.Load (filePath);
}
asserts.Add (testFullName, testAsserts);
}
if (CreateMode) {
testAsserts.AddExpected (id, actual);
return;
}
if (string.IsNullOrEmpty(message))
message = id;
string expected = testAsserts.GetExpected (id);
NUnit.Framework.Assert.AreEqual (expected, actual, message);
}
public static void Save ()
{
if (!CreateMode)
return;
foreach (var test in asserts)
test.Value.Save (Path.Combine (Location, test.Key + ext));
}
public static string GetTestMethodName ()
{
var stackTrace = new StackTrace ();
foreach (StackFrame stackFrame in stackTrace.GetFrames ()) {
MethodBase methodBase = stackFrame.GetMethod ();
Object [] attributes = methodBase.GetCustomAttributes (typeof (TestAttribute), false);
if (attributes.Length >= 1)
return methodBase.DeclaringType.FullName + "." + methodBase.Name;
}
return "Not called from a test method";
}
public class Asserts {
private const string escapes = "\n\t\0\r\\";
private const string unescapes = @"\n\t\0\r\\";
private static readonly Regex regex = new Regex (@"\\u(?<Value>[a-zA-Z0-9]{4})", RegexOptions.Compiled);
private readonly Dictionary<string, string> values = new Dictionary<string, string> ();
public void AddExpected (string id, string value)
{
values.Add (id, value);
}
public string GetExpected (string id)
{
return values [id];
}
public void Save (string filePath)
{
string dir = Path.GetDirectoryName (filePath);
if (!Directory.Exists (dir))
Directory.CreateDirectory (dir);
var sw = new StreamWriter (filePath, false, Encoding.UTF8);
foreach (var kv in values) {
sw.WriteLine (Escape (kv.Key));
sw.WriteLine (Escape (kv.Value));
}
sw.Close ();
}
public void Load (string filePath)
{
if (!File.Exists (filePath))
return;
var sr = new StreamReader (filePath, Encoding.UTF8);
while (sr.Peek () > 0) {
string id = Unescape (sr.ReadLine ());
if (sr.Peek () == 0)
break;
string value = Unescape (sr.ReadLine ());
values.Add (id, value);
}
sr.Close ();
}
private static string Escape (string str)
{
var sb = new StringBuilder ();
foreach (char c in str) {
int i = escapes.IndexOf (c);
if (i != -1) {
sb.Append (unescapes.Substring (i*2, 2));
continue;
}
if (c >= 0x7f || c < 0x20) {
sb.Append (string.Format (@"\u{0:x4}", (int) c));
continue;
}
sb.Append (c);
}
return sb.ToString ();
}
private static string Unescape (string str)
{
for (int i = 0; i < escapes.Length; i++)
str = str.Replace (unescapes.Substring (i*2, 2), "" + escapes [i]);
return regex.Replace (str,
m => ((char) int.Parse (m.Groups ["Value"].Value, NumberStyles.HexNumber)).ToString ());
}
}
}
}