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 @@
-
-