diff --git a/Extenso.Core/ByteArrayExtensions.cs b/Extenso.Core/ByteArrayExtensions.cs index fe73c3b..7b3f75b 100644 --- a/Extenso.Core/ByteArrayExtensions.cs +++ b/Extenso.Core/ByteArrayExtensions.cs @@ -46,67 +46,78 @@ public static T BinaryDeserialize(this byte[] data) } } - /// - /// Encrypts data with the System.Security.Cryptography.RSA algorithm. - /// - /// The data to be encrypted. - /// The parameters for System.Security.Cryptography.RSA. - /// - /// true to perform direct System.Security.Cryptography.RSA encryption using OAEP - /// padding (only available on a computer running Windows XP or later); otherwise, - /// false to use PKCS#1 v1.5 padding. - /// - /// The encrypted data. - public static byte[] RSAEncrypt(this byte[] source, RSAParameters parameters, bool fOAEP) - { - using (var rsaCryptoServiceProvider = new RSACryptoServiceProvider()) - { - rsaCryptoServiceProvider.ImportParameters(parameters); - return rsaCryptoServiceProvider.Encrypt(source, fOAEP); - } - } + //public static string Decrypt(this byte[] source, Encoding encoding, ICryptoTransform cryptoTransform) + //{ + // using (var memoryStream = new MemoryStream(source)) + // using (var cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read)) + // { + // byte[] bytes = new byte[source.Length]; + // cryptoStream.Read(bytes, 0, bytes.Length); + // return encoding.GetString(bytes); + // } + //} - /// - /// Decrypts data with the System.Security.Cryptography.RSA algorithm. - /// - /// The data to be decrypted. - /// The parameters for System.Security.Cryptography.RSA. - /// - /// true to perform direct System.Security.Cryptography.RSA decryption using OAEP - /// padding (only available on a computer running Microsoft Windows XP or later); - /// otherwise, false to use PKCS#1 v1.5 padding. - /// - /// The decrypted data, which is the original plain text before encryption. - public static byte[] RSADecrypt(this byte[] source, RSAParameters parameters, bool fOAEP) - { - using (var rsaCryptoServiceProvider = new RSACryptoServiceProvider()) - { - rsaCryptoServiceProvider.ImportParameters(parameters); - return rsaCryptoServiceProvider.Decrypt(source, fOAEP); - } - } + ///// + ///// Encrypts data with the System.Security.Cryptography.RSA algorithm. + ///// + ///// The data to be encrypted. + ///// The parameters for System.Security.Cryptography.RSA. + ///// + ///// true to perform direct System.Security.Cryptography.RSA encryption using OAEP + ///// padding (only available on a computer running Windows XP or later); otherwise, + ///// false to use PKCS#1 v1.5 padding. + ///// + ///// The encrypted data. + //public static byte[] RSAEncrypt(this byte[] source, RSAParameters parameters, bool fOAEP) + //{ + // using (var rsaCryptoServiceProvider = new RSACryptoServiceProvider()) + // { + // rsaCryptoServiceProvider.ImportParameters(parameters); + // return rsaCryptoServiceProvider.Encrypt(source, fOAEP); + // } + //} - /// - /// Decrypts the specified byte array using the TripleDES symmetric algorithm and returns the original string. - /// - /// The data to be decrypted. - /// The System.Text.Encoding to use. - /// The secret key to use for the symmetric algorithm. - /// The initialization vector to use for the symmetric algorithm. - /// The decrypted data, which is the original plain text before encryption. - public static string TripleDESDecrypt(this byte[] source, Encoding encoding, byte[] key, byte[] initializationVector) - { - using (var memoryStream = new MemoryStream(source)) - using (var cryptoStream = new CryptoStream( - memoryStream, - new TripleDESCryptoServiceProvider().CreateDecryptor(key, initializationVector), - CryptoStreamMode.Read)) - { - byte[] bytes = new byte[source.Length]; - cryptoStream.Read(bytes, 0, bytes.Length); - return encoding.GetString(bytes); - } - } + ///// + ///// Decrypts data with the System.Security.Cryptography.RSA algorithm. + ///// + ///// The data to be decrypted. + ///// The parameters for System.Security.Cryptography.RSA. + ///// + ///// true to perform direct System.Security.Cryptography.RSA decryption using OAEP + ///// padding (only available on a computer running Microsoft Windows XP or later); + ///// otherwise, false to use PKCS#1 v1.5 padding. + ///// + ///// The decrypted data, which is the original plain text before encryption. + //public static byte[] RSADecrypt(this byte[] source, RSAParameters parameters, bool fOAEP) + //{ + // using (var rsaCryptoServiceProvider = new RSACryptoServiceProvider()) + // { + // rsaCryptoServiceProvider.ImportParameters(parameters); + // return rsaCryptoServiceProvider.Decrypt(source, fOAEP); + // } + //} + + ///// + ///// Decrypts the specified byte array using the TripleDES symmetric algorithm and returns the original string. + ///// + ///// The data to be decrypted. + ///// The System.Text.Encoding to use. + ///// The secret key to use for the symmetric algorithm. + ///// The initialization vector to use for the symmetric algorithm. + ///// The decrypted data, which is the original plain text before encryption. + //public static string TripleDESDecrypt(this byte[] source, Encoding encoding, byte[] key, byte[] initializationVector) + //{ + // using (var memoryStream = new MemoryStream(source)) + // using (var cryptoStream = new CryptoStream( + // memoryStream, + // TripleDES.Create().CreateDecryptor(key, initializationVector), + // CryptoStreamMode.Read)) + // { + // byte[] bytes = new byte[source.Length]; + // cryptoStream.Read(bytes, 0, bytes.Length); + // return encoding.GetString(bytes); + // } + //} /// /// Creates a new non-resizable instance of the System.IO.MemoryStream class based on the specified byte array. diff --git a/Extenso.Core/CharExtensions.cs b/Extenso.Core/CharExtensions.cs index 8d130c6..66c1882 100644 --- a/Extenso.Core/CharExtensions.cs +++ b/Extenso.Core/CharExtensions.cs @@ -5,16 +5,6 @@ /// public static class CharExtensions { - /// - /// Gets a value indicating whether the specified Unicode character is a letter (uppercase or lowercase). - /// - /// The Unicode character to examine. - /// true if the character is a letter; otherwise false. - public static bool IsLetter(this char c) - { - return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'); - } - /// /// Initializes a new instance of the System.String class to the value indicated by a specified Unicode character repeated a specified number of times. /// diff --git a/Extenso.Core/DateTimeExtensions.cs b/Extenso.Core/DateTimeExtensions.cs index c49160a..951837a 100644 --- a/Extenso.Core/DateTimeExtensions.cs +++ b/Extenso.Core/DateTimeExtensions.cs @@ -38,9 +38,11 @@ public static bool IsNullOrDefault(this DateTime? source) /// A System.DateTime equivalent for unixTimestamp public static DateTime ParseUnixTimestamp(int unixTimestamp) { - return new DateTime(1970, 1, 1, 0, 0, 0, 0) - .AddSeconds(unixTimestamp) - .ToLocalTime(); + return DateTimeOffset.FromUnixTimeSeconds(unixTimestamp).DateTime; + + //return new DateTime(1970, 1, 1, 0, 0, 0, 0) + // .AddSeconds(unixTimestamp) + // .ToLocalTime(); } /// @@ -96,9 +98,9 @@ public static string ToISO8601DateString(this DateTime source) /// /// The System.DateTime to convert to its equivalent Unix Timestamp. /// A System.Int32 whose value represents the Unix Timestamp equivalent of the given System.DateTime. - public static int ToUnixTimestamp(this DateTime source) + public static long ToUnixTimestamp(this DateTime source) { - return (int)(source - new DateTime(1970, 1, 1).ToLocalTime()).TotalSeconds * 1000; + return new DateTimeOffset(source).ToUnixTimeSeconds(); } } } \ No newline at end of file diff --git a/Extenso.Core/StringExtensions.cs b/Extenso.Core/StringExtensions.cs index 68fab93..3a1da54 100644 --- a/Extenso.Core/StringExtensions.cs +++ b/Extenso.Core/StringExtensions.cs @@ -78,6 +78,26 @@ public static bool AreAnyNullOrWhiteSpace(params string[] values) return values.Any(x => string.IsNullOrWhiteSpace(x)); } + /// + /// Decodes the Base64 encoded string to a byte array. + /// + /// The Base64 encoded string to decode. + /// The decoded bytes from the Base64 encoded string. + public static byte[] Base64Deserialize(this string source) + { + // We need to know the exact length of the string - Base64 can sometimes pad us by a byte or two + int lengthDelimiterPosition = source.IndexOf(':'); + + if (lengthDelimiterPosition == -1) + { + return Convert.FromBase64String(source); + } + else + { + return Convert.FromBase64String(source[(lengthDelimiterPosition + 1)..]); + } + } + /// /// Decodes and deserializes the Base64 encoded string to an object of the specified type. /// @@ -97,7 +117,6 @@ public static T Base64Deserialize(this string source) else { int length = int.Parse(source[..lengthDelimiterPosition]); - byte[] bytes = Convert.FromBase64String(source[(lengthDelimiterPosition + 1)..]); using (var memoryStream = new MemoryStream(bytes, 0, length)) { @@ -312,42 +331,40 @@ public static string DeflateDecompress(this string source) } } - /// - /// Encrypts the given string using the specified System.Security.Cryptography.ICryptoTransform and returns - /// the data as a byte array. A parameter specifies the character encoding to use. - /// - /// The string to encrypt. - /// The character encoding to use. - /// The System.Security.Cryptography.ICryptoTransform to use. - /// An encryped string as a byte array. - public static byte[] Encrypt(this string source, Encoding encoding, ICryptoTransform cryptoTransform) - { - using (var memoryStream = new MemoryStream()) - using (var cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write)) - { - byte[] bytes = encoding.GetBytes(source); - - cryptoStream.Write(bytes, 0, bytes.Length); - cryptoStream.FlushFinalBlock(); - - return memoryStream.ToArray(); - } - } + ///// + ///// Encrypts the given string using the specified System.Security.Cryptography.ICryptoTransform and returns + ///// the data as a byte array. A parameter specifies the character encoding to use. + ///// + ///// The string to encrypt. + ///// The character encoding to use. + ///// The System.Security.Cryptography.ICryptoTransform to use. + ///// An encryped string as a byte array. + //public static byte[] Encrypt(this string source, Encoding encoding, ICryptoTransform cryptoTransform) + //{ + // using (var memoryStream = new MemoryStream()) + // using (var cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write)) + // { + // byte[] bytes = encoding.GetBytes(source); + // cryptoStream.Write(bytes, 0, bytes.Length); + // cryptoStream.FlushFinalBlock(); + // return memoryStream.ToArray(); + // } + //} - //TODO: More of these (for each SymmetricAlgorithm)? Will need Decrypt() methods in ByteArrayExtensions as well... - /// - /// Encrypts the given string using the TripleDES symmetric algorithm and returns the data as a byte array. - /// A parameter specifies the character encoding to use. - /// - /// The string to encrypt. - /// The character encoding to use. - /// The secret key to use for the symmetric algorithm. - /// The initialization vector to use for the symmetric algorithm. - /// An encryped string as a byte array. - public static byte[] EncryptTripleDES(this string source, Encoding encoding, byte[] key, byte[] initializationVector) - { - return source.Encrypt(encoding, new TripleDESCryptoServiceProvider().CreateEncryptor(key, initializationVector)); - } + ////TODO: More of these (for each SymmetricAlgorithm)? Will need Decrypt() methods in ByteArrayExtensions as well... + ///// + ///// Encrypts the given string using the TripleDES symmetric algorithm and returns the data as a byte array. + ///// A parameter specifies the character encoding to use. + ///// + ///// The string to encrypt. + ///// The character encoding to use. + ///// The secret key to use for the symmetric algorithm. + ///// The initialization vector to use for the symmetric algorithm. + ///// An encryped string as a byte array. + //public static byte[] EncryptTripleDES(this string source, Encoding encoding, byte[] key, byte[] initializationVector) + //{ + // return source.Encrypt(encoding, TripleDES.Create().CreateEncryptor(key, initializationVector)); + //} /// /// Determines whether the end of the given string matches any of the specified strings. @@ -965,6 +982,7 @@ public static bool StartsWithAny(this string source, params string[] values) /// /// The string to convert to camel case. /// The specified string converted to camel case. + [Obsolete("Use Humanizer instead. https://github.com/Humanizr/Humanizer")] public static string ToCamelCase(this string source) { string pascal = source.ToPascalCase(); @@ -1026,6 +1044,7 @@ public static IEnumerable ToLines(this string source) /// /// The string to convert to pascal case. /// The specified string converted to pascal case. + [Obsolete("Use Humanizer instead. https://github.com/Humanizr/Humanizer")] public static string ToPascalCase(this string source) { return source.ToTitleCase().Replace(" ", string.Empty); @@ -1056,6 +1075,7 @@ public static MemoryStream ToStream(this string source, Encoding encoding = null /// /// The string to convert to title case. /// The specified string converted to title case. + [Obsolete("Use Humanizer instead. https://github.com/Humanizr/Humanizer")] public static string ToTitleCase(this string source) { return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(source); @@ -1068,6 +1088,7 @@ public static string ToTitleCase(this string source) /// The string to convert to title case. /// The System.Globalization.CultureInfo to use for converting to title case. /// The specified string converted to title case. + [Obsolete("Use Humanizer instead. https://github.com/Humanizr/Humanizer")] public static string ToTitleCase(this string source, CultureInfo cultureInfo) { return cultureInfo.TextInfo.ToTitleCase(source); @@ -1177,249 +1198,5 @@ public static object XmlDeserialize(this string source, Type type) reader.Close(); } } - - #region From: WebMatrix.WebData - - // TODO: Think about removing these... - - //public static TValue As(this string source) - //{ - // return source.As(default(TValue)); - //} - - //public static TValue As(this string source, TValue defaultValue) - //{ - // try - // { - // TypeConverter converter = TypeDescriptor.GetConverter(typeof(TValue)); - // if (converter.CanConvertFrom(typeof(string))) - // { - // return (TValue)converter.ConvertFrom(source); - // } - // converter = TypeDescriptor.GetConverter(typeof(string)); - // if (converter.CanConvertTo(typeof(TValue))) - // { - // return (TValue)converter.ConvertTo(source, typeof(TValue)); - // } - // } - // catch - // { - // return defaultValue; - // } - // return defaultValue; - //} - - //public static bool AsBool(this string source) - //{ - // return source.AsBool(false); - //} - - //public static bool AsBool(this string source, bool defaultValue) - //{ - // bool flag; - // if (!bool.TryParse(source, out flag)) - // { - // return defaultValue; - // } - // return flag; - //} - - //public static DateTime AsDateTime(this string source) - //{ - // return source.AsDateTime(new DateTime()); - //} - - //public static DateTime AsDateTime(this string source, DateTime defaultValue) - //{ - // DateTime time; - // if (!DateTime.TryParse(source, out time)) - // { - // return defaultValue; - // } - // return time; - //} - - //public static decimal AsDecimal(this string source) - //{ - // return source.As(); - //} - - //public static decimal AsDecimal(this string source, decimal defaultValue) - //{ - // return source.As(defaultValue); - //} - - //public static float AsFloat(this string value) - //{ - // return value.AsFloat(0f); - //} - - //public static float AsFloat(this string source, float defaultValue) - //{ - // float num; - // if (!float.TryParse(source, out num)) - // { - // return defaultValue; - // } - // return num; - //} - - //public static int AsInt(this string source) - //{ - // return source.AsInt(0); - //} - - //public static int AsInt(this string source, int defaultValue) - //{ - // int num; - // if (!int.TryParse(source, out num)) - // { - // return defaultValue; - // } - // return num; - //} - - //public static bool Is(this string source) - //{ - // TypeConverter converter = TypeDescriptor.GetConverter(typeof(TValue)); - // try - // { - // if ((source == null) || converter.CanConvertFrom(null, source.GetType())) - // { - // converter.ConvertFrom(null, CultureInfo.CurrentCulture, source); - // return true; - // } - // } - // catch - // { - // return false; - // } - // return false; - //} - - //public static bool IsBool(this string source) - //{ - // bool flag; - // return bool.TryParse(source, out flag); - //} - - //public static bool IsDateTime(this string source) - //{ - // DateTime time; - // return DateTime.TryParse(source, out time); - //} - - //public static bool IsDecimal(this string source) - //{ - // return source.Is(); - //} - - //public static bool IsEmpty(this string source) - //{ - // return string.IsNullOrEmpty(source); - //} - - //public static bool IsFloat(this string source) - //{ - // float num; - // return float.TryParse(source, out num); - //} - - //public static bool IsInt(this string source) - //{ - // int num; - // return int.TryParse(source, out num); - //} - - #endregion From: WebMatrix.WebData - - //#region Pluralization - - //private static IDictionary pluralizationServices; - - ///// - ///// Determines whether the specified word is plural. - ///// - ///// The value to be analyzed. - ///// true if the word is plural; otherwise, false. - //public static bool IsPlural(this string word, string cultureCode = "en") - //{ - // var pluralizationService = GetPluralizationService(cultureCode); - // return pluralizationService.IsPlural(word); - //} - - ///// - ///// Determines whether the specified word is singular. - ///// - ///// The value to be analyzed. - ///// true if the word is singular; otherwise, false. - //public static bool IsSingular(this string word, string cultureCode = "en") - //{ - // var pluralizationService = GetPluralizationService(cultureCode); - // return pluralizationService.IsSingular(word); - //} - - ///// - ///// Returns the plural form of the specified word. - ///// - ///// The word to be made plural. - ///// The plural form of the input parameter. - //public static string Pluralize(this string word, string cultureCode = "en") - //{ - // if (string.IsNullOrWhiteSpace(word)) - // { - // return word; - // } - - // if (word.IsSingular()) - // { - // var pluralizationService = GetPluralizationService(cultureCode); - // return pluralizationService.Pluralize(word); - // } - // return word; - //} - - ///// - ///// Returns the singular form of the specified word. - ///// - ///// The word to be made singular. - ///// The singular form of the input parameter. - //public static string Singularize(this string word, string cultureCode = "en") - //{ - // if (string.IsNullOrWhiteSpace(word)) - // { - // return word; - // } - // if (word.IsPlural()) - // { - // var pluralizationService = GetPluralizationService(cultureCode); - // return pluralizationService.Singularize(word); - // } - // return word; - //} - - //private static PluralizationService GetPluralizationService(string cultureCode) - //{ - // if (pluralizationServices == null) - // { - // pluralizationServices = new Dictionary(); - // } - - // if (string.IsNullOrEmpty(cultureCode)) - // { - // cultureCode = "en"; - // } - - // if (!pluralizationServices.ContainsKey(cultureCode)) - // { - // var pluralizationService = PluralizationService.CreateService(new CultureInfo(cultureCode)); - // pluralizationServices.Add(cultureCode, pluralizationService); - // return pluralizationService; - // } - - // return pluralizationServices[cultureCode]; - //} - - //#endregion Pluralization } } \ No newline at end of file diff --git a/Extenso.Core/TimeSpanExtensions.cs b/Extenso.Core/TimeSpanExtensions.cs deleted file mode 100644 index 0e72df4..0000000 --- a/Extenso.Core/TimeSpanExtensions.cs +++ /dev/null @@ -1,161 +0,0 @@ -// 2018.06.24 - Will probably remove this. Commenting out for now, just in case... - -//using System; -//using System.Text; - -//namespace Extenso -//{ -// /// -// /// Provides a set of static methods for querying and manipulating instances of System.TimeSpan -// /// -// public static class TimeSpanExtensions -// { -// /// -// /// -// /// -// /// -// /// -// /// -// public static string ToFormattedEnglish(this TimeSpan source, bool useShorthand) -// { -// if (source == TimeSpan.MaxValue || source == TimeSpan.MinValue) -// { -// return "Unknown"; -// } - -// var sb = new StringBuilder(); - -// if (!useShorthand) -// { -// #region Years & Days - -// if (source.Days == 365 || source.Days == 366) -// { -// sb.Append("1 year, "); -// } -// else if (source.Days > 365) -// { -// sb.Append((source.Days / 365) + " years, "); -// } -// else if (source.Days == 1) -// { -// sb.Append("1 day, "); -// } -// else if (source.Days > 1) -// { -// sb.Append(source.Days + " days, "); -// } - -// #endregion Years & Days - -// #region Hours - -// if (source.Hours == 1) -// { -// sb.Append("1 hour, "); -// } -// else if (source.Hours > 1) -// { -// sb.Append(source.Hours + " hours, "); -// } - -// #endregion Hours - -// #region Minutes - -// if (source.Minutes == 1) -// { -// sb.Append("1 minute, "); -// } -// else if (source.Minutes > 1) -// { -// sb.Append(source.Minutes + " minutes, "); -// } - -// #endregion Minutes - -// #region Seconds - -// if (source.Seconds == 1) -// { -// sb.Append("1 second, "); -// } -// else if (source.Seconds > 1) -// { -// sb.Append(source.Seconds + " seconds, "); -// } - -// #endregion Seconds -// } -// else -// { -// #region Years & Days - -// if (source.Days == 365 || source.Days == 366) -// { -// sb.Append("1yr, "); -// } -// else if (source.Days > 365) -// { -// sb.Append((source.Days / 365) + "yr, "); -// } -// else if (source.Days == 1) -// { -// sb.Append("1d, "); -// } -// else if (source.Days > 1) -// { -// sb.Append(source.Days + "d, "); -// } - -// #endregion Years & Days - -// #region Hours - -// if (source.Hours == 1) -// { -// sb.Append("1h, "); -// } -// else if (source.Hours > 1) -// { -// sb.Append(source.Hours + "h, "); -// } - -// #endregion Hours - -// #region Minutes - -// if (source.Minutes == 1) -// { -// sb.Append("1min, "); -// } -// else if (source.Minutes > 1) -// { -// sb.Append(source.Minutes + "min, "); -// } - -// #endregion Minutes - -// #region Seconds - -// if (source.Seconds == 1) -// { -// sb.Append("1s, "); -// } -// else if (source.Seconds > 1) -// { -// sb.Append(source.Seconds + "s, "); -// } - -// #endregion Seconds -// } - -// if (sb.Length >= 2) -// { -// sb.Remove(sb.Length - 2, 2); -// } - -// return sb.ToString(); -// } -// } -//} \ No newline at end of file diff --git a/Extenso.sln b/Extenso.sln index 927aef7..b083b86 100644 --- a/Extenso.sln +++ b/Extenso.sln @@ -73,6 +73,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Blazor", "Blazor", "{D4F849 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Demo.Data.InfoSchema", "Demos\Demo.Data.InfoSchema\Demo.Data.InfoSchema.csproj", "{5EC0AA10-3440-4D4C-AA9A-F6026FF9D194}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{FB3D4311-3B8D-493A-86A1-E5C3F55C1125}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Extenso.Core.Tests", "Tests\Extenso.Core.Tests\Extenso.Core.Tests.csproj", "{DE671127-522A-4151-942E-4B14E437F6B1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -187,6 +191,10 @@ Global {5EC0AA10-3440-4D4C-AA9A-F6026FF9D194}.Debug|Any CPU.Build.0 = Debug|Any CPU {5EC0AA10-3440-4D4C-AA9A-F6026FF9D194}.Release|Any CPU.ActiveCfg = Release|Any CPU {5EC0AA10-3440-4D4C-AA9A-F6026FF9D194}.Release|Any CPU.Build.0 = Release|Any CPU + {DE671127-522A-4151-942E-4B14E437F6B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE671127-522A-4151-942E-4B14E437F6B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE671127-522A-4151-942E-4B14E437F6B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE671127-522A-4151-942E-4B14E437F6B1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -210,6 +218,7 @@ Global {44A64035-109B-48CC-A11D-25C75BF64C16} = {D4F84964-B7B4-4B1F-9E9B-35DEA0B7F2A8} {D4F84964-B7B4-4B1F-9E9B-35DEA0B7F2A8} = {409B2AA0-96DC-4F56-8187-455594DB6591} {5EC0AA10-3440-4D4C-AA9A-F6026FF9D194} = {5CF10B41-54F9-44DF-9FA0-8A53205C791D} + {DE671127-522A-4151-942E-4B14E437F6B1} = {FB3D4311-3B8D-493A-86A1-E5C3F55C1125} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8BEF57B5-2234-4CCE-876C-951A94822B8C} diff --git a/Tests/Extenso.Core.Tests/ByteArrayExtensionsTests.cs b/Tests/Extenso.Core.Tests/ByteArrayExtensionsTests.cs new file mode 100644 index 0000000..355210b --- /dev/null +++ b/Tests/Extenso.Core.Tests/ByteArrayExtensionsTests.cs @@ -0,0 +1,52 @@ +using System.Text; + +namespace Extenso.Core.Tests +{ + public class ByteArrayExtensionsTests + { + [Fact] + public void Base64Serialize() + { + string source = "the quick brown fox jumped over the lazy dog"; + byte[] bytes = Encoding.UTF8.GetBytes(source); + string base64 = bytes.Base64Serialize(); + + var deserializedBytes = base64.Base64Deserialize(); + string deserializedString = Encoding.UTF8.GetString(deserializedBytes); + + Assert.Equal(source, deserializedString); + } + + [Fact] + public void BinaryDeserialize() + { + var expected = new TestObject + { + Value1 = 1, + Value2 = "Test", + Value3 = 4.5m + }; + var serialized = expected.BinarySerialize(); + var deserialized = serialized.BinaryDeserialize(); + + Assert.Equal(expected, deserialized); + } + + [Fact] + public void XmlDeserialize() + { + var source = new TestObject + { + Value1 = 1, + Value2 = "Test", + Value3 = 4.5m + }; + + var xml = source.XmlSerialize(); + byte[] bytes = Encoding.UTF8.GetBytes(xml); + var deserialized = bytes.XmlDeserialize(Encoding.UTF8); + + Assert.Equal(source, deserialized); + } + } +} \ No newline at end of file diff --git a/Tests/Extenso.Core.Tests/CharExtensionsTests.cs b/Tests/Extenso.Core.Tests/CharExtensionsTests.cs new file mode 100644 index 0000000..0f1e139 --- /dev/null +++ b/Tests/Extenso.Core.Tests/CharExtensionsTests.cs @@ -0,0 +1,13 @@ +namespace Extenso.Core.Tests +{ + public class CharExtensionsTests + { + [Fact] + public void Repeat() + { + string expected = "_____"; + string actual = '_'.Repeat(5); + Assert.Equal(expected, actual); + } + } +} \ No newline at end of file diff --git a/Tests/Extenso.Core.Tests/DateTimeExtensionsTests.cs b/Tests/Extenso.Core.Tests/DateTimeExtensionsTests.cs new file mode 100644 index 0000000..12350d6 --- /dev/null +++ b/Tests/Extenso.Core.Tests/DateTimeExtensionsTests.cs @@ -0,0 +1,63 @@ +namespace Extenso.Core.Tests +{ + public class DateTimeExtensionsTests + { + private static DateTime testDate = new DateTime(2022, 5, 23, 0, 0, 0, DateTimeKind.Utc); + + [Fact] + public void EndOfWeek() + { + var expected = new DateTime(2022, 5, 28); + var actual = testDate.EndOfWeek(); + Assert.Equal(expected, actual); + } + + [Fact] + public void ParseUnixTimestamp() + { + int unixTimestamp = 1653264000; + var result = DateTimeExtensions.ParseUnixTimestamp(unixTimestamp); + Assert.Equal(testDate, result); + } + + [Fact] + public void StartOfMonth() + { + var expected = new DateTime(2022, 5, 1); + var actual = testDate.StartOfMonth(); + Assert.Equal(expected, actual); + } + + [Fact] + public void StartOfWeek() + { + var expected = new DateTime(2022, 5, 22); + var actual = testDate.StartOfWeek(); + Assert.Equal(expected, actual); + } + + [Fact] + public void StartOfYear() + { + var expected = new DateTime(2022, 1, 1); + var actual = testDate.StartOfYear(); + Assert.Equal(expected, actual); + } + + [Fact] + public void ToISO8601DateString() + { + string expected = "2022-05-23T00:00:00.000Z"; + string actual = testDate.ToISO8601DateString(); + Assert.Equal(expected, actual); + } + + [Fact] + public void ToUnixTimestamp() + { + long expected = 1653264000; + long actual = testDate.ToUnixTimestamp(); + Assert.Equal(expected, actual); + } + } +} \ No newline at end of file diff --git a/Tests/Extenso.Core.Tests/DecimalExtensionsTests.cs b/Tests/Extenso.Core.Tests/DecimalExtensionsTests.cs new file mode 100644 index 0000000..fa09fee --- /dev/null +++ b/Tests/Extenso.Core.Tests/DecimalExtensionsTests.cs @@ -0,0 +1,25 @@ +namespace Extenso.Core.Tests +{ + public class DecimalExtensionsTests + { + [Fact] + public void Between_True() + { + decimal source = 33.45m; + int lower = 10; + int higher = 50; + + Assert.True(source.Between(lower, higher)); + } + + [Fact] + public void Between_False() + { + decimal source = 98.67m; + int lower = 10; + int higher = 50; + + Assert.False(source.Between(lower, higher)); + } + } +} \ No newline at end of file diff --git a/Tests/Extenso.Core.Tests/EnumExtensionsTests.cs b/Tests/Extenso.Core.Tests/EnumExtensionsTests.cs new file mode 100644 index 0000000..934dfcc --- /dev/null +++ b/Tests/Extenso.Core.Tests/EnumExtensionsTests.cs @@ -0,0 +1,101 @@ +using System.ComponentModel.DataAnnotations; + +namespace Extenso.Core.Tests +{ + public class EnumExtensionsTests + { + [Fact] + public void GetDisplayName_DisplayAttribute() + { + var source = TestEnum.ValueTwo; + string expected = "2nd Value"; + string actual = EnumExtensions.GetDisplayName(source); + + Assert.Equal(expected, actual); + } + + [Fact] + public void GetDisplayName_NoDisplayAttribute() + { + var source = DayOfWeek.Wednesday; + string expected = "Wednesday"; + string actual = EnumExtensions.GetDisplayName(source); + + Assert.Equal(expected, actual); + } + + [Fact] + public void GetDisplayNames() + { + var expected = new[] { "1st Value", "2nd Value", "3rd Value", "4th Value", "5th Value" }; + var actual = EnumExtensions.GetDisplayNames(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void GetFlags() + { + var flags = TestEnum.ValueOne | TestEnum.ValueThree | TestEnum.ValueFive; + var expected = new[] { TestEnum.ValueOne, TestEnum.ValueThree, TestEnum.ValueFive }; + var actual = EnumExtensions.GetFlags(flags); + + Assert.Equal(expected, actual); + } + + [Fact] + public void GetValues() + { + var expected = new[] { TestEnum.ValueOne, TestEnum.ValueTwo, TestEnum.ValueThree, TestEnum.ValueFour, TestEnum.ValueFive }; + var actual = EnumExtensions.GetValues(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Parse() + { + var expected = TestEnum.ValueFour; + var actual = EnumExtensions.Parse("ValueFour"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ToEnum() + { + var expected = TestEnum.ValueFour; + var actual = "ValueFour".ToEnum(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void TryParse() + { + var expected = TestEnum.ValueFour; + TestEnum actual; + bool succeeded = EnumExtensions.TryParse("ValueFour", out actual); + Assert.True(succeeded && expected == actual); + } + + [Flags] + private enum TestEnum + { + [Display(Name = "1st Value")] + ValueOne = 1, + + [Display(Name = "2nd Value")] + ValueTwo = 2, + + [Display(Name = "3rd Value")] + ValueThree = 4, + + [Display(Name = "4th Value")] + ValueFour = 8, + + [Display(Name = "5th Value")] + ValueFive = 16 + } + } +} \ No newline at end of file diff --git a/Tests/Extenso.Core.Tests/Extenso.Core.Tests.csproj b/Tests/Extenso.Core.Tests/Extenso.Core.Tests.csproj new file mode 100644 index 0000000..811d394 --- /dev/null +++ b/Tests/Extenso.Core.Tests/Extenso.Core.Tests.csproj @@ -0,0 +1,28 @@ + + + + net6.0 + enable + enable + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/Tests/Extenso.Core.Tests/Int32ExtensionsTests.cs b/Tests/Extenso.Core.Tests/Int32ExtensionsTests.cs new file mode 100644 index 0000000..cec39db --- /dev/null +++ b/Tests/Extenso.Core.Tests/Int32ExtensionsTests.cs @@ -0,0 +1,37 @@ +namespace Extenso.Core.Tests +{ + public class Int32ExtensionsTests + { + [Fact] + public void Between_True() + { + int source = 33; + int lower = 10; + int higher = 50; + + Assert.True(source.Between(lower, higher)); + } + + [Fact] + public void Between_False() + { + int source = 98; + int lower = 10; + int higher = 50; + + Assert.False(source.Between(lower, higher)); + } + + [Fact] + public void IsMultipleOf_True() + { + Assert.True(10.IsMultipleOf(2)); + } + + [Fact] + public void IsMultipleOf_False() + { + Assert.False(10.IsMultipleOf(3)); + } + } +} \ No newline at end of file diff --git a/Tests/Extenso.Core.Tests/StringExtensionsTests.cs b/Tests/Extenso.Core.Tests/StringExtensionsTests.cs new file mode 100644 index 0000000..a61d076 --- /dev/null +++ b/Tests/Extenso.Core.Tests/StringExtensionsTests.cs @@ -0,0 +1,655 @@ +namespace Extenso.Core.Tests +{ + public class StringExtensionsTests + { + [Fact] + public void Append_StringValues() + { + string source = "test"; + string[] values = new[] { "_one", "_two" }; + + string expected = "test_one_two"; + string actual = source.Append(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Append_ObjectValues() + { + string source = "test"; + object[] values = new object[] { "_one_", 2 }; + + string expected = "test_one_2"; + string actual = source.Append(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void AreAnyNullOrEmpty_True_Empty() + { + string[] values = new[] { "one", "two", string.Empty, "four" }; + + bool expected = true; + bool actual = StringExtensions.AreAnyNullOrEmpty(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void AreAnyNullOrEmpty_True_Null() + { + string?[] values = new[] { "one", "two", null, "four" }; + + bool expected = true; + bool actual = StringExtensions.AreAnyNullOrEmpty(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void AreAnyNullOrEmpty_False() + { + string[] values = new[] { "one", "two", "three", "four" }; + + bool expected = false; + bool actual = StringExtensions.AreAnyNullOrEmpty(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void AreAnyNullOrWhiteSpace_True_Empty() + { + string[] values = new[] { "one", "two", string.Empty, "four" }; + + bool expected = true; + bool actual = StringExtensions.AreAnyNullOrWhiteSpace(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void AreAnyNullOrWhiteSpace_True_Null() + { + string?[] values = new[] { "one", "two", null, "four" }; + + bool expected = true; + bool actual = StringExtensions.AreAnyNullOrWhiteSpace(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void AreAnyNullOrWhiteSpace_True_WhiteSpace() + { + string[] values = new[] { "one", "two", Environment.NewLine, "four" }; + + bool expected = true; + bool actual = StringExtensions.AreAnyNullOrWhiteSpace(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void AreAnyNullOrWhiteSpace_False() + { + string[] values = new[] { "one", "two", "three", "four" }; + + bool expected = false; + bool actual = StringExtensions.AreAnyNullOrWhiteSpace(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Base64Deserialize_String() + { + string expected = "my test string"; + string encoded = expected.Base64Serialize(); + string actual = encoded.Base64Deserialize(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Base64Deserialize_Object() + { + var expected = new TestObject + { + Value1 = 1, + Value2 = "Test", + Value3 = 4.5m + }; + + string encoded = expected.Base64Serialize(); + var actual = encoded.Base64Deserialize(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Between_DifferentChar() + { + string source = "test_one-test"; + string expected = "one"; + string actual = source.Between('_', '-'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Between_SameChar() + { + string source = "test_one_test"; + string expected = "one"; + string actual = source.Between('_', '_'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void CharacterCount() + { + string source = "some sample string"; + int expected = 3; + int actual = source.CharacterCount('s'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Contains_True() + { + string source = "the QuICk brown fox"; + + bool expected = true; + bool actual = source.Contains("quick", StringComparison.InvariantCultureIgnoreCase); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Contains_False() + { + string source = "the QuICk brown fox"; + + bool expected = false; + bool actual = source.Contains("quack", StringComparison.InvariantCultureIgnoreCase); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAll_Strings_True() + { + string source = "the quick brown fox"; + + bool expected = true; + bool actual = source.ContainsAll("quick", "fox"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAll_Strings_False() + { + string source = "the quick brown fox"; + + bool expected = false; + bool actual = source.ContainsAll("quack", "fox"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAll_Chars_True() + { + string source = "the quick brown fox"; + + bool expected = true; + bool actual = source.ContainsAll('u', 'x'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAll_Chars_False() + { + string source = "the quick brown fox"; + + bool expected = false; + bool actual = source.ContainsAll('a', 'z'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAny_Strings_True() + { + string source = "the quick brown fox"; + + bool expected = true; + bool actual = source.ContainsAny("quick", "quack"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAny_Strings_False() + { + string source = "the quick brown fox"; + + bool expected = false; + bool actual = source.ContainsAny("blue", "green"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAny_Chars_True() + { + string source = "the quick brown fox"; + + bool expected = true; + bool actual = source.ContainsAny('u', 'z'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAny_Chars_False() + { + string source = "the quick brown fox"; + + bool expected = false; + bool actual = source.ContainsAny('a', 'z'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAny_Enumerable_True() + { + string source = "the quick brown fox"; + var values = new List { "quick", "quack" }; + + bool expected = true; + bool actual = source.ContainsAny(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ContainsAny_Enumerable_False() + { + string source = "the quick brown fox"; + var values = new List { "green", "blue" }; + + bool expected = false; + bool actual = source.ContainsAny(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void DeflateCompressAndDecompress() + { + string expected = "the quick brown fox"; + string compressed = expected.DeflateCompress(); + string decompressed = compressed.DeflateDecompress(); + + Assert.Equal(expected, decompressed); + } + + [Fact] + public void EndsWithAny_True() + { + string source = "the quick brown fox"; + + bool expected = true; + bool actual = source.EndsWithAny("fox", "fax"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void EndsWithAny_False() + { + string source = "the quick brown fox"; + + bool expected = false; + bool actual = source.EndsWithAny("quick", "quack"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void GZipCompressAndDecompress() + { + string expected = "the quick brown fox"; + string compressed = expected.GZipCompress(); + string decompressed = compressed.GZipDecompress(); + + Assert.Equal(expected, decompressed); + } + + [Fact] + public void IsRightToLeft_False() + { + string source = "the quick brown fox"; + + bool expected = false; + bool actual = source.IsRightToLeft(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void IsRightToLeft_True() + { + string source = "השועל החום המהיר"; + + bool expected = true; + bool actual = source.IsRightToLeft(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Left() + { + string source = "test_one_two"; + + string expected = "test"; + string actual = source.Left(4); + + Assert.Equal(expected, actual); + } + + [Fact] + public void LeftOf_Char() + { + string source = "test_one_two"; + + string expected = "t"; + string actual = source.LeftOf('e'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void LeftOf_Char_N() + { + string source = "test_one_two"; + + string expected = "test_on"; + string actual = source.LeftOf('e', 2); + + Assert.Equal(expected, actual); + } + + [Fact] + public void LeftOf_String() + { + string source = "test_one_two"; + + string expected = "test_"; + string actual = source.LeftOf("one"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void LeftOfLastIndexOf_Char() + { + string source = "test_one_two"; + + string expected = "test_on"; + string actual = source.LeftOfLastIndexOf('e'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void LeftOfLastIndexOf_String() + { + string source = "test_one_two"; + + string expected = "test_"; + string actual = source.LeftOfLastIndexOf("one"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Prepend_StringValues() + { + string source = "test"; + string[] values = new[] { "one_", "two_" }; + + string expected = "one_two_test"; + string actual = source.Prepend(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Prepend_ObjectValues() + { + string source = "test"; + object[] values = new object[] { 2, "_one_" }; + + string expected = "2_one_test"; + string actual = source.Prepend(values); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Repeat() + { + string value = "="; + + string expected = "====="; + string actual = value.Repeat(5); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Replace() + { + string source = "the quick brown fox jumped over the lazy dog"; + string expected = "the quick brown chicken jumped over the lazy frog"; + + var replacements = new Dictionary + { + { "fox", "chicken" }, + { "dog", "frog" } + }; + + string actual = source.Replace(replacements); + Assert.Equal(expected, actual); + } + + [Fact] + public void Right() + { + string source = "test_one_two"; + string expected = "two"; + string actual = source.Right(3); + + Assert.Equal(expected, actual); + } + + [Fact] + public void RightOf_Char() + { + string source = "test_one_two"; + string expected = "one_two"; + string actual = source.RightOf('_'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void RightOf_Char_N() + { + string source = "test_one_two"; + string expected = "_two"; + string actual = source.RightOf('e', 2); + + Assert.Equal(expected, actual); + } + + [Fact] + public void RightOf_String() + { + string source = "test_one_two"; + string expected = "one_two"; + string actual = source.RightOf("_one"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void RightOfLastIndexOf_Char() + { + string source = "test_one_two"; + string expected = "_two"; + string actual = source.RightOfLastIndexOf('e'); + + Assert.Equal(expected, actual); + } + + [Fact] + public void RightOfLastIndexOf_String() + { + string source = "test_one_two"; + string expected = "one_two"; + string actual = source.RightOfLastIndexOf("_one"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void SafeTrim_Null() + { + string? source = null; + string? expected = null; + string actual = source.SafeTrim(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void SafeTrim_NotNull() + { + string? source = " something "; + string? expected = "something"; + string actual = source.SafeTrim(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void SplitPascal() + { + string source = "SomePascalValue"; + string expected = "Some Pascal Value"; + string actual = source.SplitPascal(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void StartsWithAny_True() + { + string source = "the quick brown fox"; + + bool expected = true; + bool actual = source.StartsWithAny("the", "a "); + + Assert.Equal(expected, actual); + } + + [Fact] + public void StartsWithAny_False() + { + string source = "the quick brown fox"; + + bool expected = false; + bool actual = source.StartsWithAny("foo", "bar"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ToFile() + { + string expected = "Some Text"; + + string tempFileName = Path.GetTempFileName(); + expected.ToFile(tempFileName); + + bool exists = File.Exists(tempFileName); + Assert.True(exists); + + string actual = File.ReadAllText(tempFileName); + Assert.Equal(expected, actual); + } + + [Fact] + public void ToLines() + { + string source = +@"Line 1 +Line 2 +Line 3"; + + var expected = new[] { "Line 1", "Line 2", "Line 3" }; + + var actual = source.ToLines(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void WordCount() + { + string source = "some sample string"; + int expected = 3; + int actual = source.WordCount(); + + Assert.Equal(expected, actual); + } + + [Fact] + public void WordCount_SpecificWord() + { + string source = "the quick brown fox jumped over the lazy dog"; + int expected = 2; + int actual = source.WordCount("the"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void XmlDeserialize() + { + var expected = new TestObject + { + Value1 = 1, + Value2 = "Test", + Value3 = 4.5m + }; + + string xml = expected.XmlSerialize(); + var actual = xml.XmlDeserialize(); + + Assert.Equal(expected, actual); + } + } +} \ No newline at end of file diff --git a/Tests/Extenso.Core.Tests/TestObject.cs b/Tests/Extenso.Core.Tests/TestObject.cs new file mode 100644 index 0000000..5dfe302 --- /dev/null +++ b/Tests/Extenso.Core.Tests/TestObject.cs @@ -0,0 +1,12 @@ +namespace Extenso.Core.Tests +{ + [Serializable] + public struct TestObject + { + public int Value1; + + public string Value2; + + public decimal Value3; + } +} \ No newline at end of file diff --git a/Tests/Extenso.Core.Tests/Usings.cs b/Tests/Extenso.Core.Tests/Usings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/Tests/Extenso.Core.Tests/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file