/Utilities/Helpers/EnumHelper.cs
C# | 1135 lines | 687 code | 110 blank | 338 comment | 35 complexity | a9d723da4a25ba7ca879c28315c2a931 MD5 | raw file
Possible License(s): Apache-2.0
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Globalization;
- using System.Reflection;
- using NUnit.Framework;
-
- namespace Delta.Utilities.Helpers
- {
- /// <summary>
- /// Enum helper class, allows extracting Description attributes, which is
- /// useful for displaying name of enum and stuff. Also useful because
- /// Descriptions don't get obfuscated and EnumHelper has extra operations,
- /// like GetSize to get the number of elements an enum uses.
- /// </summary>
- public static class EnumHelper
- {
- #region EnumEnumerator Class
- /// <summary>
- /// Enum enumerator helper for GetEnumerator,
- /// this allow us to enumerate enums just like collections
- /// </summary>
- public class EnumEnumerator
- : IEnumerator, IEnumerable
- {
- #region EnumType (Public)
- /// <summary>
- /// The enum we use
- /// </summary>
- public Type EnumType;
- #endregion
-
- #region index (Public)
- /// <summary>
- /// Own index
- /// </summary>
- public int index;
- #endregion
-
- #region EnumCount (Public)
- /// <summary>
- /// Count of enum values.
- /// </summary>
- /// <returns>Int</returns>
- public int EnumCount
- {
- get
- {
- return enumValues.Length;
- }
- }
- #endregion
-
- #region Current (Public)
- /// <summary>
- /// Current enum value
- /// </summary>
- public object Current
- {
- get
- {
- if (index >= 0 &&
- index < EnumCount)
- {
- return enumValues.GetValue(index);
- }
- else
- {
- // Just return first entry if index is invalid
- return enumValues.GetValue(0);
- }
- }
- }
- #endregion
-
- #region Private
-
- #region enumValues (Private)
- /// <summary>
- /// Enum values
- /// </summary>
- private readonly Array enumValues;
- #endregion
-
- #endregion
-
- #region Constructors
- /// <summary>
- /// Create enum enumerator
- /// </summary>
- /// <param name="setEnumType">Enum type</param>
- public EnumEnumerator(Type setEnumType)
- {
- EnumType = setEnumType;
- index = -1;
- enumValues = Enum.GetValues(EnumType);
- }
- #endregion
-
- #region IEnumerable Members
- /// <summary>
- /// Get enumerator
- /// </summary>
- /// <returns>Enumerator to enumerate with</returns>
- public IEnumerator GetEnumerator()
- {
- return this;
- }
- #endregion
-
- #region IEnumerator Members
- /// <summary>
- /// Move next
- /// </summary>
- public bool MoveNext()
- {
- index++;
- // Finished?
- return index < EnumCount;
- }
-
- /// <summary>
- /// Reset
- /// </summary>
- public void Reset()
- {
- index = -1;
- }
- #endregion
- }
- #endregion
-
- #region GetCount (Static)
- /// <summary>
- /// Gets the number of elements for the given Enum type.
- /// </summary>
- /// <typeparam name="T">Type of enum</typeparam>
- /// <returns>Number of possible enum elements</returns>
- public static int GetCount<T>()
- {
- Type enumType = typeof(T);
- if (enumType.IsEnum)
- {
- return Enum.GetValues(enumType).Length;
- }
-
- Log.Warning(
- "EnumHelper.GetCount: The given type=" + enumType + " isn't a " +
- "valid enum!");
- return 0;
- }
-
- /// <summary>
- /// Gets the number of elements for the given Enum type.
- /// </summary>
- /// <param name="anyEnum">Any enum value</param>
- /// <returns>Number of enum values in this given enum</returns>
- public static int GetCount(this Enum anyEnum)
- {
- Type enumType = anyEnum.GetType();
- if (enumType.IsEnum)
- {
- return Enum.GetValues(enumType).Length;
- }
-
- Log.Warning(
- "EnumHelper.GetCount: The given type=" + enumType + " isn't a valid " +
- "enum!");
- return 0;
- }
- #endregion
-
- #region NextValue (Static)
- /// <summary>
- /// Get the next enum value in any given enum.
- /// </summary>
- /// <typeparam name="T">Type for this enum</typeparam>
- /// <param name="enumValue">Enum type</param>
- /// <returns>Next enum value</returns>
- public static T NextValue<T>(this T enumValue)
- where T : IConvertible
- {
- // At first we determine the type
- Type enumType = typeof(T);
- // to look if the given object is really an Enum
- if (enumType.IsEnum == false)
- {
- // if not, we log a warning
- Log.Warning(
- "EnumHelper.NextValue: The given type=" + enumType + " isn't a " +
- "valid enum!");
- // and just return the given value back...
- return enumValue;
- }
-
- // To know which is the current value of the enum, we just iterate
- // through all of them (in worst case)
- Array enumValues = Enum.GetValues(enumType);
- int foundIndex = MathHelper.InvalidIndex;
- for (int i = 0; i < enumValues.Length; i++)
- {
- // If we have found it (which occurs every time sooner or later)
- if (enumValues.GetValue(i).Equals(enumValue))
- {
- // we "compute" the index of the next value, which is just the next
- // index or the first index, if the current value is the last one
- // -> cycling
- foundIndex =
- i == enumValues.Length - 1
- ? 0
- : i + 1;
- break;
- }
- }
-
- return (T)enumValues.GetValue(foundIndex);
- }
- #endregion
-
- #region ToUInt64 (Static)
- /// <summary>
- /// Converts given enum into unsigned long
- /// </summary>
- /// <param name="enumValue">Enum value to convert</param>
- /// <returns>Unsigned long value created from this enum value</returns>
- /// <exception cref="InvalidOperationException">
- /// Invalid internal enum type
- /// </exception>
- public static ulong ToUInt64(this Enum enumValue)
- {
- switch (enumValue.GetTypeCode())
- {
- case TypeCode.SByte:
- case TypeCode.Int16:
- case TypeCode.Int32:
- case TypeCode.Int64:
- return (ulong)Convert.ToInt64(enumValue,
- CultureInfo.InvariantCulture);
-
- case TypeCode.Byte:
- case TypeCode.UInt16:
- case TypeCode.UInt32:
- case TypeCode.UInt64:
- return Convert.ToUInt64(enumValue, CultureInfo.InvariantCulture);
- }
-
- throw new InvalidOperationException("Invalid internal enum type");
- }
- #endregion
-
- #region ToInt (Static)
- /// <summary>
- /// Converts given enum into int
- /// </summary>
- /// <param name="enumValue">Enum value to convert</param>
- /// <returns>Integer value created from this enum value</returns>
- /// <exception cref="InvalidOperationException"></exception>
- public static int ToInt(this Enum enumValue)
- {
- TypeCode typeCode = enumValue.GetTypeCode();
- switch (typeCode)
- {
- case TypeCode.SByte:
- case TypeCode.Int16:
- case TypeCode.Int32:
- case TypeCode.Byte:
- case TypeCode.UInt16:
- return Convert.ToInt32(enumValue, CultureInfo.InvariantCulture);
-
- case TypeCode.UInt32:
- case TypeCode.Int64:
- case TypeCode.UInt64:
- Log.Warning(
- "You are converting an enum with internal type of " + typeCode +
- " to an Int32. This may yield wrong results, so use ToUInt64 " +
- "instead.");
- return Convert.ToInt32(enumValue, CultureInfo.InvariantCulture);
- }
-
- throw new InvalidOperationException(
- "Invalid internal enum type: " + typeCode);
- }
- #endregion
-
- #region IsFlagSet (Static)
- /// <summary>
- /// Checks if given Enum has given flag set. If the enum does not use
- /// flags, this method should not be used.
- /// </summary>
- /// <param name="combinedEnum">Combined enum value</param>
- /// <param name="flag">Flag to check</param>
- /// <returns>True if the enum flag is set, false otherwise.</returns>
- public static bool IsFlagSet(this Enum combinedEnum, Enum flag)
- {
- return combinedEnum.HasFlag(flag);
- }
- #endregion
-
- #region ToEnum (Static)
- /// <summary>
- /// Simple implementation which replaces all other Enum conversion methods.
- /// Works with: String names, string numbers, Combined enums (comma
- /// separated, or as number string), Irregular numbered ones.
- /// It returns default enum value, if there is no match.
- /// </summary>
- /// <typeparam name="T">Type of enum to parse</typeparam>
- /// <param name="enumName">
- /// Enum string to convert (can be a number, a string, a comma separated
- /// combination or a combined number)
- /// </param>
- /// <returns>
- /// Enum type parsed or the default value if parsing was not possible
- /// </returns>
- public static T ToEnum<T>(this string enumName)
- {
- try
- {
- return
- String.IsNullOrEmpty(enumName)
- ? default(T)
- : (T)Enum.Parse(typeof(T), enumName, false);
- }
- catch (Exception)
- {
- return default(T);
- }
- }
-
- /// <summary>
- /// Simple implementation which replaces all other Enum conversion methods.
- /// Works with: String names, string numbers, Combined enums (comma
- /// separated, or as number string), Irregular numbered ones.
- /// It returns default enum value, if there is no match.
- /// </summary>
- /// <typeparam name="T">Type of enum to parse</typeparam>
- /// <param name="enumNames">
- /// Enum string array of enum values, which will be combined into one
- /// comma separated string and converted to an Enum.
- /// </param>
- /// <returns>
- /// Enum type parsed or the default value if parsing was not possible
- /// </returns>
- public static T ToEnum<T>(this string[] enumNames)
- {
- return enumNames.Write().ToEnum<T>();
- }
-
- /// <summary>
- /// Simple implementation which replaces all other Enum conversion methods.
- /// Works with: String names, string numbers, Combined enums (comma
- /// separated, or as number string), Irregular numbered ones.
- /// It returns default enum value, if there is no match.
- /// </summary>
- /// <typeparam name="T">Type of enum to parse</typeparam>
- /// <param name="enumName">
- /// Enum string to convert (can be a number, a string, a comma separated
- /// combination or a combined number)
- /// </param>
- /// <param name="result">
- /// Enum type parsed or the default value if parsing was not possible
- /// </param>
- /// <returns>True if the enum value was found, false otherwise</returns>
- public static bool ToEnum<T>(this string enumName, out T result)
- {
- if (String.IsNullOrEmpty(enumName))
- {
- // Special case: treat empty string as default value
- result = default(T);
- return true;
- }
- try
- {
- result = (T)Enum.Parse(typeof(T), enumName, false);
- return true;
- }
- catch (Exception)
- {
- result = default(T);
- return false;
- }
- }
- #endregion
-
- #region GetEnumIndex (Static)
- /// <summary>
- /// Get enum index from value. If we use a known enum, we could simply
- /// write (int)SomeEnum.Value, but we can't do that with System.Enum
- /// we have to use in a lot of methods or if we use an auto-generated enum
- /// </summary>
- /// <param name="enumValue">Enum value</param>
- /// <returns>
- /// Index of the enum value, which is normally the enum value,
- /// but if the enum uses custom values for each enum, it is not the same!
- /// </returns>
- public static int GetEnumIndex(this Enum enumValue)
- {
- string[] enumNames = Enum.GetNames(enumValue.GetType());
-
- for (int num = 0; num < enumNames.Length; num++)
- {
- if (enumValue.ToString() == enumNames[num])
- {
- return num;
- }
- }
-
- // If not found, just return maxValue + 1. Don't throw any exception
- return enumNames.Length;
- }
- #endregion
-
- #region SelectNextEnum (Static)
- /// <summary>
- /// Select next enum
- /// </summary>
- /// <param name="enumValue">Enum</param>
- /// <returns>Next enum value</returns>
- public static Enum SelectNextEnum(this Enum enumValue)
- {
- Array enumValues = Enum.GetValues(enumValue.GetType());
-
- // Select next enum value
- int valueIndex = (GetEnumIndex(enumValue) + 1) % GetCount(enumValue);
- return (Enum)enumValues.GetValue(valueIndex);
- }
- #endregion
-
- #region Next (Static)
- /// <summary>
- /// Get next enum value
- /// </summary>
- /// <param name="enumValue">Enum</param>
- /// <returns>Next enum value</returns>
- public static Enum Next(this Enum enumValue)
- {
- return SelectNextEnum(enumValue);
- }
- #endregion
-
- #region SelectPreviousEnum (Static)
- /// <summary>
- /// Select previous enum
- /// </summary>
- /// <param name="enumValue">Enum</param>
- /// <returns>Previous enum value</returns>
- public static Enum SelectPreviousEnum(this Enum enumValue)
- {
- Array enumValues = Enum.GetValues(enumValue.GetType());
-
- // Select next enum value
- int valueIndex = (GetEnumIndex(enumValue) - 1) % GetCount(enumValue);
- if (valueIndex < 0)
- {
- valueIndex += GetCount(enumValue);
- }
- return (Enum)enumValues.GetValue(valueIndex);
- }
- #endregion
-
- #region Previous (Static)
- /// <summary>
- /// Get previous enum value
- /// </summary>
- /// <param name="enumValue">Enum</param>
- /// <returns>Previous enum value</returns>
- public static Enum Previous(this Enum enumValue)
- {
- return SelectPreviousEnum(enumValue);
- }
- #endregion
-
- #region GetValues (Static)
- /// <summary>
- /// Returns all values of the given enum, which is severy single possible
- /// enum value as an array of enum values. For more details see:
- /// http://www.dolittle.no/blogs/einar/archive/2008/01/13/missing-enum-getvalues-when-doing-silverlight-for-instance.aspx
- /// </summary>
- public static T[] GetValues<T>()
- {
- Type enumType = typeof(T);
-
- #region Validation
- if (enumType.IsEnum == false)
- {
- Log.Warning("The given type '" + enumType + "' isn't an enum");
- return new T[0];
- }
- #endregion
-
- List<T> values = new List<T>();
- foreach (FieldInfo field in enumType.GetFields())
- {
- if (field.IsLiteral)
- {
- T value = (T)field.GetValue(enumType);
- values.Add(value);
- }
- }
-
- return values.ToArray();
- }
-
- /// <summary>
- /// Returns all values of the given enum, which is severy single possible
- /// enum value as an array of enum values. For more details see:
- /// http://www.dolittle.no/blogs/einar/archive/2008/01/13/missing-enum-getvalues-when-doing-silverlight-for-instance.aspx
- /// </summary>
- /// <param name="enumType">Some enum type</param>
- /// <returns>Array of enum values</returns>
- public static Enum[] GetValues(this Type enumType)
- {
- #region Validation
- if (enumType.IsEnum == false)
- {
- Log.Warning("The given type '" + enumType + "' isn't an enum");
- return new Enum[0];
- }
- #endregion
-
- List<Enum> values = new List<Enum>();
- foreach (FieldInfo field in enumType.GetFields())
- {
- if (field.IsLiteral)
- {
- object value = field.GetValue(enumType);
- values.Add((Enum)value);
- }
- }
-
- return values.ToArray();
- }
- #endregion
-
- #region GetNames (Static)
- /// <summary>
- /// Returns the names for all enum values, which is severy single possible
- /// enum value as a string array. For more details see:
- /// http://stackoverflow.com/questions/1038234/iterating-through-an-enumeration-in-silverlight
- /// </summary>
- /// <typeparam name="T">Type of enum</typeparam>
- /// <returns>List of strings with the enum names</returns>
- public static string[] GetNames<T>()
- {
- return GetNames(typeof(T));
- }
-
- /// <summary>
- /// Returns the names for all enum values, which is severy single possible
- /// enum value as a string array. For more details see:
- /// http://stackoverflow.com/questions/1038234/iterating-through-an-enumeration-in-silverlight
- /// </summary>
- /// <param name="enumType">Some enum type</param>
- /// <returns>List of strings with the enum names</returns>
- public static string[] GetNames(Type enumType)
- {
- #region Validation
- if (enumType.IsEnum == false)
- {
- Log.Warning("The given type '" + enumType + "' isn't an enum");
- return new string[0];
- }
- #endregion
-
- List<string> values = new List<string>();
- foreach (FieldInfo field in enumType.GetFields())
- {
- if (field.IsLiteral)
- {
- values.Add(field.Name);
- }
- }
-
- return values.ToArray();
- }
- #endregion
-
- #region GetEnumerator (Static)
- /// <summary>
- /// Get enumerator
- /// </summary>
- /// <returns>Enumerator for enumeration (foreach, etc.)</returns>
- public static EnumEnumerator GetEnumerator(Type enumType)
- {
- return new EnumEnumerator(enumType);
- }
- #endregion
-
- #region GetEnumDescription (Static)
- /// <summary>
- /// Gets enum value Description Attribute
- /// </summary>
- /// <param name="value">
- /// The value you want the description attribute for
- /// </param>
- /// <returns>The description, if any, else it's value.ToString()</returns>
- public static string GetEnumDescription(this Enum value)
- {
- FieldInfo field = value.GetType().GetField(value.ToString());
- if (field != null)
- {
- DescriptionAttribute[] attributes =
- (DescriptionAttribute[])field.GetCustomAttributes(
- typeof(DescriptionAttribute), false);
- return
- attributes.Length > 0
- ? attributes[0].Description
- : value.ToString();
- }
-
- // If that fails, just use enum name
- return value.ToString();
- }
- #endregion
-
- #region Description (Static)
- /// <summary>
- /// Helper method to get an enum description attribute from a specific enum
- /// value as a string.
- /// </summary>
- /// <param name="value">Enum value</param>
- /// <returns>
- /// Description text if available, otherwise just the enum name.
- /// </returns>
- public static string Description(this Enum value)
- {
- return GetEnumDescription(value);
- }
- #endregion
-
- #region GetEnumDescription (Static)
- /// <summary>
- /// Gets the description for a certain named value in an enum
- /// </summary>
- /// <param name="value">The type of the enum</param>
- /// <param name="name">The name of the enum value</param>
- /// <returns>The description, if any, else the passed name</returns>
- public static string GetEnumDescription(Type value, string name)
- {
- FieldInfo fi = value.GetField(name);
- if (fi != null)
- {
- DescriptionAttribute[] attributes =
- (DescriptionAttribute[])fi.GetCustomAttributes(
- typeof(DescriptionAttribute), false);
- return attributes.Length > 0
- ? attributes[0].Description
- : name;
- }
- // If that fails, just use name
- return name;
- }
- #endregion
-
- #region GetAllEnumDescriptions (Static)
- /// <summary>
- /// Get all enum descriptions as string array, useful for
- /// Controls.DrawDropDownList(...)
- /// </summary>
- public static string[] GetAllEnumDescriptions(Type enumType)
- {
- ;
- EnumEnumerator enumerator = GetEnumerator(enumType);
- string[] descArray = new string[enumerator.EnumCount];
-
- foreach (Enum enumValue in enumerator)
- {
- descArray[enumerator.index] =
- GetEnumDescription(enumValue);
- }
-
- return descArray;
- }
-
- /// <summary>
- /// Get all enum descriptions as string array, useful for
- /// Controls.DrawDropDownList(...)
- /// </summary>
- /// <param name="value">Enum value</param>
- /// <returns>List of enum descriptions (if there are any)</returns>
- public static string[] GetAllEnumDescriptions(this Enum value)
- {
- return GetAllEnumDescriptions(value.GetType());
- }
- #endregion
-
- #region GetEnumValue (Static)
- /// <summary>
- /// Gets the value of an enum, based on its Description Attribute or
- /// named value.
- /// </summary>
- /// <param name="value">The enum type</param>
- /// <param name="description">The description or name of the element
- /// </param>
- /// <returns>The value, or the passed in description, if it was not found
- /// </returns>
- public static object GetEnumValue(Type value, string description)
- {
- FieldInfo[] fis = value.GetFields();
- foreach (FieldInfo fi in fis)
- {
- DescriptionAttribute[] attributes =
- (DescriptionAttribute[])fi.GetCustomAttributes(
- typeof(DescriptionAttribute), false);
-
- if ((attributes.Length > 0 &&
- attributes[0].Description == description) ||
- fi.Name == description)
- {
- return fi.GetValue(fi.Name);
- }
- }
-
- return description;
- }
- #endregion
-
- #region ToStringArray
- /// <summary>
- /// Get the combined enum values back as a string array. Makes only sense
- /// for combined enums as normal enums will just return one entry and you
- /// could just use ToString to get to that.
- /// </summary>
- /// <param name="value">Combined enum value</param>
- /// <returns>
- /// String array with all the selected enum values as names. You can use
- /// ToEnum to convert the string array back to a combined enum.
- /// </returns>
- public static string[] ToStringArray(this Enum value)
- {
- return value.ToString().SplitAndTrim(',');
- }
- #endregion
-
- #region SplitCombinedEnum
- /// <summary>
- /// Get the combined enum values back as an enum list. Makes only sense
- /// for combined enums as normal enums will just return one entry and you
- /// could just use the value itself.
- /// </summary>
- /// <param name="value">Combined enum value</param>
- /// <returns>
- /// List with all the selected enum values (flags) that were used to build
- /// this combined enum.
- /// </returns>
- public static List<T> SplitCombinedEnum<T>(this T value)
- where T : IConvertible
- {
- // Make sure we got a valid enum
- if (value is Enum == false)
- {
- Log.Warning(
- "EnumHelper.SplitCombinedEnum: The given type=" + value + " isn't " +
- "a enum, unable to split it!");
- // And just return the given value back...
- return new List<T>(new T[]
- {
- value
- });
- }
-
- string[] enumTexts = (value as Enum).ToStringArray();
- List<T> ret = new List<T>();
- if (enumTexts.Length > 1)
- {
- foreach (string enumText in enumTexts)
- {
- ret.Add(EnumHelper.ToEnum<T>(enumText));
- }
- return ret;
- }
-
- // No combined enum, just return the current value
- ret.Add(value);
- return ret;
- }
- #endregion
-
- /// <summary>
- /// Enum helper tests
- /// </summary>
- public class EnumHelperTests
- {
- #region Helpers
- /// <summary>
- /// Test enum
- /// </summary>
- private enum TestEnum
- {
- [Description("Some entry")]
- SomeEntry,
-
- [Description("Another one")]
- AnotherOne,
-
- [Description("Hey stop it now")]
- HeyStopItNow,
-
- [Description("Okay okay")]
- OkayOkay,
- }
- #endregion
-
- #region Helpers
- /// <summary>
- /// Flag enum
- /// </summary>
- [Flags]
- private enum FlagEnum : ulong
- {
- Flag1 = 1,
-
- Flag2 = 2,
-
- Flag3 = 4,
-
- Flag4 = 8,
-
- FlagUint64 = 1 << 48,
- }
- #endregion
-
- #region Helpers
- /// <summary>
- /// Test combined enum
- /// </summary>
- [Flags]
- private enum TestCombinedEnum
- {
- Zero = 0,
-
- NumberOne = 1,
-
- NumberTwo = 2,
-
- NumberFour = 4,
- }
- #endregion
-
- #region TestEnumStuff (Static)
- /// <summary>
- /// Test enum stuff. Note: Too slow for a dynamic unit test.
- /// </summary>
- [Test]
- public static void TestEnumStuff()
- {
- //// First get size of TestEnum (with type of enum)
- //Assert.Equal(GetSize(typeof(TestEnum)), 4);
- //Assert.Equal(typeof(TestEnum).GetSize(), 4);
-
- //// Now try with some enum member (should give the same result)
- //Assert.Equal(GetSize(TestEnum.SomeEntry), 4);
-
- // Test with extension
- Assert.Equal(TestEnum.SomeEntry.GetCount(), 4);
- Assert.Equal(TestEnum.SomeEntry.GetCount(), 4);
-
- // Try to get enum from name
- Assert.Equal(TestEnum.OkayOkay,
- "OkayOkay".ToEnum<TestEnum>());
-
- // Get description of an enum members
- Assert.Equal(GetEnumDescription(TestEnum.OkayOkay), "Okay okay");
- Assert.Equal(TestEnum.OkayOkay.Description(), "Okay okay");
-
- // Test enum enumerator stuff
- string allEnumNames = GetEnumerator(typeof(TestEnum)).Write();
- Assert.Equal("SomeEntry, AnotherOne, HeyStopItNow, OkayOkay",
- allEnumNames);
-
- // Test same with description values
- string allEnumDescNames = "";
- foreach (TestEnum enumValue in
- GetEnumerator(typeof(TestEnum)))
- {
- allEnumDescNames += (allEnumDescNames.Length == 0
- ? ""
- : ", ") +
- GetEnumDescription(enumValue);
- }
- Assert.Equal(
- "Some entry, Another one, Hey stop it now, Okay okay",
- allEnumDescNames);
-
- // Same check with GetAllEnumDescriptions
- Assert.Equal(
- "Some entry, Another one, Hey stop it now, Okay okay",
- GetAllEnumDescriptions(typeof(TestEnum)).Write());
- }
- #endregion
-
- #region TestNextAndPreviousEnum (Static)
- /// <summary>
- /// Test next and previous enum. Note: Too slow for a dynamic unit test.
- /// </summary>
- [Test]
- public static void TestNextAndPreviousEnum()
- {
- TestEnum someEnum = TestEnum.SomeEntry;
- Assert.Equal(TestEnum.SomeEntry, someEnum);
-
- // Check next entry
- someEnum = (TestEnum)someEnum.SelectNextEnum();
- Assert.Equal(TestEnum.AnotherOne, someEnum);
- Assert.Equal(TestEnum.AnotherOne, TestEnum.SomeEntry.Next());
-
- // Go back 2 entries, this will select the last enum entry
- someEnum = (TestEnum)someEnum.SelectPreviousEnum();
- someEnum = (TestEnum)someEnum.SelectPreviousEnum();
- Assert.Equal(TestEnum.OkayOkay, someEnum);
- Assert.Equal(TestEnum.AnotherOne, TestEnum.HeyStopItNow.Previous());
- }
- #endregion
-
- #region TestGetAllEnumValues (Static)
- /// <summary>
- /// Test get all enum values. Note: Too slow for a dynamic unit test.
- /// </summary>
- [Test]
- public static void TestGetAllEnumValues()
- {
- // Test with type
- TestEnum[] enums = GetValues<TestEnum>();
- Assert.Equal("SomeEntry, AnotherOne, HeyStopItNow, OkayOkay",
- enums.Write());
-
- // Create with instance
- string[] inputEnumNames = new[]
- {
- "SomeEntry",
- "AnotherOne",
- "HeyStopItNow",
- "OkayOkay",
- };
-
- //This code needs reflection, not supported right now in DE:
- //enums = GetAllEnumValues(CreateEnum(inputEnumNames).GetType());
- //Assert.Equal("SomeEntry, AnotherOne, HeyStopItNow, OkayOkay",
- // ArrayHelper.Write(enums));
- }
- #endregion
-
- #region GetValues (Static)
- /// <summary>
- /// Get values
- /// </summary>
- [Test]
- public static void GetValues()
- {
- object[] values = typeof(StringSplitOptions).GetValues();
- Assert.Equal(values.Length, 2);
- Assert.Equal(values[0], StringSplitOptions.None);
- Assert.Equal(values[1], StringSplitOptions.RemoveEmptyEntries);
-
- StringSplitOptions[] genericValues =
- GetValues<StringSplitOptions>();
- Assert.Equal(genericValues.Length, 2);
- Assert.Equal(genericValues[0], StringSplitOptions.None);
- Assert.Equal(genericValues[1], StringSplitOptions.RemoveEmptyEntries);
- }
- #endregion
-
- #region GetNames (Static)
- /// <summary>
- /// Get names
- /// </summary>
- [Test]
- public static void GetNames()
- {
- string[] names = EnumHelper.GetNames(typeof(StringSplitOptions));
- Assert.Equal(names.Length, 2);
- Assert.Equal(names[0], "None");
- Assert.Equal(names[1], "RemoveEmptyEntries");
-
- string[] genericNames = GetNames<StringSplitOptions>();
- Assert.Equal(genericNames.Length, 2);
- Assert.Equal(genericNames[0], "None");
- Assert.Equal(genericNames[1], "RemoveEmptyEntries");
- }
- #endregion
-
- #region ConvertToNumberWithCombinedEnum (LongRunning)
- /// <summary>
- /// Convert to number
- /// </summary>
- [Test]
- public void ConvertToNumberWithCombinedEnum()
- {
- // Reproduce test with standard methods
- Assert.Equal(4, (int)"NumberFour".ToEnum<TestCombinedEnum>());
- Assert.Equal(6,
- (int)"NumberTwo, NumberFour".ToEnum<TestCombinedEnum>());
- Assert.Equal(
- (int)(TestCombinedEnum.NumberTwo | TestCombinedEnum.NumberFour),
- (int)"6".ToEnum<TestCombinedEnum>());
- Assert.Equal("NumberTwo, NumberFour",
- (TestCombinedEnum.NumberTwo |
- TestCombinedEnum.NumberFour).ToString());
- Assert.Equal(TestCombinedEnum.Zero, "bla".ToEnum<TestCombinedEnum>());
- Assert.Equal("Zero", TestCombinedEnum.Zero.ToString());
-
- Assert.Equal(0,
- (int)(TestCombinedEnum.Zero.ToString().
- ToEnum<TestCombinedEnum>()));
- Assert.Equal(
- (int)(TestCombinedEnum.NumberTwo |
- TestCombinedEnum.NumberFour),
- (int)(TestCombinedEnum.NumberTwo |
- TestCombinedEnum.NumberFour.ToString().
- ToEnum<TestCombinedEnum>()));
-
- // Finally write down a combined enum.
- TestCombinedEnum combinedValue =
- TestCombinedEnum.NumberTwo |
- TestCombinedEnum.NumberFour;
- Assert.Equal("NumberTwo, NumberFour", combinedValue.ToString());
- Assert.Equal(combinedValue.ToStringArray(), new string[]
- {
- "NumberTwo", "NumberFour"
- });
- // This can be useful to build a combined enum name as a filename!
- Assert.Equal(combinedValue.ToStringArray().Write("_"),
- "NumberTwo_NumberFour");
- Assert.Equal(combinedValue,
- combinedValue.ToStringArray().ToEnum<TestCombinedEnum>());
- }
- #endregion
-
- #region GetCount
- /// <summary>
- /// Get count
- /// </summary>
- [Test]
- public void GetCount()
- {
- Assert.Equal(7, GetCount<DayOfWeek>());
- }
- #endregion
-
- #region NextValue
- /// <summary>
- /// Next value
- /// </summary>
- [Test]
- public void NextValue()
- {
- Assert.Equal(DayOfWeek.Monday, DayOfWeek.Sunday.NextValue());
- }
- #endregion
-
- #region ToEnum
- /// <summary>
- /// Get enum from name
- /// </summary>
- [Test]
- public void ToEnum()
- {
- // Standard Enum
- Assert.Equal(FlagEnum.Flag2, "Flag2".ToEnum<FlagEnum>());
-
- // Combined Enum
- Assert.Equal(FlagEnum.Flag1 | FlagEnum.Flag3,
- "Flag1, Flag3".ToEnum<FlagEnum>());
- Assert.Equal(FlagEnum.Flag2 | FlagEnum.Flag4,
- "Flag4, Flag2".ToEnum<FlagEnum>());
-
- // Number to Enum
- Assert.Equal(FlagEnum.Flag3,
- "4".ToEnum<FlagEnum>());
-
- // Number to combined Enum
- Assert.Equal(FlagEnum.Flag2 | FlagEnum.Flag4,
- "10".ToEnum<FlagEnum>());
- }
- #endregion
-
- #region FlagTests
- /// <summary>
- /// Flag tests
- /// </summary>
- [Test]
- public void FlagTests()
- {
- Assert.Equal(2,
- (int)("NumberTwo, NumberFour".ToEnum<TestCombinedEnum>() &
- TestCombinedEnum.NumberTwo));
- }
- #endregion
-
- #region ConvertToInteger
- /// <summary>
- /// ConvertToInteger test
- /// </summary>
- [Test]
- public void ConvertToInteger()
- {
- // Test with int
- Assert.Equal(2, TestCombinedEnum.NumberTwo.ToInt());
- Assert.Equal(6,
- (TestCombinedEnum.NumberFour |
- TestCombinedEnum.NumberTwo).ToInt());
-
- // Test with UInt64
- Assert.Equal<ulong>(1 << 48, FlagEnum.FlagUint64.ToUInt64());
-
- // This should warn about possible overflows
- Assert.Equal(4, FlagEnum.Flag3.ToInt());
- }
- #endregion
-
- #region ToInt
- /// <summary>
- /// Convert to number
- /// </summary>
- [Test]
- public void ToInt()
- {
- Assert.Equal(0,
- EnumHelper.ToInt(TestCombinedEnum.Zero));
- Assert.Equal(2,
- EnumHelper.ToInt(TestCombinedEnum.NumberTwo));
-
- Assert.Equal(4,
- EnumHelper.ToInt(TestCombinedEnum.NumberFour));
- Assert.Equal(6, EnumHelper.ToInt(
- TestCombinedEnum.NumberTwo | TestCombinedEnum.NumberFour));
- Assert.Equal(TestCombinedEnum.NumberFour,
- EnumHelper.ToEnum<TestCombinedEnum>("4"));
- Assert.Equal(TestCombinedEnum.NumberTwo | TestCombinedEnum.NumberFour,
- EnumHelper.ToEnum<TestCombinedEnum>("6"));
- }
- #endregion
- }
- }
- }