From 4e702c7c79d0f0a660fdd81ecf1648376b628438 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 20 Apr 2016 15:09:41 +0200 Subject: [PATCH] Fixing tests - kill KegacyShortStringHelper --- .../Strings/LegacyShortStringHelper.cs | 531 ------------------ src/Umbraco.Core/Umbraco.Core.csproj | 1 - .../Routing/RenderRouteHandlerTests.cs | 2 +- .../Strings/CmsHelperCasingTests.cs | 13 - .../Strings/LegacyShortStringHelperTests.cs | 358 ------------ .../Strings/LegacyStringExtensionsTests.cs | 181 ------ src/Umbraco.Tests/Umbraco.Tests.csproj | 2 - 7 files changed, 1 insertion(+), 1087 deletions(-) delete mode 100644 src/Umbraco.Core/Strings/LegacyShortStringHelper.cs delete mode 100644 src/Umbraco.Tests/Strings/LegacyShortStringHelperTests.cs delete mode 100644 src/Umbraco.Tests/Strings/LegacyStringExtensionsTests.cs diff --git a/src/Umbraco.Core/Strings/LegacyShortStringHelper.cs b/src/Umbraco.Core/Strings/LegacyShortStringHelper.cs deleted file mode 100644 index 901c9ee299..0000000000 --- a/src/Umbraco.Core/Strings/LegacyShortStringHelper.cs +++ /dev/null @@ -1,531 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml; -using Umbraco.Core.Configuration; - -namespace Umbraco.Core.Strings -{ - /// - /// Legacy implementation of string functions for short strings such as aliases or url segments. - /// - /// - /// Not necessarily optimized to work on large bodies of text. - /// Can expose surprising or bogus behavior. - /// Uses invariant culture everywhere. - /// - internal class LegacyShortStringHelper : IShortStringHelper - { - #region Ctor and vars - - /// - /// Freezes the helper so it can prevents its configuration from being modified. - /// - /// Will be called by ShortStringHelperResolver when resolution freezes. - public void Freeze() - { - // we have nothing to protect. - } - - const string UmbracoValidAliasCharacters = "_-abcdefghijklmnopqrstuvwxyz1234567890"; - const string UmbracoInvalidFirstCharacters = "0123456789"; - - #endregion - - #region Short string services JavaScript - - const string SssjsValidCharacters = "_-abcdefghijklmnopqrstuvwxyz1234567890"; - const string SssjsInvalidFirstCharacters = "0123456789"; - - private const string SssjsFormat = @" -var UMBRACO_FORCE_SAFE_ALIAS = {0}; -var UMBRACO_FORCE_SAFE_ALIAS_VALIDCHARS = '{1}'; -var UMBRACO_FORCE_SAFE_ALIAS_INVALID_FIRST_CHARS = '{2}'; - -function safeAlias(alias) {{ - if (UMBRACO_FORCE_SAFE_ALIAS) {{ - var safeAlias = ''; - var aliasLength = alias.length; - for (var i = 0; i < aliasLength; i++) {{ - currentChar = alias.substring(i, i + 1); - if (UMBRACO_FORCE_SAFE_ALIAS_VALIDCHARS.indexOf(currentChar.toLowerCase()) > -1) {{ - // check for camel (if previous character is a space, we'll upper case the current one - if (safeAlias == '' && UMBRACO_FORCE_SAFE_ALIAS_INVALID_FIRST_CHARS.indexOf(currentChar.toLowerCase()) > 0) {{ - currentChar = ''; - }} else {{ - // first char should always be lowercase (camel style) - if (safeAlias.length == 0) - currentChar = currentChar.toLowerCase(); - - if (i < aliasLength - 1 && safeAlias != '' && alias.substring(i - 1, i) == ' ') - currentChar = currentChar.toUpperCase(); - - safeAlias += currentChar; - }} - }} - }} - - alias = safeAlias; - }} - return alias; -}} - -function getSafeAlias(input, value, immediate, callback) {{ - callback(safeAlias(value)); -}} - -function validateSafeAlias(input, value, immediate, callback) {{ - callback(value == safeAlias(value)); -}} - -// legacy backward compatibility requires that one -function isValidAlias(alias) {{ - return alias == safeAlias(alias); -}} -"; - - /// - /// Gets the JavaScript code defining client-side short string services. - /// - public string GetShortStringServicesJavaScript(string controllerPath) - { - return string.Format(SssjsFormat, - UmbracoConfig.For.UmbracoSettings().Content.ForceSafeAliases ? "true" : "false", SssjsValidCharacters, SssjsInvalidFirstCharacters); - } - - #endregion - - #region IShortStringHelper CleanFor... - - /// - /// Cleans a string to produce a string that can safely be used in an alias. - /// - /// The text to filter. - /// The safe alias. - /// The string will be cleaned in the context of invariant culture. - public string CleanStringForSafeAlias(string text) - { - // ported from StringExtensions.ToSafeAlias() - - const string validAliasCharacters = UmbracoValidAliasCharacters; - const string invalidFirstCharacters = UmbracoInvalidFirstCharacters; - var safeString = new StringBuilder(); - int aliasLength = text.Length; - for (var i = 0; i < aliasLength; i++) - { - var currentChar = text.Substring(i, 1); - if (validAliasCharacters.Contains(currentChar.ToLowerInvariant())) - { - // check for camel (if previous character is a space, we'll upper case the current one - if (safeString.Length == 0 && invalidFirstCharacters.Contains(currentChar.ToLowerInvariant())) - { - //currentChar = ""; - } - else - { - if (i < aliasLength - 1 && i > 0 && text.Substring(i - 1, 1) == " ") - currentChar = currentChar.ToUpperInvariant(); - - safeString.Append(currentChar); - } - } - } - - return safeString.ToString(); - } - - /// - /// Cleans a string, in the context of the invariant culture, to produce a string that can safely be used in an alias. - /// - /// The text to filter. - /// The culture. - /// The safe alias. - /// Legacy does not support culture contexts. - public string CleanStringForSafeAlias(string text, CultureInfo culture) - { - return CleanStringForSafeAlias(text); - } - - /// - /// Cleans a string to produce a string that can safely be used in an url segment, in the context of the invariant culture. - /// - /// The text to filter. - /// The safe url segment. - public string CleanStringForUrlSegment(string text) - { - return LegacyFormatUrl(text); - } - - /// - /// Cleans a string, in the context of the invariant culture, to produce a string that can safely be used in an url segment. - /// - /// The text to filter. - /// The culture. - /// The safe url segment. - /// Legacy does not support culture contexts. - public string CleanStringForUrlSegment(string text, CultureInfo culture) - { - return CleanStringForUrlSegment(text); - } - - /// - /// Cleans a string, in the context of the invariant culture, to produce a string that can safely be used as a filename, - /// both internally (on disk) and externally (as a url). - /// - /// The text to filter. - /// The safe filename. - /// Legacy says this was used to "overcome an issue when Umbraco is used in IE in an intranet environment" but that issue is not documented. - public string CleanStringForSafeFileName(string text) - { - var filePath = text; - - // ported from Core.IO.IOHelper.SafeFileName() - - if (String.IsNullOrEmpty(filePath)) - return String.Empty; - - if (!String.IsNullOrWhiteSpace(filePath)) - { - foreach (var character in Path.GetInvalidFileNameChars()) - { - filePath = filePath.Replace(character, '-'); - } - } - else - { - filePath = String.Empty; - } - - //Break up the file in name and extension before applying the UrlReplaceCharacters - var fileNamePart = filePath.Substring(0, filePath.LastIndexOf('.')); - var ext = filePath.Substring(filePath.LastIndexOf('.')); - - //Because the file usually is downloadable as well we check characters against 'UmbracoSettings.UrlReplaceCharacters' - foreach (var n in UmbracoConfig.For.UmbracoSettings().RequestHandler.CharCollection) - { - if (n.Char.IsNullOrWhiteSpace() == false) - fileNamePart = fileNamePart.Replace(n.Char, n.Replacement); - } - - filePath = string.Concat(fileNamePart, ext); - - // Adapted from: http://stackoverflow.com/a/4827510/5018 - // Combined both Reserved Characters and Character Data - // from http://en.wikipedia.org/wiki/Percent-encoding - var stringBuilder = new StringBuilder(); - - const string reservedCharacters = "!*'();:@&=+$,/?%#[]-~{}\"<>\\^`| "; - - foreach (var character in filePath) - { - if (reservedCharacters.IndexOf(character) == -1) - stringBuilder.Append(character); - else - stringBuilder.Append("-"); - } - - // Remove repeating dashes - // From: http://stackoverflow.com/questions/5111967/regex-to-remove-a-specific-repeated-character - var reducedString = Regex.Replace(stringBuilder.ToString(), "-+", "-"); - - return reducedString; - } - - /// - /// Cleans a string, in the context of the invariant culture, to produce a string that can safely be used as a filename, - /// both internally (on disk) and externally (as a url). - /// - /// The text to filter. - /// The culture. - /// The safe filename. - /// Legacy does not support culture contexts. - public string CleanStringForSafeFileName(string text, CultureInfo culture) - { - return CleanStringForSafeFileName(text); - } - - #endregion - - #region CleanString - - // legacy does not implement these - - public string CleanString(string text, CleanStringType stringType) - { - return text; - } - - public string CleanString(string text, CleanStringType stringType, char separator) - { - return text; - } - - public string CleanString(string text, CleanStringType stringType, CultureInfo culture) - { - return text; - } - - public string CleanString(string text, CleanStringType stringType, char separator, CultureInfo culture) - { - return text; - } - - #endregion - - #region SplitPascalCasing - - /// - /// Splits a pascal-cased string by inserting a separator in between each term. - /// - /// The text to split. - /// The separator. - /// The splitted string. - /// Probably only supports Ascii strings. - public string SplitPascalCasing(string text, char separator) - { - // ported from StringExtensions.SplitPascalCasing() - - var replacement = "$1" + separator; - var result = Regex.Replace(text, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", replacement); - return result; - } - - #endregion - - #region Legacy - - /// - /// Cleans a string to produce a string that can safely be used in an alias. - /// - /// The text to filter. - /// The safe alias. - /// The string will be cleaned in the context of invariant culture. - public string LegacyCleanStringForUmbracoAlias(string text) - { - // ported from StringExtensions.ToUmbracoAlias() - // kept here for reference, not used anymore - - if (string.IsNullOrEmpty(text)) return string.Empty; - - //convert case first - //var tmp = text.ConvertCase(caseType); - // note: always Camel anyway - var tmp = LegacyConvertStringCase(text, CleanStringType.CamelCase); - - //remove non-alphanumeric chars - var result = Regex.Replace(tmp, @"[^a-zA-Z0-9\s\.-]+", "", RegexOptions.Compiled); - - // note: spaces are always removed anyway - //if (removeSpaces) - // result = result.Replace(" ", ""); - - return result; - } - - /// - /// Filters a string to convert case, and more. - /// - /// the text to filter. - /// The string case type. - /// The filtered text. - /// - /// This is the legacy method, so we can't really change it, although it has issues (see unit tests). - /// It does more than "converting the case", and also remove spaces, etc. - /// - public string LegacyConvertStringCase(string phrase, CleanStringType cases) - { - // ported from StringExtensions.ConvertCase - - cases &= CleanStringType.CaseMask; - - var splittedPhrase = Regex.Split(phrase, @"[^a-zA-Z0-9\']", RegexOptions.Compiled); - - if (cases == CleanStringType.Unchanged) - return string.Join("", splittedPhrase); - - //var splittedPhrase = phrase.Split(' ', '-', '.'); - var sb = new StringBuilder(); - - foreach (var splittedPhraseChars in splittedPhrase.Select(s => s.ToCharArray())) - { - if (splittedPhraseChars.Length > 0) - { - splittedPhraseChars[0] = ((new String(splittedPhraseChars[0], 1)).ToUpperInvariant().ToCharArray())[0]; - } - sb.Append(new String(splittedPhraseChars)); - } - - var result = sb.ToString(); - - if (cases == CleanStringType.CamelCase) - { - if (result.Length > 1) - { - var pattern = new Regex("^([A-Z]*)([A-Z].*)$", RegexOptions.Singleline | RegexOptions.Compiled); - var match = pattern.Match(result); - if (match.Success) - { - result = match.Groups[1].Value.ToLowerInvariant() + match.Groups[2].Value; - - return result.Substring(0, 1).ToLowerInvariant() + result.Substring(1); - } - - return result; - } - - return result.ToLowerInvariant(); - } - - return result; - } - - /// - /// Converts string to a URL alias. - /// - /// The value. - /// The char replacements. - /// if set to true replace double dashes. - /// if set to true strip non ASCII. - /// if set to true URL encode. - /// - /// - /// This ensures that ONLY ascii chars are allowed and of those ascii chars, only digits and lowercase chars, all - /// punctuation, etc... are stripped out, however this method allows you to pass in string's to replace with the - /// specified replacement character before the string is converted to ascii and it has invalid characters stripped out. - /// This allows you to replace strings like & , etc.. with your replacement character before the automatic - /// reduction. - /// - public string LegacyToUrlAlias(string value, IDictionary charReplacements, bool replaceDoubleDashes, bool stripNonAscii, bool urlEncode) - { - // to lower case invariant - // replace chars one by one using charReplacements - // (opt) convert to ASCII then remove anything that's not ASCII - // trim - and _ then (opt) remove double - - // (opt) url-encode - - // charReplacement is actually *string* replacement ie it can replace " " by a non-breaking space - // so it's kind of a pre-filter actually... - // we need pre-filters, and post-filters, within each token... - // not so... we may want to replace   with a space BEFORE cutting into tokens... - - //first to lower case - value = value.ToLowerInvariant(); - - //then replacement chars - value = charReplacements.Aggregate(value, (current, kvp) => current.Replace(kvp.Key, kvp.Value)); - - //then convert to only ascii, this will remove the rest of any invalid chars - if (stripNonAscii) - { - value = Encoding.ASCII.GetString( - Encoding.Convert( - Encoding.UTF8, - Encoding.GetEncoding( - Encoding.ASCII.EncodingName, - new EncoderReplacementFallback(String.Empty), - new DecoderExceptionFallback()), - Encoding.UTF8.GetBytes(value))); - - //remove all characters that do not fall into the following categories (apart from the replacement val) - var validCodeRanges = - //digits - Enumerable.Range(48, 10).Concat( - //lowercase chars - Enumerable.Range(97, 26)); - - var sb = new StringBuilder(); - foreach (var c in value.Where(c => charReplacements.Values.Contains(c.ToString(CultureInfo.InvariantCulture)) || validCodeRanges.Contains(c))) - { - sb.Append(c); - } - - value = sb.ToString(); - } - - //trim dashes from end - value = value.Trim('-', '_'); - - //replace double occurances of - or _ - value = replaceDoubleDashes ? Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled) : value; - - //url encode result - return urlEncode ? System.Web.HttpUtility.UrlEncode(value) : value; - } - - /// - /// Cleans a string to produce a string that can safely be used in an url segment. - /// - /// The text to filter. - /// The safe url segment. - /// - /// Uses UmbracoSettings.UrlReplaceCharacters - /// and UmbracoSettings.RemoveDoubleDashesFromUrlReplacing. - /// - public string LegacyFormatUrl(string url) - { - var newUrl = url.ToLowerInvariant(); - foreach (var n in UmbracoConfig.For.UmbracoSettings().RequestHandler.CharCollection) - { - if (n.Char != "") - newUrl = newUrl.Replace(n.Char, n.Replacement); - } - - // check for double dashes - if (UmbracoConfig.For.UmbracoSettings().RequestHandler.RemoveDoubleDashes) - { - newUrl = Regex.Replace(newUrl, @"[-]{2,}", "-"); - } - - return newUrl; - } - - #endregion - - #region ReplaceMany - - /// - /// Returns a new string in which all occurences of specified strings are replaced by other specified strings. - /// - /// The string to filter. - /// The replacements definition. - /// The filtered string. - public string ReplaceMany(string text, IDictionary replacements) - { - // Have done various tests, implementing my own "super fast" state machine to handle - // replacement of many items, or via regexes, but on short strings and not too - // many replacements (which prob. is going to be our case) nothing can beat this... - // (at least with safe and checked code -- we don't want unsafe/unchecked here) - - // Note that it will do chained-replacements ie replaced items can be replaced - // in turn by another replacement (ie the order of replacements is important) - - return replacements.Aggregate(text, (current, kvp) => current.Replace(kvp.Key, kvp.Value)); - } - - /// - /// Returns a new string in which all occurences of specified characters are replaced by a specified character. - /// - /// The string to filter. - /// The characters to replace. - /// The replacement character. - /// The filtered string. - public string ReplaceMany(string text, char[] chars, char replacement) - { - // be safe - if (text == null) - throw new ArgumentNullException("text"); - if (chars == null) - throw new ArgumentNullException("chars"); - - // see note above - - return chars.Aggregate(text, (current, c) => current.Replace(c, replacement)); - } - - #endregion - } -} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index e699a351a5..57c9263ea7 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1300,7 +1300,6 @@ - diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index 8faa22ae25..4b750b6894 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -46,7 +46,7 @@ namespace Umbraco.Tests.Routing UmbracoApiControllerResolver.Current = new UmbracoApiControllerResolver( new ActivatorServiceProvider(), Logger, PluginManager.Current.ResolveUmbracoApiControllers()); - ShortStringHelperResolver.Current = new ShortStringHelperResolver(new LegacyShortStringHelper()); + ShortStringHelperResolver.Current = new ShortStringHelperResolver(new DefaultShortStringHelper(SettingsForTests.GetDefault())); base.FreezeResolution(); } diff --git a/src/Umbraco.Tests/Strings/CmsHelperCasingTests.cs b/src/Umbraco.Tests/Strings/CmsHelperCasingTests.cs index 77682661b2..dc39650baa 100644 --- a/src/Umbraco.Tests/Strings/CmsHelperCasingTests.cs +++ b/src/Umbraco.Tests/Strings/CmsHelperCasingTests.cs @@ -30,19 +30,6 @@ namespace Umbraco.Tests.Strings Assert.AreEqual(expected, output); } - [TestCase("thisIsTheEnd", "This Is The End")] - [TestCase("th", "Th")] - [TestCase("t", "t")] - [TestCase("thisis", "Thisis")] - [TestCase("ThisIsTheEnd", "This Is The End")] - [TestCase("WhoIsNumber6InTheVillage", "Who Is Number6In The Village")] // we're happy to reproduce the issue - public void CompatibleLegacyReplacement(string input, string expected) - { - var helper = new LegacyShortStringHelper(); - var output = input.Length < 2 ? input : helper.SplitPascalCasing(input, ' ').ToFirstUpperInvariant(); - Assert.AreEqual(expected, output); - } - [TestCase("thisIsTheEnd", "This Is The End")] [TestCase("th", "Th")] [TestCase("t", "t")] diff --git a/src/Umbraco.Tests/Strings/LegacyShortStringHelperTests.cs b/src/Umbraco.Tests/Strings/LegacyShortStringHelperTests.cs deleted file mode 100644 index 073b7add49..0000000000 --- a/src/Umbraco.Tests/Strings/LegacyShortStringHelperTests.cs +++ /dev/null @@ -1,358 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using Umbraco.Core.Strings; -using Umbraco.Tests.TestHelpers; - -namespace Umbraco.Tests.Strings -{ - [TestFixture] - public class LegacyShortStringHelperTests - { - private LegacyShortStringHelper _helper; - - [SetUp] - public void Setup() - { - var config = SettingsForTests.GetDefault(); - SettingsForTests.ConfigureSettings(config); - _helper = new LegacyShortStringHelper(); - } - - [TearDown] - public void TearDown() - { - } - - - #region Cases - [TestCase("foo", "foo")] - [TestCase(" foo ", "Foo")] - [TestCase("Foo", "Foo")] - [TestCase("FoO", "FoO")] - [TestCase("FoO bar", "FoOBar")] - [TestCase("FoO bar NIL", "FoOBarNIL")] - [TestCase("FoO 33bar 22NIL", "FoO33bar22NIL")] - [TestCase("FoO 33bar 22NI", "FoO33bar22NI")] - [TestCase("0foo", "foo")] - [TestCase("2foo bar", "fooBar")] - [TestCase("9FOO", "FOO")] - [TestCase("foo-BAR", "foo-BAR")] - [TestCase("foo-BA-dang", "foo-BA-dang")] - [TestCase("foo_BAR", "foo_BAR")] - [TestCase("foo'BAR", "fooBAR")] - [TestCase("sauté dans l'espace", "sauteDansLespace", IgnoreReason = "non-supported non-ascii chars")] - [TestCase("foo\"\"bar", "foobar")] - [TestCase("-foo-", "-foo-")] - [TestCase("_foo_", "_foo_")] - [TestCase("spécial", "special", IgnoreReason = "non-supported non-ascii chars")] - [TestCase("brô dëk ", "broDek", IgnoreReason = "non-supported non-ascii chars")] - [TestCase("1235brô dëk ", "broDek", IgnoreReason = "non-supported non-ascii chars")] - [TestCase("汉#字*/漢?字", "")] - [TestCase("aa DB cd EFG X KLMN OP qrst", "aaDBCdEFGXKLMNOPQrst")] - [TestCase("AA db cd EFG X KLMN OP qrst", "AADbCdEFGXKLMNOPQrst")] - [TestCase("AAA db cd EFG X KLMN OP qrst", "AAADbCdEFGXKLMNOPQrst")] - [TestCase("4 ways selector", "WaysSelector")] - [TestCase("WhatIfWeDoItAgain", "WhatIfWeDoItAgain")] - [TestCase("whatIfWeDoItAgain", "whatIfWeDoItAgain")] - [TestCase("WhatIfWEDOITAgain", "WhatIfWEDOITAgain")] - [TestCase("WhatIfWe doItAgain", "WhatIfWeDoItAgain")] - #endregion - public void CleanStringForSafeAlias(string input, string expected) - { - // NOTE legacy CleanStringForSafeAlias has issues w/some cases - // -> ignore test cases - // also, some aliases are strange... how can "-foo-" be a valid alias? - var output = _helper.CleanStringForSafeAlias(input); - Assert.AreEqual(expected, output); - } - - #region Cases - [TestCase("Tab 1", "tab1")] - [TestCase("Home - Page", "homePage")] - [TestCase("Home.Page", "homePage")] - [TestCase("Shannon's Document Type", "shannonsDocumentType")] // look, lowercase s and the end of shannons - [TestCase("!BADDLY nam-ed Document Type", "baddlyNamEdDocumentType")] - [TestCase("i %Want!thisTo end up In Proper@case", "iWantThisToEndUpInProperCase")] - [TestCase("Räksmörgås %%$£¤¤¤§ kéKé", "raksmorgasKeKe", IgnoreReason = "non-supported non-ascii chars")] - [TestCase("TRii", "tRii")] - [TestCase("**TRii", "tRii")] - [TestCase("trII", "trII")] - [TestCase("**trII", "trII")] - [TestCase("trIIX", "trIIX")] - [TestCase("**trIIX", "trIIX")] - #endregion - public void LegacyCleanStringForUmbracoAlias(string input, string expected) - { - // NOTE ToUmbracoAlias has issues w/non-ascii, and a few other things - // -> ignore test cases - // also all those tests should, in theory, fail because removeSpaces is false by default - var output = _helper.LegacyCleanStringForUmbracoAlias(input); - Assert.AreEqual(expected, output); - } - - #region Cases - [TestCase("Home Page", "home-page")] - [TestCase("Shannon's Home Page!", "shannons-home-page!")] - [TestCase("#Someones's Twitter $h1z%n", "someoness-twitter-$h1zn")] - [TestCase("Räksmörgås", "raeksmoergaas")] - [TestCase("'em guys-over there, are#goin' a \"little\"bit crazy eh!! :)", "em-guys-over-there,-aregoin-a-littlebit-crazy-eh!!-)")] - [TestCase("汉#字*/漢?字", "汉字star漢字")] - [TestCase("Réalösk fix bran#lo'sk", "realosk-fix-bran-lo-sk", IgnoreReason = "cannot handle it")] - #endregion - public void LegacyFormatUrl(string input, string expected) - { - // NOTE CleanStringForUrlSegment has issues with a few cases - // -> ignore test cases - // also some results are a bit strange... - var output = _helper.LegacyFormatUrl(input); - Assert.AreEqual(expected, output); - - // NOTE: not testing the overload with culture - // in legacy, they are the same - } - - #region Cases - [TestCase("Home Page", "home-page", true, true, false)] - [TestCase("Shannon's Home Page!", "shannons-home-page", true, true, false)] - [TestCase("#Someones's Twitter $h1z%n", "someoness-twitter-h1zn", true, true, false)] - [TestCase("Räksmörgås", "rksmrgs", true, true, false)] - [TestCase("'em guys-over there, are#goin' a \"little\"bit crazy eh!! :)", "em-guys-over-there-aregoin-a-littlebit-crazy-eh", true, true, false)] - [TestCase("汉#字*/漢?字", "", true, true, false)] - [TestCase("汉#字*/漢?字", "汉字漢字", true, false, false)] - [TestCase("汉#字*/漢?字", "%e6%b1%89%e5%ad%97%e6%bc%a2%e5%ad%97", true, false, true)] - [TestCase("Réalösk fix bran#lo'sk", "realosk-fix-bran-lo-sk", true, true, false, IgnoreReason = "cannot handle it")] - #endregion - public void LegacyToUrlAlias(string input, string expected, bool replaceDoubleDashes, bool stripNonAscii, bool urlEncode) - { - var replacements = new Dictionary - { - {" ", "-"}, - {"\"", ""}, - {""", ""}, - {"@", ""}, - {"%", ""}, - {".", ""}, - {";", ""}, - {"/", ""}, - {":", ""}, - {"#", ""}, - {"+", ""}, - {"*", ""}, - {"&", ""}, - {"?", ""} - }; - - // NOTE CleanStringForUrlSegment has issues with a few cases - // -> ignore test cases - // also some results are a bit strange... - var output = _helper.LegacyToUrlAlias(input, replacements, replaceDoubleDashes, stripNonAscii, urlEncode); - Assert.AreEqual(expected, output); - - // NOTE: not testing the overload with culture - // in legacy, they are the same - } - - #region Cases - [TestCase("Tab 1", "tab1", CleanStringType.CamelCase)] - [TestCase("Home - Page", "homePage", CleanStringType.CamelCase)] - [TestCase("Shannon's document type", "shannon'sDocumentType", CleanStringType.CamelCase)] - [TestCase("This is the FIRSTTIME of TheDay.", "ThisistheFIRSTTIMEofTheDay", CleanStringType.Unchanged)] - [TestCase("Sépàyô lüx.", "Sepayolux", CleanStringType.Unchanged, IgnoreReason = "non-supported non-ascii chars")] - [TestCase("This is the FIRSTTIME of TheDay.", "ThisIsTheFIRSTTIMEOfTheDay", CleanStringType.PascalCase)] - [TestCase("This is the FIRSTTIME of TheDay.", "thisIsTheFIRSTTIMEOfTheDay", CleanStringType.CamelCase)] - #endregion - public void LegacyConvertStringCase(string input, string expected, CleanStringType caseType) - { - // NOTE LegacyConvertStringCase has issues with a few cases - // -> ignore test cases - // also it removes symbols, etc... except the quote? - var output = _helper.LegacyConvertStringCase(input, caseType); - Assert.AreEqual(expected, output); - } - - #region Cases - [TestCase("ThisIsTheEndMyFriend", "This Is The End My Friend")] - [TestCase("ThisIsTHEEndMyFriend", "This Is THE End My Friend")] - [TestCase("THISIsTHEEndMyFriend", "THIS Is THE End My Friend")] - [TestCase("This33I33sThe33EndMyFriend", "This33 I33s The33 End My Friend", IgnoreReason = "fails")] - [TestCase("ThisIsTHEEndMyFriendX", "This Is THE End My Friend X")] - [TestCase("ThisIsTHEEndMyFriendXYZ", "This Is THE End My Friend XYZ")] - [TestCase("ThisIsTHEEndMyFriendXYZt", "This Is THE End My Friend XY Zt")] - [TestCase("UneÉlévationÀPartir", "Une Élévation À Partir", IgnoreReason = "non-supported non-ascii chars")] - #endregion - public void SplitPascalCasing(string input, string expected) - { - // NOTE legacy SplitPascalCasing has issues w/some cases - // -> ignore test cases - var output = _helper.SplitPascalCasing(input, ' '); - Assert.AreEqual(expected, output); - } - - #region Cases - [TestCase("foo", "foo")] - [TestCase(" foo ", "foo")] - [TestCase("Foo", "foo")] - [TestCase("FoO", "foO")] - [TestCase("FoO bar", "foOBar")] - [TestCase("FoO bar NIL", "foOBarNil")] - [TestCase("FoO 33bar 22NIL", "foO33bar22Nil")] - [TestCase("FoO 33bar 22NI", "foO33bar22NI")] - [TestCase("0foo", "foo")] - [TestCase("2foo bar", "fooBar")] - [TestCase("9FOO", "foo")] - [TestCase("foo-BAR", "fooBar")] - [TestCase("foo-BA-dang", "fooBADang")] - [TestCase("foo_BAR", "fooBar")] - [TestCase("foo'BAR", "fooBar")] - [TestCase("sauté dans l'espace", "sauteDansLEspace")] - [TestCase("foo\"\"bar", "fooBar")] - [TestCase("-foo-", "foo")] - [TestCase("_foo_", "foo")] - [TestCase("spécial", "special")] - [TestCase("brô dëk ", "broDek")] - [TestCase("1235brô dëk ", "broDek")] - [TestCase("汉#字*/漢?字", "")] - [TestCase("aa DB cd EFG X KLMN OP qrst", "aaDBCdEfgXKlmnOPQrst")] - [TestCase("AA db cd EFG X KLMN OP qrst", "aaDbCdEfgXKlmnOPQrst")] - [TestCase("AAA db cd EFG X KLMN OP qrst", "aaaDbCdEfgXKlmnOPQrst")] - #endregion - public void CleanStringToAscii(string input, string expected) - { - var output = _helper.CleanString(input, CleanStringType.Ascii | CleanStringType.CamelCase); - // legacy does nothing - Assert.AreEqual(input, output); - } - - #region Cases - [TestCase("1235brô dëK tzARlan ban123!pOo", "brodeKtzARlanban123pOo", CleanStringType.Unchanged)] - [TestCase(" 1235brô dëK tzARlan ban123!pOo ", "brodeKtzARlanban123pOo", CleanStringType.Unchanged)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "BroDeKTzARLanBan123POo", CleanStringType.PascalCase)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "broDeKTzARLanBan123POo", CleanStringType.CamelCase)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "BRODEKTZARLANBAN123POO", CleanStringType.UpperCase)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "brodektzarlanban123poo", CleanStringType.LowerCase)] - [TestCase("aa DB cd EFG X KLMN OP qrst", "aaDBCdEfgXKlmnOPQrst", CleanStringType.CamelCase)] - [TestCase("aaa DB cd EFG X KLMN OP qrst", "aaaDBCdEfgXKlmnOPQrst", CleanStringType.CamelCase)] - [TestCase("aa DB cd EFG X KLMN OP qrst", "AaDBCdEfgXKlmnOPQrst", CleanStringType.PascalCase)] - [TestCase("aaa DB cd EFG X KLMN OP qrst", "AaaDBCdEfgXKlmnOPQrst", CleanStringType.PascalCase)] - [TestCase("AA db cd EFG X KLMN OP qrst", "aaDbCdEfgXKlmnOPQrst", CleanStringType.CamelCase)] - [TestCase("AAA db cd EFG X KLMN OP qrst", "aaaDbCdEfgXKlmnOPQrst", CleanStringType.CamelCase)] - [TestCase("AA db cd EFG X KLMN OP qrst", "AADbCdEfgXKlmnOPQrst", CleanStringType.PascalCase)] - [TestCase("AAA db cd EFG X KLMN OP qrst", "AaaDbCdEfgXKlmnOPQrst", CleanStringType.PascalCase)] - [TestCase("We store some HTML in the DB for performance", "WeStoreSomeHtmlInTheDBForPerformance", CleanStringType.PascalCase)] - [TestCase("We store some HTML in the DB for performance", "weStoreSomeHtmlInTheDBForPerformance", CleanStringType.CamelCase)] - [TestCase("X is true", "XIsTrue", CleanStringType.PascalCase)] - [TestCase("X is true", "xIsTrue", CleanStringType.CamelCase)] - [TestCase("IO are slow", "IOAreSlow", CleanStringType.PascalCase)] - [TestCase("IO are slow", "ioAreSlow", CleanStringType.CamelCase)] - [TestCase("RAM is fast", "RamIsFast", CleanStringType.PascalCase)] - [TestCase("RAM is fast", "ramIsFast", CleanStringType.CamelCase)] - [TestCase("Tab 1", "tab1", CleanStringType.CamelCase)] - [TestCase("Home - Page", "homePage", CleanStringType.CamelCase)] - [TestCase("Shannon's Document Type", "shannonsDocumentType", CleanStringType.CamelCase)] - [TestCase("!BADDLY nam-ed Document Type", "baddlyNamEdDocumentType", CleanStringType.CamelCase)] - [TestCase(" !BADDLY nam-ed Document Type", "BADDLYnamedDocumentType", CleanStringType.Unchanged)] - [TestCase("!BADDLY nam-ed Document Type", "BaddlyNamEdDocumentType", CleanStringType.PascalCase)] - [TestCase("i %Want!thisTo end up In Proper@case", "IWantThisToEndUpInProperCase", CleanStringType.PascalCase)] - [TestCase("Räksmörgås %%$£¤¤¤§ kéKé", "raksmorgasKeKe", CleanStringType.CamelCase)] - [TestCase("Räksmörgås %%$£¤¤¤§ kéKé", "RaksmorgasKeKe", CleanStringType.PascalCase)] - [TestCase("Räksmörgås %%$£¤¤¤§ kéKé", "RaksmorgaskeKe", CleanStringType.Unchanged)] - [TestCase("TRii", "TRii", CleanStringType.Unchanged)] - [TestCase("**TRii", "TRii", CleanStringType.Unchanged)] - [TestCase("TRii", "trIi", CleanStringType.CamelCase)] - [TestCase("**TRii", "trIi", CleanStringType.CamelCase)] - [TestCase("TRii", "TRIi", CleanStringType.PascalCase)] - [TestCase("**TRii", "TRIi", CleanStringType.PascalCase)] - [TestCase("trII", "trII", CleanStringType.Unchanged)] - [TestCase("**trII", "trII", CleanStringType.Unchanged)] - [TestCase("trII", "trII", CleanStringType.CamelCase)] - [TestCase("**trII", "trII", CleanStringType.CamelCase)] - [TestCase("trII", "TrII", CleanStringType.PascalCase)] - [TestCase("**trII", "TrII", CleanStringType.PascalCase)] - [TestCase("trIIX", "trIix", CleanStringType.CamelCase)] - [TestCase("**trIIX", "trIix", CleanStringType.CamelCase)] - [TestCase("trIIX", "TrIix", CleanStringType.PascalCase)] - [TestCase("**trIIX", "TrIix", CleanStringType.PascalCase)] - #endregion - public void CleanStringToAsciiWithCase(string input, string expected, CleanStringType caseType) - { - var output = _helper.CleanString(input, caseType | CleanStringType.Ascii); - // legacy does nothing - Assert.AreEqual(input, output); - } - - #region Cases - [TestCase("1235brô dëK tzARlan ban123!pOo", "bro de K tz AR lan ban123 p Oo", ' ', CleanStringType.Unchanged)] - [TestCase(" 1235brô dëK tzARlan ban123!pOo ", "bro de K tz AR lan ban123 p Oo", ' ', CleanStringType.Unchanged)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "Bro De K Tz AR Lan Ban123 P Oo", ' ', CleanStringType.PascalCase)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "Bro De K Tz AR Lan Ban123 P Oo", ' ', CleanStringType.PascalCase)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "bro De K Tz AR Lan Ban123 P Oo", ' ', CleanStringType.CamelCase)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "bro-De-K-Tz-AR-Lan-Ban123-P-Oo", '-', CleanStringType.CamelCase)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "BRO-DE-K-TZ-AR-LAN-BAN123-P-OO", '-', CleanStringType.UpperCase)] - [TestCase("1235brô dëK tzARlan ban123!pOo", "bro-de-k-tz-ar-lan-ban123-p-oo", '-', CleanStringType.LowerCase)] - [TestCase("Tab 1", "tab 1", ' ', CleanStringType.CamelCase)] - [TestCase("Home - Page", "home Page", ' ', CleanStringType.CamelCase)] - [TestCase("Shannon's Document Type", "shannons Document Type", ' ', CleanStringType.CamelCase)] - [TestCase("!BADDLY nam-ed Document Type", "baddly Nam Ed Document Type", ' ', CleanStringType.CamelCase)] - [TestCase(" !BADDLY nam-ed Document Type", "BADDLY nam ed Document Type", ' ', CleanStringType.Unchanged)] - [TestCase("!BADDLY nam-ed Document Type", "Baddly Nam Ed Document Type", ' ', CleanStringType.PascalCase)] - [TestCase("i %Want!thisTo end up In Proper@case", "I Want This To End Up In Proper Case", ' ', CleanStringType.PascalCase)] - [TestCase("Räksmörgås %%$£¤¤¤§ kéKé", "raksmorgas Ke Ke", ' ', CleanStringType.CamelCase)] - [TestCase("Räksmörgås %%$£¤¤¤§ kéKé", "Raksmorgas Ke Ke", ' ', CleanStringType.PascalCase)] - [TestCase("Räksmörgås %%$£¤¤¤§ kéKé", "Raksmorgas ke Ke", ' ', CleanStringType.Unchanged)] - #endregion - public void CleanStringToAsciiWithCaseAndSeparator(string input, string expected, char separator, CleanStringType caseType) - { - var output = _helper.CleanString(input, caseType | CleanStringType.Ascii, separator); - // legacy does nothing - Assert.AreEqual(input, output); - } - - [Test] // can't do cases with an IDictionary - public void ReplaceManyWithCharMap() - { - const string input = "télévisiön tzvâr ßup   pof"; - const string expected = "television tzvar ssup pof"; - IDictionary replacements = new Dictionary - { - { "é", "e" }, - { "ö", "o" }, - { "â", "a" }, - { "ß", "ss" }, - { " ", " " }, - }; - var output = _helper.ReplaceMany(input, replacements); - Assert.AreEqual(expected, output); - } - - #region Cases - [TestCase("val$id!ate|this|str'ing", "$!'", '-', "val-id-ate|this|str-ing")] - [TestCase("val$id!ate|this|str'ing", "$!'", '*', "val*id*ate|this|str*ing")] - #endregion - public void ReplaceManyByOneChar(string input, string toReplace, char replacement, string expected) - { - var output = _helper.ReplaceMany(input, toReplace.ToArray(), replacement); - Assert.AreEqual(expected, output); - } - - #region Cases - [TestCase("foo.txt", "foo.txt")] - [TestCase("foo", "foo", IgnoreReason = "fails when no extension")] - [TestCase(".txt", ".txt")] - [TestCase("nag*dog/poo:xit.txt", "nag-dog-poo-xit.txt")] - [TestCase("the dog is in the house.txt", "the-dog-is-in-the-house.txt")] - [TestCase("nil.nil.nil.txt", "nilnilnil.txt")] // because of chars map - [TestCase("taradabum", "taradabum", IgnoreReason = "fails when no extension")] - [TestCase("tara$$da:b/u - { - {" ", "-"}, - {"\"", ""}, - {""", ""}, - {"@", ""}, - {"%", ""}, - {".", ""}, - {";", ""}, - {"/", ""}, - {":", ""}, - {"#", ""}, - {"+", ""}, - {"*", ""}, - {"&", ""}, - {"?", ""} - }; - - var name1 = "Home Page"; - var name2 = "Shannon's Home Page!"; - var name3 = "#Someones's Twitter $h1z%n"; - var name4 = "Räksmörgås"; - var name5 = "'em guys-over there, are#goin' a \"little\"bit crazy eh!! :)"; - var name6 = "汉#字*/漢?字"; - - var url1 = name1.ToUrlSegment(); - var url2 = name2.ToUrlSegment(); - var url3 = name3.ToUrlSegment(); - var url4 = name4.ToUrlSegment(); - var url5 = name5.ToUrlSegment(); - var url6 = name6.ToUrlSegment(); - var url7 = name6.ToUrlSegment(); - var url8 = name6.ToUrlSegment(); - - Assert.AreEqual("home-page", url1); - Assert.AreEqual("shannons-home-page", url2); - Assert.AreEqual("someoness-twitter-h1zn", url3); - Assert.AreEqual("rksmrgs", url4); - Assert.AreEqual("em-guys-over-there-aregoin-a-littlebit-crazy-eh", url5); - Assert.AreEqual("", url6); - Assert.AreEqual("汉字漢字", url7); - Assert.AreEqual("%e6%b1%89%e5%ad%97%e6%bc%a2%e5%ad%97", url8); - - } - - [TestCase] - public void StringExtensions_To_Camel_Case() - { - //Arrange - - var name1 = "Tab 1"; - var name2 = "Home - Page"; - var name3 = "Shannon's document type"; - - //Act - - var camelCase1 = name1.ToCleanString(CleanStringType.CamelCase); - var camelCase2 = name2.ToCleanString(CleanStringType.CamelCase); - var camelCase3 = name3.ToCleanString(CleanStringType.CamelCase); - - //Assert - - Assert.AreEqual("tab1", camelCase1); - Assert.AreEqual("homePage", camelCase2); - Assert.AreEqual("shannon'sDocumentType", camelCase3); - } - - [TestCase] - public void StringExtensions_To_Entity_Alias() - { - //Arrange - - var name1 = "Tab 1"; - var name2 = "Home - Page"; - var name3 = "Shannon's Document Type"; - var name4 = "!BADDLY nam-ed Document Type"; - var name5 = "i %Want!thisTo end up In Proper@case"; - - //Act - - var alias1 = name1.ToSafeAlias(); - var alias2 = name2.ToSafeAlias(); - var alias3 = name3.ToSafeAlias(); - var alias4 = name4.ToSafeAlias(); - var alias5 = name5.ToSafeAlias(/*StringAliasCaseType.PascalCase*/); - - //Assert - - Assert.AreEqual("tab1", alias1); - Assert.AreEqual("homePage", alias2); - Assert.AreEqual("shannonsDocumentType", alias3); - Assert.AreEqual("baddlyNamEdDocumentType", alias4); - - // disable: does not support PascalCase anymore - //Assert.AreEqual("IWantThisToEndUpInProperCase", alias5); - } - - } -} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 4766505912..e04d17d1c8 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -350,9 +350,7 @@ - -