Files
zszq-trs/UnitTestProject/Base/UnitTestBase.cs
2024-05-09 14:06:26 +08:00

164 lines
6.8 KiB
C#

using System.Collections;
using System.Collections.Specialized;
using System.Net.Http.Formatting;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
namespace YLErp
{
[TestClass]
public class UnitTestBase
{
protected OptUserInfo GetOptUser([CallerMemberName] string m_name = "")
{
if (string.IsNullOrEmpty(m_name) || m_name == ".ctor")
{
m_name = GetType().Name;
}
return new OptUserInfo(0, m_name, OptUserFrom.UnitTest, userGroup: null);
}
/// <summary>
/// 读取资源文件所有文本
/// </summary>
protected static string ReadResourceFile(string relativeFilePath)
{
var path = Path.Combine(AppContext.BaseDirectory, "Resources\\" + relativeFilePath);
return File.ReadAllText(path);
}
/// <summary>
/// 读取资源文件所有行
/// </summary>
protected static string[] ReadResourceFileLines(string relativeFilePath)
{
var path = Path.Combine(AppContext.BaseDirectory, "Resources\\" + relativeFilePath);
return File.ReadAllLines(path);
}
protected static T DeserializeFormData<T>(string resourceFileRelativePath) where T : new()
{
var list = new List<KeyValuePair<string, string>>();
var lines = ReadResourceFileLines(resourceFileRelativePath);
foreach (var line in lines)
{
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
var index = line.IndexOf(':');
if (index < 0)
{
continue;
}
list.Add(new KeyValuePair<string, string>(line.Substring(0, index).Trim(), line.Substring(index + 1).Trim()));
}
var fc = new FormDataCollection(list);
return MapForm<T>(fc.ReadAsNameValueCollection(), "");
}
protected class OtcOptionTradeFullFormData
{
public IEnumerable<OtcOptionTradeFull> trades { get; set; }
}
private static readonly Regex _regex = new(@"\[(?<value>.*?)\]", RegexOptions.Compiled | RegexOptions.Singleline);
private static T MapForm<T>(NameValueCollection nvc, string rootObjectName) where T : new()
{
var result = new T();
foreach (var kvp in nvc.AllKeys)
{
if (!kvp.StartsWith(rootObjectName))
{
throw new Exception("All keys should start with " + rootObjectName);
}
var match = _regex.Match(kvp.Remove(0, rootObjectName.Length));
if (match.Success)
{
// build path in a form of [Documents, 0, DocumentID]-like array
var path = new List<string>();
while (match.Success)
{
path.Add(match.Groups["value"].Value);
match = match.NextMatch();
}
// this is object we currently working on
object currentObject = result;
for (var i = 0; i < path.Count; i++)
{
var last = i == path.Count - 1;
var propName = path[i];
if (int.TryParse(propName, out var index))
{
// index access, like [0]
var list = currentObject as IList;
if (list == null)
{
throw new Exception("Invalid index access expression"); // more info here
}
// get the type of item in that list (i.e. Document)
var args = list.GetType().GetGenericArguments();
var listItemType = args[0];
if (last)
{
// may need more sophisticated conversion from string to target type
list[index] = Convert.ChangeType(nvc[kvp], Nullable.GetUnderlyingType(listItemType) ?? listItemType);
}
else
{
// if not initialized - initalize
var next = index < list.Count ? list[index] : null;
if (next == null)
{
// handle IList case in a special way here, since you cannot create instance of interface
next = Activator.CreateInstance(listItemType);
// fill with nulls if not enough items yet
while (index >= list.Count)
{
list.Add(null);
}
list[index] = next;
}
currentObject = next;
}
}
else
{
var prop = currentObject.GetType().GetProperty(propName, BindingFlags.Instance | BindingFlags.Public);
if (last)
{
// may need more sophisticated conversion from string to target type
prop.SetValue(currentObject, Convert.ChangeType(nvc[kvp], Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType));
}
else
{
// if not initialized - initalize
var next = prop.GetValue(currentObject);
if (next == null)
{
// TODO: handle IList case in a special way here, since you cannot create instance of interface
next = Activator.CreateInstance(prop.PropertyType);
prop.SetValue(currentObject, next);
}
currentObject = next;
}
}
}
}
}
return result;
}
}
}