155 lines
3.9 KiB
C#
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 ());
|
|
}
|
|
}
|
|
}
|
|
} |