From 9a10863760657e7d44a979a9c7a37527fde631d1 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 3 Oct 2013 16:04:24 +0200 Subject: [PATCH 1/3] Core.EnumerableExtensions - bugfix f9663a9 --- src/Umbraco.Core/EnumerableExtensions.cs | 42 +++++++++++++++++------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Core/EnumerableExtensions.cs b/src/Umbraco.Core/EnumerableExtensions.cs index dfdd26cd84..2aba7684f0 100644 --- a/src/Umbraco.Core/EnumerableExtensions.cs +++ b/src/Umbraco.Core/EnumerableExtensions.cs @@ -17,21 +17,41 @@ namespace Umbraco.Core throw new NullReferenceException("source"); // enumerate the source only once! - var enumerator = source.GetEnumerator(); - - while (enumerator.MoveNext()) - yield return EnumerateGroup(enumerator, groupSize); + return new InGroupsEnumerator(source, groupSize).Groups(); } - private static IEnumerable EnumerateGroup(IEnumerator enumerator, int count) + // this class makes sure that the source is enumerated only ONCE + // which means that when it is enumerated, the actual groups content + // has to be evaluated at the same time, and stored in an array. + private class InGroupsEnumerator { - var c = 1; - do - { - yield return enumerator.Current; - } while (c++ < count && enumerator.MoveNext()); - } + private readonly IEnumerator _source; + private readonly int _count; + private bool _mightHaveNext; + public InGroupsEnumerator(IEnumerable source, int count) + { + _source = source.GetEnumerator(); + _count = count; + _mightHaveNext = true; + } + + public IEnumerable> Groups() + { + while (_mightHaveNext && _source.MoveNext()) + yield return Group().ToArray(); // see note above + } + + private IEnumerable Group() + { + var c = 0; + do + { + yield return _source.Current; + } while (++c < _count && _source.MoveNext()); + _mightHaveNext = c == _count; + } + } /// The distinct by. /// The source. From 4c13dbf8b7af5eba3900e0c326a1d871d084eb04 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 3 Oct 2013 17:49:38 +0200 Subject: [PATCH 2/3] Core.StringExtensions - fix methods that should be extension methods --- src/Umbraco.Core/StringExtensions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index 8582324c51..eebd7ff1e8 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -999,7 +999,7 @@ namespace Umbraco.Core /// strings are cleaned up to camelCase and Ascii. /// The clean string. /// The string is cleaned in the context of the IShortStringHelper default culture. - public static string ToCleanString(string text, CleanStringType stringType) + public static string ToCleanString(this string text, CleanStringType stringType) { return ShortStringHelper.CleanString(text, stringType); } @@ -1013,7 +1013,7 @@ namespace Umbraco.Core /// The separator. /// The clean string. /// The string is cleaned in the context of the IShortStringHelper default culture. - public static string ToCleanString(string text, CleanStringType stringType, char separator) + public static string ToCleanString(this string text, CleanStringType stringType, char separator) { return ShortStringHelper.CleanString(text, stringType, separator); } @@ -1026,7 +1026,7 @@ namespace Umbraco.Core /// strings are cleaned up to camelCase and Ascii. /// The culture. /// The clean string. - public static string ToCleanString(string text, CleanStringType stringType, CultureInfo culture) + public static string ToCleanString(this string text, CleanStringType stringType, CultureInfo culture) { return ShortStringHelper.CleanString(text, stringType, culture); } @@ -1040,7 +1040,7 @@ namespace Umbraco.Core /// The separator. /// The culture. /// The clean string. - public static string ToCleanString(string text, CleanStringType stringType, char separator, CultureInfo culture) + public static string ToCleanString(this string text, CleanStringType stringType, char separator, CultureInfo culture) { return ShortStringHelper.CleanString(text, stringType, separator, culture); } From 08660704cc904bc91a803580453e524514cbbf79 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 3 Oct 2013 17:52:14 +0200 Subject: [PATCH 3/3] Core.StringExtensions - adjust to new default IShortStringHelper (see f64b8d6) --- src/Umbraco.Tests/CodeFirst/ContentTypeMapper.cs | 4 ++-- src/Umbraco.Tests/CodeFirst/TypeInheritanceTest.cs | 6 +++--- src/Umbraco.Tests/CoreStrings/CmsHelperCasingTests.cs | 3 ++- src/Umbraco.Web/Models/DynamicPublishedContent.cs | 7 ++++--- src/Umbraco.Web/umbraco.presentation/item.cs | 3 ++- src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs | 5 +++-- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Tests/CodeFirst/ContentTypeMapper.cs b/src/Umbraco.Tests/CodeFirst/ContentTypeMapper.cs index d7ff2c2f94..d0130b948e 100644 --- a/src/Umbraco.Tests/CodeFirst/ContentTypeMapper.cs +++ b/src/Umbraco.Tests/CodeFirst/ContentTypeMapper.cs @@ -19,9 +19,9 @@ namespace Umbraco.Tests.CodeFirst foreach (var property in content.Properties) { - var @alias = property.Alias; + var @alias = property.Alias.ToLowerInvariant(); - var propertyInfo = propertyInfos.FirstOrDefault(x => x.Name.ToUmbracoAlias() == @alias); + var propertyInfo = propertyInfos.FirstOrDefault(x => x.Name.ToLowerInvariant() == @alias); if (propertyInfo == null) continue; object value = null; diff --git a/src/Umbraco.Tests/CodeFirst/TypeInheritanceTest.cs b/src/Umbraco.Tests/CodeFirst/TypeInheritanceTest.cs index e53d8552e8..ccc5d887f5 100644 --- a/src/Umbraco.Tests/CodeFirst/TypeInheritanceTest.cs +++ b/src/Umbraco.Tests/CodeFirst/TypeInheritanceTest.cs @@ -64,9 +64,9 @@ namespace Umbraco.Tests.CodeFirst } Assert.That(list.Count, Is.EqualTo(3)); - Assert.That(list.Any(x => x == "meta"), Is.True); - Assert.That(list.Any(x => x == "metaSeo"), Is.True); - Assert.That(list.Any(x => x == "base"), Is.True); + Assert.Contains("Meta", list); + Assert.Contains("MetaSeo", list); + Assert.Contains("Base", list); } [Test] diff --git a/src/Umbraco.Tests/CoreStrings/CmsHelperCasingTests.cs b/src/Umbraco.Tests/CoreStrings/CmsHelperCasingTests.cs index 477a9a5b05..500c0ef81f 100644 --- a/src/Umbraco.Tests/CoreStrings/CmsHelperCasingTests.cs +++ b/src/Umbraco.Tests/CoreStrings/CmsHelperCasingTests.cs @@ -17,7 +17,8 @@ namespace Umbraco.Tests.CoreStrings [TestCase("t", "t")] [TestCase("thisis", "Thisis")] [TestCase("ThisIsTheEnd", "This Is The End")] - [TestCase("WhoIsNumber6InTheVillage", "Who Is Number6In The Village")] // note the issue with Number6In + //[TestCase("WhoIsNumber6InTheVillage", "Who Is Number6In The Village")] // note the issue with Number6In + [TestCase("WhoIsNumber6InTheVillage", "Who Is Number6 In The Village")] // now fixed since DefaultShortStringHelper is the default public void SpaceCamelCasing(string input, string expected) { var output = umbraco.cms.helpers.Casing.SpaceCamelCasing(input); diff --git a/src/Umbraco.Web/Models/DynamicPublishedContent.cs b/src/Umbraco.Web/Models/DynamicPublishedContent.cs index 2d17ee11c0..690cfb114b 100644 --- a/src/Umbraco.Web/Models/DynamicPublishedContent.cs +++ b/src/Umbraco.Web/Models/DynamicPublishedContent.cs @@ -13,6 +13,7 @@ using Umbraco.Core.PropertyEditors; using System.Reflection; using System.Xml.Linq; using umbraco.cms.businesslogic; +using Umbraco.Core.Strings; using ContentType = umbraco.cms.businesslogic.ContentType; namespace Umbraco.Web.Models @@ -403,9 +404,9 @@ namespace Umbraco.Web.Models { //if we cannot get with the current alias, try changing it's case attempt = alias[0].IsUpperCase() - ? getMember(alias.ConvertCase(StringAliasCaseType.CamelCase)) - : getMember(alias.ConvertCase(StringAliasCaseType.PascalCase)); - } + ? getMember(alias.ToCleanString(CleanStringType.Ascii | CleanStringType.Alias | CleanStringType.CamelCase)) + : getMember(alias.ToCleanString(CleanStringType.Ascii | CleanStringType.Alias | CleanStringType.PascalCase)); + } return !attempt.Success ? null diff --git a/src/Umbraco.Web/umbraco.presentation/item.cs b/src/Umbraco.Web/umbraco.presentation/item.cs index 1cf5e8ae31..9965e3a435 100644 --- a/src/Umbraco.Web/umbraco.presentation/item.cs +++ b/src/Umbraco.Web/umbraco.presentation/item.cs @@ -6,6 +6,7 @@ using StackExchange.Profiling; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Profiling; +using Umbraco.Core.Strings; namespace umbraco { @@ -179,7 +180,7 @@ namespace umbraco else if (helper.FindAttribute(attributes, "case") == "upper") _fieldContent = _fieldContent.ToUpper(); else if (helper.FindAttribute(attributes, "case") == "title") - _fieldContent = _fieldContent.ConvertCase(StringAliasCaseType.PascalCase); + _fieldContent = _fieldContent.ToCleanString(CleanStringType.Ascii | CleanStringType.Alias | CleanStringType.PascalCase); // OTHER FORMATTING FUNCTIONS // If we use masterpages, this is moved to the ItemRenderer to add support for before/after in inline XSLT diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs index a2ac541247..5ff63fec91 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs @@ -8,6 +8,7 @@ using System.Web; using Umbraco.Core; using Umbraco.Core.Dynamics; using Umbraco.Core.Logging; +using Umbraco.Core.Strings; using umbraco.interfaces; using System.Collections; using System.Reflection; @@ -670,8 +671,8 @@ namespace umbraco.MacroEngines { //if we cannot get with the current alias, try changing it's case attempt = alias[0].IsUpperCase() - ? getMember(alias.ConvertCase(StringAliasCaseType.CamelCase)) - : getMember(alias.ConvertCase(StringAliasCaseType.PascalCase)); + ? getMember(alias.ToCleanString(CleanStringType.Ascii | CleanStringType.Alias | CleanStringType.CamelCase)) + : getMember(alias.ToCleanString(CleanStringType.Ascii | CleanStringType.Alias | CleanStringType.PascalCase)); } return attempt.Success ? attempt.Result : null;