mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
correct build number calculations - now its days from last release + hour + minute of build some changes to migrate to json schema + preparation of using db to save settings
138 lines
5.0 KiB
C#
138 lines
5.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Enum = System.Enum;
|
|
|
|
namespace mRemoteNGTests.TestHelpers
|
|
{
|
|
internal static class Randomizer
|
|
{
|
|
private static readonly Random Random = new();
|
|
|
|
internal static string RandomString(params string[] excludedStrings)
|
|
{
|
|
return GetNonExcludedValue(() => Guid.NewGuid().ToString("N"), excludedStrings);
|
|
}
|
|
|
|
internal static bool RandomBool(bool? excludedBool = null)
|
|
{
|
|
if (excludedBool.HasValue)
|
|
return !excludedBool.Value;
|
|
|
|
return Random.Next() % 2 == 0;
|
|
}
|
|
|
|
internal static int RandomInt(int minValue = int.MinValue, int maxValue = int.MaxValue, params int[] excludeInts)
|
|
{
|
|
return GetNonExcludedValue(() => Random.Next(minValue, maxValue), excludeInts);
|
|
}
|
|
|
|
internal static DateTime RandomDateTime(params DateTime[] excludeTimes)
|
|
{
|
|
var date = GetNonExcludedValue(() =>
|
|
new DateTime(
|
|
RandomInt(minValue: 1990, maxValue: 2019),
|
|
RandomInt(minValue: 1, maxValue: 13),
|
|
RandomInt(minValue: 1, maxValue: 29),
|
|
RandomInt(minValue: 0, maxValue: 24),
|
|
RandomInt(minValue: 0, maxValue: 60),
|
|
RandomInt(minValue: 0, maxValue: 60)),
|
|
excludeTimes);
|
|
|
|
return date;
|
|
}
|
|
|
|
internal static T RandomEnum<T>(params object[] excludeValues) where T : struct, IConvertible
|
|
{
|
|
if (!typeof(T).IsEnum)
|
|
throw new ArgumentException("T must be an enum");
|
|
|
|
return (T)RandomEnum(typeof(T), excludeValues);
|
|
}
|
|
|
|
internal static object RandomEnum(Type enumType, params object[] excludeValues)
|
|
{
|
|
if (!enumType.IsEnum)
|
|
throw new ArgumentException("enumType must be an enum");
|
|
|
|
var values = Enum.GetValues(enumType);
|
|
return GetNonExcludedValue(() => values.GetValue(Random.Next(values.Length)), excludeValues);
|
|
}
|
|
|
|
private static T GetNonExcludedValue<T>(Func<T> builder, params object[] excludedValues)
|
|
{
|
|
do
|
|
{
|
|
var value = builder();
|
|
if (!excludedValues.Contains(value))
|
|
return value;
|
|
} while (true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Randomizes the primitive-type settable properties of the given object.
|
|
/// Returns the same object instance to enable fluent method calls. It will
|
|
/// never choose the value that the property current holds. For booleans, this
|
|
/// means they will always be toggled rather than truly randomized.
|
|
/// </summary>
|
|
internal static T RandomizeValues<T>(this T con)
|
|
where T : class
|
|
{
|
|
var opByType = new Dictionary<Type, Action<PropertyInfo, T>>
|
|
{
|
|
{ typeof(int), (p, c) => p.SetValue(c, RandomInt(minValue: 0, excludeInts:(int)p.GetValue(c))) },
|
|
{ typeof(bool), (p, c) => p.SetValue(c, !(bool)p.GetValue(c)) },
|
|
{ typeof(string), (p, c) => p.SetValue(c, RandomString((string)p.GetValue(c))) },
|
|
{ typeof(DateTime), (p, c) => p.SetValue(c, RandomDateTime((DateTime)p.GetValue(c))) },
|
|
{ typeof(Enum), (p, c) => p.SetValue(c, RandomEnum(p.PropertyType, p.GetValue(c))) },
|
|
};
|
|
|
|
var settableProperties = con
|
|
.GetType()
|
|
.GetProperties()
|
|
.Where(p => p.GetSetMethod() != null);
|
|
|
|
foreach (var property in settableProperties)
|
|
{
|
|
if (opByType.TryGetValue(property.PropertyType, out var mutator))
|
|
mutator(property, con);
|
|
|
|
else if (property.PropertyType.BaseType != null &&
|
|
opByType.TryGetValue(property.PropertyType.BaseType, out var mutator2))
|
|
mutator2(property, con);
|
|
}
|
|
|
|
return con;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Toggles all <see cref="bool"/> settable properties
|
|
/// on the given object.
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="obj"></param>
|
|
/// <param name="excludeProperties"></param>
|
|
/// <returns></returns>
|
|
internal static T ToggleAllBooleanProperties<T>(this T obj, params string[] excludeProperties)
|
|
where T : class
|
|
{
|
|
var settableBooleanProperties = obj
|
|
.GetType()
|
|
.GetProperties()
|
|
.Where(p =>
|
|
p.GetSetMethod() != null &&
|
|
p.PropertyType == typeof(bool) &&
|
|
!excludeProperties.Contains(p.Name));
|
|
|
|
foreach (var property in settableBooleanProperties)
|
|
{
|
|
var currentValue = (bool)property.GetValue(obj);
|
|
property.SetValue(obj, !currentValue);
|
|
}
|
|
|
|
return obj;
|
|
}
|
|
}
|
|
}
|