using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Matlock.TestHelpers.Utils
{
using System;
using System.Reflection;
using System.Text;
public static class RandomHelper
{
/* This method can be used to fill all public properties of an object with random values depending on their type. CAUTION: it does not fill attributes that end with 'ID' or attributes which are called 'pk'. They have to be filled manually.*/
private static readonly Random randomSeed = new Random(); /* Generates a random string with the given length*/
public static T FillPropertiesWithRandomValues<T>(T obj)
{
Type type = obj.GetType();
PropertyInfo[] infos =
type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (PropertyInfo info in infos)
{
Type infoType = info.PropertyType;
Type nullableType = null;
if (infoType.IsGenericType && infoType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
nullableType = ExtractTypeFromNullable(infoType);
}
if (info.CanWrite)
{
if (infoType.Equals(typeof(DateTime)) || infoType.Equals(typeof(DateTime?)))
{
info.SetValue(obj, RandomDateTime(DateTime.Now, new DateTime(3000, 01, 01)), null);
}
else if (infoType.Equals(typeof(string)))
{
info.SetValue(obj, info.Name + "_" + RandomString(20, false), null);
}
else if ((infoType.Equals(typeof(long)) || infoType.Equals(typeof(double)) ||
infoType.Equals(typeof(int)) || infoType.Equals(typeof(long)) ||
infoType.Equals(typeof(int))) && !info.Name.ToLower().EndsWith("id") &&
!info.Name.ToLower().Equals("pk"))
{
info.SetValue(obj, RandomNumber(0, 999999), null);
}
else if ((infoType.Equals(typeof(long?)) || infoType.Equals(typeof(double?)) ||
infoType.Equals(typeof(int?)) || infoType.Equals(typeof(long?)) ||
infoType.Equals(typeof(int?))) && !info.Name.ToLower().EndsWith("id") &&
!info.Name.ToLower().Equals("pk"))
{
Type genericType = info.PropertyType.GetGenericArguments()[0];
info.SetValue(obj, Convert.ChangeType(RandomNumber(0, 999999), genericType), null);
}
else if (infoType.Equals(typeof(bool)))
{
info.SetValue(obj, RandomBool(), null);
}
else if (infoType.Equals(typeof(System.Guid)))
{
info.SetValue(obj, Guid.NewGuid(), null);
}
else if (infoType.Equals(typeof(System.Enum)))
{
var values = Enum.GetValues(infoType);
var list = new List<Object>();
foreach (var array in values)
{
list.Add(array);
}
var val = list[new Random().Next(0, list.Count)];
info.SetValue(obj, val, null);
}
else if (((infoType.BaseType != null) && (infoType.BaseType.Equals(typeof(System.Enum)))))
{
var values = Enum.GetValues(infoType);
var list = new List<Object>();
foreach (var array in values)
{
list.Add(array);
}
var val = list[new Random().Next(0, list.Count)];
info.SetValue(obj, val, null);
}
else if (nullableType != null)
{
if (nullableType.BaseType.Equals(typeof(System.Enum)))
{
var values = Enum.GetValues(nullableType);
var list = new List<Object>();
foreach (var array in values)
{
list.Add(array);
}
var val = list[new Random().Next(0, list.Count)];
info.SetValue(obj, val, null);
}
}
else if (infoType.IsInterface)
{
// TODO get implementing interfaces from all assemblies and choose random?
}
}
}
return obj;
}
///<summary>Indentify and extracting type from Nullable Type</summary>
public static Type ExtractTypeFromNullable(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var valueProp = type.GetProperty("Value");
return valueProp.PropertyType;
}
else
{
return null;
}
}
public static string RandomString(int size, bool lowerCase)
{
var randomString = new StringBuilder(size);
/* Ascii start position (65 = A / 97 = a)*/
int start = lowerCase ? 97 : 65;
/* Add random chars*/
for (int i = 0; i < size; i++)
{
randomString.Append((char)((26 * randomSeed.NextDouble()) + start));
}
return randomString.ToString();
}
public static int RandomNumber(int minimal, int maximal)
{
return randomSeed.Next(minimal, maximal);
}
/* Returns a random boolean value*/
public static bool RandomBool()
{
return randomSeed.NextDouble() > 0.5;
} /* Returns a random color*/
public static DateTime RandomDateTime(DateTime min, DateTime max)
{
if (max <= min)
{
const string Message = "Max must be greater than min.";
throw new ArgumentException(Message);
}
long minTicks = min.Ticks;
long maxTicks = max.Ticks;
double rn = ((Convert.ToDouble(maxTicks) - Convert.ToDouble(minTicks)) * randomSeed.NextDouble()) + Convert.ToDouble(minTicks);
return new DateTime(Convert.ToInt64(rn));
}
}
}