mirror of https://github.com/SixLabors/ImageSharp
13 changed files with 272 additions and 237 deletions
@ -0,0 +1,98 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="StringExtensionsUnitTests.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Test harness for the string extensions
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Web.UnitTests.Extensions |
||||
|
{ |
||||
|
using System; |
||||
|
using ImageProcessor.Web.Extensions; |
||||
|
using NUnit.Framework; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Test harness for the string extensions
|
||||
|
/// </summary>
|
||||
|
[TestFixture] |
||||
|
public class StringExtensionsUnitTests |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Tests the MD5 fingerprint
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The input value</param>
|
||||
|
/// <param name="expected">The expected output of the hash</param>
|
||||
|
[Test] |
||||
|
[TestCase("test input", "2e7f7a62eabf0993239ca17c78c464d9")] |
||||
|
[TestCase("lorem ipsum dolor", "96ee002fee25e8b675a477c9750fa360")] |
||||
|
[TestCase("LoReM IpSuM DoLoR", "41e201da794c7fbdb8ce5526a71c8c83")] |
||||
|
[TestCase("1234567890", "e15e31c3d8898c92ab172a4311be9e84")] |
||||
|
public void TestToMd5Fingerprint(string input, string expected) |
||||
|
{ |
||||
|
string result = input.ToMD5Fingerprint(); |
||||
|
bool comparison = result.Equals(expected, StringComparison.InvariantCultureIgnoreCase); |
||||
|
Assert.True(comparison); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tests the SHA-1 fingerprint
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The input value</param>
|
||||
|
/// <param name="expected">The expected output of the hash</param>
|
||||
|
[Test] |
||||
|
[TestCase("test input", "49883b34e5a0f48224dd6230f471e9dc1bdbeaf5")] |
||||
|
[TestCase("lorem ipsum dolor", "75899ad8827a32493928903aecd6e931bf36f967")] |
||||
|
[TestCase("LoReM IpSuM DoLoR", "2f44519afae72fc0837b72c6b53cb11338a1f916")] |
||||
|
[TestCase("1234567890", "01b307acba4f54f55aafc33bb06bbbf6ca803e9a")] |
||||
|
public void TestToSHA1Fingerprint(string input, string expected) |
||||
|
{ |
||||
|
string result = input.ToSHA1Fingerprint(); |
||||
|
bool comparison = result.Equals(expected, StringComparison.InvariantCultureIgnoreCase); |
||||
|
Assert.True(comparison); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tests if the value is a valid URI path name. I.E the path part of a uri.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The value to test</param>
|
||||
|
/// <param name="expected">Whether the value is correct</param>
|
||||
|
/// <remarks>
|
||||
|
/// The full RFC3986 does not seem to pass the test with the square brackets
|
||||
|
/// ':' is failing for some reason in VS but not elsewhere. Could be a build issue.
|
||||
|
/// </remarks>
|
||||
|
[Test] |
||||
|
[TestCase("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", true)] |
||||
|
[TestCase("-", true)] |
||||
|
[TestCase(".", true)] |
||||
|
[TestCase("_", true)] |
||||
|
[TestCase("~", true)] |
||||
|
[TestCase(":", true)] |
||||
|
[TestCase("/", true)] |
||||
|
[TestCase("?", true)] |
||||
|
[TestCase("#", false)] |
||||
|
[TestCase("[", false)] |
||||
|
[TestCase("]", false)]
|
||||
|
[TestCase("@", true)] |
||||
|
[TestCase("!", true)] |
||||
|
[TestCase("$", true)] |
||||
|
[TestCase("&", true)] |
||||
|
[TestCase("'", true)] |
||||
|
[TestCase("(", true)] |
||||
|
[TestCase(")", true)] |
||||
|
[TestCase("*", true)] |
||||
|
[TestCase("+", true)] |
||||
|
[TestCase(",", true)] |
||||
|
[TestCase(";", true)] |
||||
|
[TestCase("=", true)] |
||||
|
[TestCase("lorem ipsum", false)] |
||||
|
[TestCase("é", false)] |
||||
|
public void TestIsValidUriPathName(string input, bool expected) |
||||
|
{ |
||||
|
bool result = input.IsValidVirtualPathName(); |
||||
|
Assert.AreEqual(expected, result); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,143 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="StringExtensions.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Encapsulates a series of time saving extension methods to the <see cref="T:System.String" /> class.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Web.Extensions |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Globalization; |
||||
|
using System.Linq; |
||||
|
using System.Security.Cryptography; |
||||
|
using System.Text; |
||||
|
using System.Text.RegularExpressions; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Encapsulates a series of time saving extension methods to the <see cref="T:System.String"/> class.
|
||||
|
/// </summary>
|
||||
|
public static class StringExtensions |
||||
|
{ |
||||
|
#region Cryptography
|
||||
|
/// <summary>
|
||||
|
/// Creates an MD5 fingerprint of the String.
|
||||
|
/// </summary>
|
||||
|
/// <param name="expression">The <see cref="T:System.String">String</see> instance that this method extends.</param>
|
||||
|
/// <returns>An MD5 fingerprint of the String.</returns>
|
||||
|
public static string ToMD5Fingerprint(this string expression) |
||||
|
{ |
||||
|
byte[] bytes = Encoding.Unicode.GetBytes(expression.ToCharArray()); |
||||
|
|
||||
|
using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()) |
||||
|
{ |
||||
|
byte[] hash = md5.ComputeHash(bytes); |
||||
|
|
||||
|
// Concatenate the hash bytes into one long String.
|
||||
|
return hash.Aggregate( |
||||
|
new StringBuilder(32), |
||||
|
(sb, b) => sb.Append(b.ToString("X2", CultureInfo.InvariantCulture))) |
||||
|
.ToString().ToLowerInvariant(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates an SHA1 fingerprint of the String.
|
||||
|
/// </summary>
|
||||
|
/// <param name="expression">The <see cref="T:System.String">String</see> instance that this method extends.</param>
|
||||
|
/// <returns>An SHA1 fingerprint of the String.</returns>
|
||||
|
public static string ToSHA1Fingerprint(this string expression) |
||||
|
{ |
||||
|
byte[] bytes = Encoding.ASCII.GetBytes(expression.ToCharArray()); |
||||
|
|
||||
|
using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) |
||||
|
{ |
||||
|
byte[] hash = sha1.ComputeHash(bytes); |
||||
|
|
||||
|
// Concatenate the hash bytes into one long String.
|
||||
|
return hash.Aggregate( |
||||
|
new StringBuilder(40), |
||||
|
(sb, b) => sb.Append(b.ToString("X2", CultureInfo.InvariantCulture))) |
||||
|
.ToString().ToLowerInvariant(); |
||||
|
} |
||||
|
} |
||||
|
#endregion
|
||||
|
|
||||
|
#region Numbers
|
||||
|
/// <summary>
|
||||
|
/// Creates an array of integers scraped from the String.
|
||||
|
/// </summary>
|
||||
|
/// <param name="expression">The <see cref="T:System.String">String</see> instance that this method extends.</param>
|
||||
|
/// <returns>An array of integers scraped from the String.</returns>
|
||||
|
public static int[] ToPositiveIntegerArray(this string expression) |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(expression)) |
||||
|
{ |
||||
|
throw new ArgumentNullException("expression"); |
||||
|
} |
||||
|
|
||||
|
Regex regex = new Regex(@"[\d+]+(?=[,-])|[\d+]+(?![,-])", RegexOptions.Compiled); |
||||
|
|
||||
|
MatchCollection matchCollection = regex.Matches(expression); |
||||
|
|
||||
|
// Get the collections.
|
||||
|
int count = matchCollection.Count; |
||||
|
int[] matches = new int[count]; |
||||
|
|
||||
|
// Loop and parse the int values.
|
||||
|
for (int i = 0; i < count; i++) |
||||
|
{ |
||||
|
matches[i] = int.Parse(matchCollection[i].Value, CultureInfo.InvariantCulture); |
||||
|
} |
||||
|
|
||||
|
return matches; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates an array of floats scraped from the String.
|
||||
|
/// </summary>
|
||||
|
/// <param name="expression">The <see cref="T:System.String">String</see> instance that this method extends.</param>
|
||||
|
/// <returns>An array of floats scraped from the String.</returns>
|
||||
|
public static float[] ToPositiveFloatArray(this string expression) |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(expression)) |
||||
|
{ |
||||
|
throw new ArgumentNullException("expression"); |
||||
|
} |
||||
|
|
||||
|
Regex regex = new Regex(@"[\d+\.]+(?=[,-])|[\d+\.]+(?![,-])", RegexOptions.Compiled); |
||||
|
|
||||
|
MatchCollection matchCollection = regex.Matches(expression); |
||||
|
|
||||
|
// Get the collections.
|
||||
|
int count = matchCollection.Count; |
||||
|
float[] matches = new float[count]; |
||||
|
|
||||
|
// Loop and parse the int values.
|
||||
|
for (int i = 0; i < count; i++) |
||||
|
{ |
||||
|
matches[i] = float.Parse(matchCollection[i].Value, CultureInfo.InvariantCulture); |
||||
|
} |
||||
|
|
||||
|
return matches; |
||||
|
} |
||||
|
#endregion
|
||||
|
|
||||
|
#region Files and Paths
|
||||
|
/// <summary>
|
||||
|
/// Checks the string to see whether the value is a valid virtual path name.
|
||||
|
/// </summary>
|
||||
|
/// <param name="expression">The <see cref="T:System.String">String</see> instance that this method extends.</param>
|
||||
|
/// <returns>True if the given string is a valid virtual path name</returns>
|
||||
|
public static bool IsValidVirtualPathName(this string expression) |
||||
|
{ |
||||
|
Uri uri; |
||||
|
|
||||
|
return Uri.TryCreate(expression, UriKind.Relative, out uri) && uri.IsWellFormedOriginalString(); |
||||
|
} |
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue