From be2d81154bb22abedc7dfcbccbde131b39fa094b Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 9 Jun 2016 20:13:20 +0200 Subject: [PATCH] U4-6674 - Kill ToContentSet, becomes ToIndexedArray --- src/Umbraco.Core/Models/IPublishedContent.cs | 21 - .../IPublishedContentExtended.cs | 29 +- .../PublishedContent/IndexedArrayItem.cs | 172 ++++ .../PublishedContentExtended.cs | 56 +- .../PublishedContentOrderedSet.cs | 32 - .../PublishedContent/PublishedContentSet.cs | 234 ----- .../PublishedContentWrapped.cs | 11 - src/Umbraco.Core/Umbraco.Core.csproj | 3 +- .../DynamicDocumentTestsBase.cs | 917 ++++++++---------- .../PublishedContentMoreTests.cs | 97 +- .../PublishedContentTestElements.cs | 14 - .../PublishedContent/PublishedContentTests.cs | 152 +-- .../PublishedContent/RootNodeTests.cs | 4 - src/Umbraco.Web/ExamineExtensions.cs | 12 +- .../Models/DynamicPublishedContent.cs | 220 ----- .../Models/DynamicPublishedContentList.cs | 14 +- .../Models/PublishedContentBase.cs | 18 - src/Umbraco.Web/PublishedContentExtensions.cs | 446 +-------- 18 files changed, 626 insertions(+), 1826 deletions(-) create mode 100644 src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs delete mode 100644 src/Umbraco.Core/Models/PublishedContent/PublishedContentOrderedSet.cs delete mode 100644 src/Umbraco.Core/Models/PublishedContent/PublishedContentSet.cs diff --git a/src/Umbraco.Core/Models/IPublishedContent.cs b/src/Umbraco.Core/Models/IPublishedContent.cs index 4f563d0e7c..89fdaeed99 100644 --- a/src/Umbraco.Core/Models/IPublishedContent.cs +++ b/src/Umbraco.Core/Models/IPublishedContent.cs @@ -16,21 +16,6 @@ namespace Umbraco.Core.Models /// public interface IPublishedContent { - #region ContentSet - - // Because of http://issues.umbraco.org/issue/U4-1797 and in order to implement - // Index() and methods that derive from it such as IsFirst(), IsLast(), etc... all - // content items must know about their containing content set. - - /// - /// Gets the content set to which the content belongs. - /// - /// The default set consists in the siblings of the content (including the content - /// itself) ordered by sortOrder. - IEnumerable ContentSet { get; } - - #endregion - #region ContentType /// @@ -73,12 +58,6 @@ namespace Umbraco.Core.Models /// have a published version, or not. bool IsDraft { get; } - /// - /// Gets the index of the published content within its current owning content set. - /// - /// The index of the published content within its current owning content set. - int GetIndex(); - #endregion #region Tree diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentExtended.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentExtended.cs index 4446a21329..524ef969b3 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentExtended.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentExtended.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Umbraco.Core.Models.PublishedContent +namespace Umbraco.Core.Models.PublishedContent { /// /// Provides methods to handle extended content. @@ -20,27 +15,5 @@ namespace Umbraco.Core.Models.PublishedContent /// Gets a value indicating whether properties were added to the extended content. /// bool HasAddedProperties { get; } - - /// - /// Sets the content set of the extended content. - /// - /// - void SetContentSet(IEnumerable contentSet); - - /// - /// Resets the content set of the extended content. - /// - void ClearContentSet(); - - /// - /// Sets the index of the extended content. - /// - /// The index value. - void SetIndex(int value); - - /// - /// Resets the index of the extended content. - /// - void ClearIndex(); } } diff --git a/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs b/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs new file mode 100644 index 0000000000..0349807e27 --- /dev/null +++ b/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Umbraco.Core.Models.PublishedContent +{ + public class IndexedArrayItem + { + public IndexedArrayItem(TContent content, int index) + { + Content = content; + Index = index; + } + + public TContent Content { get; } + + public int Index { get; } + + public int TotalCount { get; internal set; } + + public bool IsFirst() + { + return Index == 0; + } + + public HtmlString IsFirst(string valueIfTrue) + { + return IsFirst(valueIfTrue, string.Empty); + } + + public HtmlString IsFirst(string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsFirst() ? valueIfTrue : valueIfFalse); + } + + public bool IsNotFirst() + { + return IsFirst() == false; + } + + public HtmlString IsNotFirst(string valueIfTrue) + { + return IsNotFirst(valueIfTrue, string.Empty); + } + + public HtmlString IsNotFirst(string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsNotFirst() ? valueIfTrue : valueIfFalse); + } + + public bool IsIndex(int index) + { + return Index == index; + } + + public HtmlString IsIndex(int index, string valueIfTrue) + { + return IsIndex(index, valueIfTrue, string.Empty); + } + + public HtmlString IsIndex(int index, string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsIndex(index) ? valueIfTrue : valueIfFalse); + } + + public bool IsModZero(int modulus) + { + return Index % modulus == 0; + } + + public HtmlString IsModZero(int modulus, string valueIfTrue) + { + return IsModZero(modulus, valueIfTrue, string.Empty); + } + + public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsModZero(modulus) ? valueIfTrue : valueIfFalse); + } + + public bool IsNotModZero(int modulus) + { + return IsModZero(modulus) == false; + } + + public HtmlString IsNotModZero(int modulus, string valueIfTrue) + { + return IsNotModZero(modulus, valueIfTrue, string.Empty); + } + + public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsNotModZero(modulus) ? valueIfTrue : valueIfFalse); + } + + public bool IsNotIndex(int index) + { + return IsIndex(index) == false; + } + + public HtmlString IsNotIndex(int index, string valueIfTrue) + { + return IsNotIndex(index, valueIfTrue, string.Empty); + } + + public HtmlString IsNotIndex(int index, string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsNotIndex(index) ? valueIfTrue : valueIfFalse); + } + + public bool IsLast() + { + return Index == TotalCount - 1; + } + + public HtmlString IsLast(string valueIfTrue) + { + return IsLast(valueIfTrue, string.Empty); + } + + public HtmlString IsLast(string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsLast() ? valueIfTrue : valueIfFalse); + } + + public bool IsNotLast() + { + return IsLast() == false; + } + + public HtmlString IsNotLast(string valueIfTrue) + { + return IsNotLast(valueIfTrue, string.Empty); + } + + public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsNotLast() ? valueIfTrue : valueIfFalse); + } + + public bool IsEven() + { + return Index % 2 == 0; + } + + public HtmlString IsEven(string valueIfTrue) + { + return IsEven(valueIfTrue, string.Empty); + } + + public HtmlString IsEven(string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsEven() ? valueIfTrue : valueIfFalse); + } + + public bool IsOdd() + { + return Index % 2 == 1; + } + + public HtmlString IsOdd(string valueIfTrue) + { + return IsOdd(valueIfTrue, string.Empty); + } + + public HtmlString IsOdd(string valueIfTrue, string valueIfFalse) + { + return new HtmlString(IsOdd() ? valueIfTrue : valueIfFalse); + } + } +} diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentExtended.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentExtended.cs index d9c3829d6d..6309b6e8b7 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentExtended.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentExtended.cs @@ -17,31 +17,9 @@ namespace Umbraco.Core.Models.PublishedContent #endregion - #region Index - - private int? _index; - - public override int GetIndex() - { - // fast - if (_index.HasValue) return _index.Value; - - // slow -- and don't cache, not in a set - if (_contentSet == null) return Content.GetIndex(); - - // slow -- but cache for next time - var index = _contentSet.FindIndex(x => x.Id == Id); - if (index < 0) - throw new IndexOutOfRangeException("Could not find content in the content set."); - _index = index; - return index; - } - - #endregion - #region Extend - internal static IPublishedContentExtended Extend(IPublishedContent content, IEnumerable contentSet) + internal static IPublishedContentExtended Extend(IPublishedContent content) { // first unwrap content down to the lowest possible level, ie either the deepest inner // IPublishedContent or the first extended that has added properties. this is to avoid @@ -95,7 +73,6 @@ namespace Umbraco.Core.Models.PublishedContent var extended2 = extended as IPublishedContentExtended; if (extended2 == null) throw new Exception("Extended does not implement IPublishedContentExtended."); - extended2.SetContentSet(contentSet); return extended2; } @@ -115,37 +92,6 @@ namespace Umbraco.Core.Models.PublishedContent get { return _properties != null; } } - void IPublishedContentExtended.SetContentSet(IEnumerable contentSet) - { - _contentSet = contentSet; - } - - void IPublishedContentExtended.ClearContentSet() - { - _contentSet = null; - } - - void IPublishedContentExtended.SetIndex(int value) - { - _index = value; - } - - void IPublishedContentExtended.ClearIndex() - { - _index = null; - } - - #endregion - - #region Content set - - private IEnumerable _contentSet; - - public override IEnumerable ContentSet - { - get { return _contentSet ?? Content.ContentSet; } - } - #endregion #region Properties diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentOrderedSet.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentOrderedSet.cs deleted file mode 100644 index 25956aa3d4..0000000000 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentOrderedSet.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Umbraco.Core.Models.PublishedContent -{ - /// - /// Represents an ordered set of . - /// - /// The type of content. - public class PublishedContentOrderedSet : PublishedContentSet, IOrderedEnumerable - where T : class, IPublishedContent - { -// ReSharper disable ParameterTypeCanBeEnumerable.Local - internal PublishedContentOrderedSet(IOrderedEnumerable content) -// ReSharper restore ParameterTypeCanBeEnumerable.Local - : base(content) - { } - - // note: because we implement IOrderedEnumerable, we don't need to implement the ThenBy nor - // ThenByDescending methods here, only CreateOrderedEnumerable and that does it. - - #region IOrderedEnumerable - - public IOrderedEnumerable CreateOrderedEnumerable(Func keySelector, IComparer comparer, bool descending) - { - return new PublishedContentOrderedSet(((IOrderedEnumerable)Source).CreateOrderedEnumerable(keySelector, comparer, descending)); - } - - #endregion - } -} diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentSet.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentSet.cs deleted file mode 100644 index 369a554674..0000000000 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentSet.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Umbraco.Core.Models.PublishedContent -{ - /// - /// Represents a set of . - /// - /// The type of content. - /// - /// A ContentSet{T} is created from an IEnumerable{T} using the ToContentSet - /// extension method. - /// The content set source is enumerated only once. Same as what you get - /// when you call ToList on an IEnumerable. Only, ToList enumerates its source when - /// created, whereas a content set enumerates its source only when the content set itself - /// is enumerated. - /// - public class PublishedContentSet : IEnumerable - where T : class, IPublishedContent - { - // used by ToContentSet extension method to initialize a new set from an IEnumerable. - internal PublishedContentSet(IEnumerable source) - { - if (source == null) - throw new ArgumentNullException("source"); - Source = source; - } - - #region Source - - protected readonly IEnumerable Source; - - #endregion - - #region Enumerated - - // cache the enumeration so we don't enumerate more than once. Same as what you get - // when you call ToList on an IEnumerable. Only, ToList enumerates its source when - // created, whereas a content set enumerates its source only when the content set itself - // is enumerated. - - // cache the wrapped items so if we reset the enumeration, we do not re-wrap everything (only new items). - - private T[] _enumerated; - private readonly Dictionary _xContent = new Dictionary(); - - // wrap an item, ie create the actual clone for this set - private T MapContentAsT(T t) - { - return MapContent(t) as T; - } - - internal IPublishedContentExtended MapContent(T t) - { - IPublishedContentExtended extend; - if (_xContent.TryGetValue(t, out extend)) return extend; - - extend = PublishedContentExtended.Extend(t, this); - var asT = extend as T; - if (asT == null) - throw new InvalidOperationException(string.Format("Failed extend a published content of type {0}." - + "Got {1} when expecting {2}.", t.GetType().FullName, extend.GetType().FullName, typeof(T).FullName)); - _xContent[t] = extend; - return extend; - } - - private T[] Enumerated - { - get - { - // enumerate the source and cache the result - // tell clones about their index within the set (for perfs purposes) - var index = 0; - return _enumerated ?? (_enumerated = Source.Select(t => - { - var extend = MapContent(t); - extend.SetIndex(index++); - return extend as T; - }).ToArray()); - } - } - - // indicates that the source has changed - // so the set can clear its inner caches - // should only be used by DynamicPublishedContentList - internal void SourceChanged() - { - // reset the cached enumeration so it's enumerated again - if (_enumerated == null) return; - _enumerated = null; - - foreach (var item in _xContent.Values) - item.ClearIndex(); - - var removed = _xContent.Keys.Except(Source); - foreach (var content in removed) - { - _xContent[content].ClearContentSet(); - _xContent.Remove(content); - } - } - - /// - /// Gets the number of items in the set. - /// - /// The number of items in the set. - /// Will cause the set to be enumerated if it hasn't been already. - public virtual int Count - { - get { return Enumerated.Length; } - } - #endregion - - #region IEnumerable - - public IEnumerator GetEnumerator() - { - return ((IEnumerable)Enumerated).GetEnumerator(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Wrap methods returning T - - public T ElementAt(int index) - { - return MapContentAsT(Source.ElementAt(index)); - } - - public T ElementAtOrDefault(int index) - { - var element = Source.ElementAtOrDefault(index); - return element == null ? null : MapContentAsT(element); - } - - public T First() - { - return MapContentAsT(Source.First()); - } - - public T First(Func predicate) - { - return MapContentAsT(Source.First(predicate)); - } - - public T FirstOrDefault() - { - var first = Source.FirstOrDefault(); - return first == null ? null : MapContentAsT(first); - } - - public T FirstOrDefault(Func predicate) - { - var first = Source.FirstOrDefault(predicate); - return first == null ? null : MapContentAsT(first); - } - - public T Last() - { - return MapContentAsT(Source.Last()); - } - - public T Last(Func predicate) - { - return MapContentAsT(Source.Last(predicate)); - } - - public T LastOrDefault() - { - var last = Source.LastOrDefault(); - return last == null ? null : MapContentAsT(last); - } - - public T LastOrDefault(Func predicate) - { - var last = Source.LastOrDefault(predicate); - return last == null ? null : MapContentAsT(last); - } - - public T Single() - { - return MapContentAsT(Source.Single()); - } - - public T Single(Func predicate) - { - return MapContentAsT(Source.Single(predicate)); - } - - public T SingleOrDefault() - { - var single = Source.SingleOrDefault(); - return single == null ? null : MapContentAsT(single); - } - - public T SingleOrDefault(Func predicate) - { - var single = Source.SingleOrDefault(predicate); - return single == null ? null : MapContentAsT(single); - } - - #endregion - - #region Wrap methods returning IOrderedEnumerable - - public PublishedContentOrderedSet OrderBy(Func keySelector) - { - return new PublishedContentOrderedSet(Source.OrderBy(keySelector)); - } - - public PublishedContentOrderedSet OrderBy(Func keySelector, IComparer comparer) - { - return new PublishedContentOrderedSet(Source.OrderBy(keySelector, comparer)); - } - - public PublishedContentOrderedSet OrderByDescending(Func keySelector) - { - return new PublishedContentOrderedSet(Source.OrderByDescending(keySelector)); - } - - public PublishedContentOrderedSet OrderByDescending(Func keySelector, IComparer comparer) - { - return new PublishedContentOrderedSet(Source.OrderByDescending(keySelector, comparer)); - } - - #endregion - } -} diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs index 059979ed66..19f3ac28dd 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs @@ -48,12 +48,6 @@ namespace Umbraco.Core.Models.PublishedContent return Content; } - #region ContentSet - - public virtual IEnumerable ContentSet => Content.ContentSet; - - #endregion - #region ContentType public virtual PublishedContentType ContentType => Content.ContentType; @@ -102,11 +96,6 @@ namespace Umbraco.Core.Models.PublishedContent public virtual bool IsDraft => Content.IsDraft; - public virtual int GetIndex() - { - return Content.GetIndex(); - } - #endregion #region Tree diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 623ec0e4d6..3ea3d79581 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -627,8 +627,7 @@ - - + diff --git a/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs b/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs index 613ada78d8..7e4cf93980 100644 --- a/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs +++ b/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs @@ -15,9 +15,9 @@ using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.PublishedContent { - [TestFixture] + [TestFixture] public abstract class DynamicDocumentTestsBase : PublishedContentTestBase - { + { private IUmbracoSettingsSection _umbracoSettings; public override void Initialize() @@ -37,25 +37,25 @@ namespace Umbraco.Tests.PublishedContent // explicitely want to be here... var propertyTypes = new[] - { - // AutoPublishedContentType will auto-generate other properties - new PublishedPropertyType("umbracoNaviHide", 0, "?"), - new PublishedPropertyType("selectedNodes", 0, "?"), - new PublishedPropertyType("umbracoUrlAlias", 0, "?"), - new PublishedPropertyType("content", 0, Constants.PropertyEditors.TinyMCEAlias), - new PublishedPropertyType("testRecursive", 0, "?"), - new PublishedPropertyType("siteTitle", 0, "?"), - new PublishedPropertyType("creatorName", 0, "?"), - new PublishedPropertyType("blah", 0, "?"), // ugly error when that one is missing... - }; + { + // AutoPublishedContentType will auto-generate other properties + new PublishedPropertyType("umbracoNaviHide", 0, "?"), + new PublishedPropertyType("selectedNodes", 0, "?"), + new PublishedPropertyType("umbracoUrlAlias", 0, "?"), + new PublishedPropertyType("content", 0, Constants.PropertyEditors.TinyMCEAlias), + new PublishedPropertyType("testRecursive", 0, "?"), + new PublishedPropertyType("siteTitle", 0, "?"), + new PublishedPropertyType("creatorName", 0, "?"), + new PublishedPropertyType("blah", 0, "?"), // ugly error when that one is missing... + }; var type = new AutoPublishedContentType(0, "anything", propertyTypes); ContentTypesCache.GetPublishedContentTypeByAlias = (alias) => type; } - + protected override string GetXmlContent(int templateId) - { - return @" + { + return @" @@ -94,14 +94,14 @@ namespace Umbraco.Tests.PublishedContent "; - } + } - /// - /// Returns the dynamic node/document to run tests against - /// - /// - /// - protected abstract dynamic GetDynamicNode(int id); + /// + /// Returns the dynamic node/document to run tests against + /// + /// + /// + protected abstract dynamic GetDynamicNode(int id); [Test] public void Recursive_Property() @@ -135,589 +135,460 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual("page2/alias, 2ndpagealias", doc.umbracoUrlAlias); } - /// - /// Tests the IsLast method with the result set from a Where statement - /// [Test] - public void Is_Last_From_Where_Filter() + public void Single() + { + var doc = GetDynamicNode(4444); + + var result = doc.Children().Single(); + + Assert.IsNotNull(result); + Assert.AreEqual(5555, result.Id); + } + + [Test] + public void Single_With_Query() + { + var doc = GetDynamicNode(1046); + + var result = doc.Children().Single("id==1175"); + + Assert.IsNotNull(result); + Assert.AreEqual(1175, result.Id); + } + + [Test] + public void First() { var doc = GetDynamicNode(1173); - foreach (var d in doc.Children.Where("Visible")) + var result = doc.Children().First(); + + Assert.IsNotNull(result); + Assert.AreEqual(1174, result.Id); + } + + [Test] + public void First_With_Query() + { + var doc = GetDynamicNode(1173); + + var result = doc.Children().First("blah==\"some content\""); + + Assert.IsNotNull(result); + Assert.AreEqual(1176, result.Id); + } + + [Test] + public void Where_User_Property_Value() + { + var doc = GetDynamicNode(1173); + + var result = (IEnumerable) doc.Children().Where("blah==\"some content\""); + + Assert.IsNotNull(result); + Assert.AreEqual(1, result.Count()); + Assert.AreEqual(1176, result.Single().Id); + } + + [Test] + public void String_ContainsValue_Extension_Method() + { + var doc = GetDynamicNode(1046); + + var paramVals = new Dictionary { { "searchId", 1173 } }; //this is an integer value + var result = doc.Children() + .Where("selectedNodes.ContainsValue(searchId)", paramVals) //call an extension method + .FirstOrDefault(); + + Assert.IsNotNull(result); + Assert.AreEqual(4444, result.Id); + + //don't find! + paramVals = new Dictionary { { "searchId", 1111777 } }; + result = doc.Children() + .Where("selectedNodes.ContainsValue(searchId)", paramVals) + .FirstOrDefault(); + + Assert.IsNotNull(result); + Assert.IsTrue(result.GetType() == typeof (DynamicNull)); + //Assert.AreEqual(typeof(DynamicNull), result.GetType()); + } + + [Test] + public void String_Contains_Method() + { + var doc = GetDynamicNode(1046); + + var paramVals = new Dictionary { { "searchId", "1173" } }; + var result = doc.Children() + .Where("selectedNodes.Contains(searchId)", paramVals) + .FirstOrDefault(); + + Assert.IsNotNull(result); + Assert.AreEqual(4444, result.Id); + + //don't find! + paramVals = new Dictionary { { "searchId", "1aaa173" } }; + result = doc.Children() + .Where("selectedNodes.Contains(searchId)", paramVals) + .FirstOrDefault(); + + Assert.IsNotNull(result); + Assert.IsTrue(result.GetType() == typeof (DynamicNull)); + //Assert.AreEqual(typeof (DynamicNull), result.GetType()); + } + + [Test] + public void String_Split_Method() + { + var doc = GetDynamicNode(1046); + + var paramVals = new Dictionary { - if (d.Id != 1178) - { - Assert.IsFalse(d.IsLast()); - } - else - { - Assert.IsTrue(d.IsLast()); - } + { "splitTerm", new char[] { ',' } }, + { "splitOptions", StringSplitOptions.RemoveEmptyEntries } + }; + var result = doc.Children() + .Where("selectedNodes.Split(splitTerm, splitOptions).Length == 3", paramVals) + .FirstOrDefault(); + + Assert.IsNotNull(result); + Assert.AreEqual(4444, result.Id); + } + + [Ignore("We are ignoring this test because currently our ExpressionParser class cannot deal with this... it needs some serious TLC but it is very complex.")] + [Test] + public void Complex_Linq() + { + var doc = GetDynamicNode(1173); + + var paramVals = new Dictionary { { "splitTerm", new char[] { ',' } }, { "searchId", "1173" } }; + var result = doc.Ancestors().OrderBy("level") + .Single() + .Descendants() + .Where("selectedNodes != null && selectedNodes != String.Empty && selectedNodes.Split(splitTerm).Contains(searchId)", paramVals) + .FirstOrDefault(); + + Assert.IsNotNull(result); + Assert.AreEqual(4444, result.Id); + } + + [Test] + public void Children_GroupBy_DocumentTypeAlias() + { + var doc = GetDynamicNode(1046); + + var found1 = doc.Children.GroupBy("DocumentTypeAlias"); + + var casted = (IEnumerable>) (found1); + Assert.AreEqual(2, casted.Count()); + Assert.AreEqual(2, casted.Single(x => x.Key.ToString() == "Home").Count()); + Assert.AreEqual(1, casted.Single(x => x.Key.ToString() == "CustomDocument").Count()); + } + + [Test] + public void Children_Where_DocumentTypeAlias() + { + var doc = GetDynamicNode(1046); + + var found1 = doc.Children.Where("DocumentTypeAlias == \"CustomDocument\""); + var found2 = doc.Children.Where("DocumentTypeAlias == \"Home\""); + + Assert.AreEqual(1, found1.Count()); + Assert.AreEqual(2, found2.Count()); + } + + [Test] + public void Children_Where_NodeTypeAlias() + { + var doc = GetDynamicNode(1046); + + var found1 = doc.Children.Where("NodeTypeAlias == \"CustomDocument\""); + var found2 = doc.Children.Where("NodeTypeAlias == \"Home\""); + + Assert.AreEqual(1, found1.Count()); + Assert.AreEqual(2, found2.Count()); + } + + [Test] + public void Children_Order_By_Update_Date() + { + var asDynamic = GetDynamicNode(1173); + + var ordered = asDynamic.Children.OrderBy("UpdateDate"); + var casted = (IEnumerable) ordered; + + var correctOrder = new[] { 1178, 1177, 1174, 1176 }; + for (var i = 0; i < correctOrder.Length; i++) + { + Assert.AreEqual(correctOrder[i], ((dynamic) casted.ElementAt(i)).Id); } } - [Test] - public void Single() - { - var doc = GetDynamicNode(4444); - - var result = doc.Children().Single(); - - Assert.IsNotNull(result); - Assert.AreEqual(5555, result.Id); - } - - [Test] - public void Single_With_Query() - { - var doc = GetDynamicNode(1046); - - var result = doc.Children().Single("id==1175"); - - Assert.IsNotNull(result); - Assert.AreEqual(1175, result.Id); - } - - [Test] - public void First() - { - var doc = GetDynamicNode(1173); - - var result = doc.Children().First(); - - Assert.IsNotNull(result); - Assert.AreEqual(1174, result.Id); - } - - [Test] - public void First_With_Query() - { - var doc = GetDynamicNode(1173); - - var result = doc.Children().First("blah==\"some content\""); - - Assert.IsNotNull(result); - Assert.AreEqual(1176, result.Id); - } - - [Test] - public void Where_User_Property_Value() - { - var doc = GetDynamicNode(1173); - - var result = (IEnumerable)doc.Children().Where("blah==\"some content\""); - - Assert.IsNotNull(result); - Assert.AreEqual(1, result.Count()); - Assert.AreEqual(1176, result.Single().Id); - } - - [Test] - public void String_ContainsValue_Extension_Method() - { - var doc = GetDynamicNode(1046); - - var paramVals = new Dictionary { { "searchId", 1173 } }; //this is an integer value - var result = doc.Children() - .Where("selectedNodes.ContainsValue(searchId)", paramVals) //call an extension method - .FirstOrDefault(); - - Assert.IsNotNull(result); - Assert.AreEqual(4444, result.Id); - - //don't find! - paramVals = new Dictionary { { "searchId", 1111777 } }; - result = doc.Children() - .Where("selectedNodes.ContainsValue(searchId)", paramVals) - .FirstOrDefault(); - - Assert.IsNotNull(result); - Assert.IsTrue(result.GetType() == typeof(DynamicNull)); - //Assert.AreEqual(typeof(DynamicNull), result.GetType()); - } - - [Test] - public void String_Contains_Method() - { - var doc = GetDynamicNode(1046); - - var paramVals = new Dictionary { { "searchId", "1173" } }; - var result = doc.Children() - .Where("selectedNodes.Contains(searchId)", paramVals) - .FirstOrDefault(); - - Assert.IsNotNull(result); - Assert.AreEqual(4444, result.Id); - - //don't find! - paramVals = new Dictionary { { "searchId", "1aaa173" } }; - result = doc.Children() - .Where("selectedNodes.Contains(searchId)", paramVals) - .FirstOrDefault(); - - Assert.IsNotNull(result); - Assert.IsTrue(result.GetType() == typeof (DynamicNull)); - //Assert.AreEqual(typeof (DynamicNull), result.GetType()); - } - - [Test] - public void String_Split_Method() - { - var doc = GetDynamicNode(1046); - - var paramVals = new Dictionary - { - { "splitTerm", new char[] { ',' } }, - { "splitOptions", StringSplitOptions.RemoveEmptyEntries } - }; - var result = doc.Children() - .Where("selectedNodes.Split(splitTerm, splitOptions).Length == 3", paramVals) - .FirstOrDefault(); - - Assert.IsNotNull(result); - Assert.AreEqual(4444, result.Id); - } - - [Ignore("We are ignoring this test because currently our ExpressionParser class cannot deal with this... it needs some serious TLC but it is very complex.")] - [Test] - public void Complex_Linq() - { - var doc = GetDynamicNode(1173); - - var paramVals = new Dictionary {{"splitTerm", new char[] {','}}, {"searchId", "1173"}}; - var result = doc.Ancestors().OrderBy("level") - .Single() - .Descendants() - .Where("selectedNodes != null && selectedNodes != String.Empty && selectedNodes.Split(splitTerm).Contains(searchId)", paramVals) - .FirstOrDefault(); - - Assert.IsNotNull(result); - Assert.AreEqual(4444, result.Id); - } - - [Test] - public void Index() - { - var doc = GetDynamicNode(1173); - Assert.AreEqual(0, doc.Index()); - doc = GetDynamicNode(1176); - Assert.AreEqual(3, doc.Index()); - doc = GetDynamicNode(1177); - Assert.AreEqual(1, doc.Index()); - doc = GetDynamicNode(1178); - Assert.AreEqual(2, doc.Index()); - } - - [Test] - public virtual void Is_First_Root_Nodes() - { - var doc = GetDynamicNode(1046); //test root nodes - Assert.IsTrue(doc.IsFirst()); - doc = GetDynamicNode(1172); - Assert.IsFalse(doc.IsFirst()); - } - [Test] - public void Is_First() + public void Children_Order_By_Update_Date_Descending() { - var doc = GetDynamicNode(1173); //test normal nodes - Assert.IsTrue(doc.IsFirst()); - doc = GetDynamicNode(1175); - Assert.IsFalse(doc.IsFirst()); + var asDynamic = GetDynamicNode(1173); + + var ordered = asDynamic.Children.OrderBy("UpdateDate desc"); + var casted = (IEnumerable) ordered; + + var correctOrder = new[] { 1176, 1174, 1177, 1178 }; + for (var i = 0; i < correctOrder.Length; i++) + { + Assert.AreEqual(correctOrder[i], ((dynamic) casted.ElementAt(i)).Id); + } + } [Test] - public virtual void Is_Not_First_Root_Nodes() + public void HasProperty() { - var doc = GetDynamicNode(1046); //test root nodes - Assert.IsFalse(doc.IsNotFirst()); - doc = GetDynamicNode(1172); - Assert.IsTrue(doc.IsNotFirst()); - } + var asDynamic = GetDynamicNode(1173); - [Test] - public void Is_Not_First() - { - var doc = GetDynamicNode(1173); //test normal nodes - Assert.IsFalse(doc.IsNotFirst()); - doc = GetDynamicNode(1175); - Assert.IsTrue(doc.IsNotFirst()); - } + var hasProp = asDynamic.HasProperty(Constants.Conventions.Content.UrlAlias); + + Assert.AreEqual(true, (bool) hasProp); + + } [Test] - public virtual void Is_Position_Root_Nodes() + public void Skip() { - var doc = GetDynamicNode(1046); //test root nodes - Assert.IsTrue(doc.IsPosition(0)); - doc = GetDynamicNode(1172); - Assert.IsTrue(doc.IsPosition(1)); + var asDynamic = GetDynamicNode(1173); + + var skip = asDynamic.Children.Skip(2); + var casted = (IEnumerable) skip; + + Assert.AreEqual(2, casted.Count()); + Assert.IsTrue(casted.Select(x => ((dynamic) x).Id).ContainsAll(new dynamic[] { 1178, 1176 })); + } - [Test] - public void Is_Position() - { - var doc = GetDynamicNode(1173); //test normal nodes - Assert.IsTrue(doc.IsPosition(0)); - doc = GetDynamicNode(1175); - Assert.IsTrue(doc.IsPosition(1)); - } + [Test] + public void HasValue() + { + var asDynamic = GetDynamicNode(1173); - [Test] - public void Children_GroupBy_DocumentTypeAlias() - { - var doc = GetDynamicNode(1046); + var hasValue = asDynamic.HasValue(Constants.Conventions.Content.UrlAlias); + var noValue = asDynamic.HasValue("blahblahblah"); - var found1 = doc.Children.GroupBy("DocumentTypeAlias"); + Assert.IsTrue(hasValue); + Assert.IsFalse(noValue); + } - var casted = (IEnumerable>)(found1); - Assert.AreEqual(2, casted.Count()); - Assert.AreEqual(2, casted.Single(x => x.Key.ToString() == "Home").Count()); - Assert.AreEqual(1, casted.Single(x => x.Key.ToString() == "CustomDocument").Count()); - } + [Test] + public void Take() + { + var asDynamic = GetDynamicNode(1173); - [Test] - public void Children_Where_DocumentTypeAlias() - { - var doc = GetDynamicNode(1046); + var take = asDynamic.Children.Take(2); + var casted = (IEnumerable) take; - var found1 = doc.Children.Where("DocumentTypeAlias == \"CustomDocument\""); - var found2 = doc.Children.Where("DocumentTypeAlias == \"Home\""); + Assert.AreEqual(2, casted.Count()); + Assert.IsTrue(casted.Select(x => ((dynamic) x).Id).ContainsAll(new dynamic[] { 1174, 1177 })); + } - Assert.AreEqual(1, found1.Count()); - Assert.AreEqual(2, found2.Count()); - } + [Test] + public void Ancestors_Where_Visible() + { + var asDynamic = GetDynamicNode(1174); - [Test] - public void Children_Where_NodeTypeAlias() - { - var doc = GetDynamicNode(1046); + var whereVisible = asDynamic.Ancestors().Where("Visible"); + var casted = (IEnumerable) whereVisible; - var found1 = doc.Children.Where("NodeTypeAlias == \"CustomDocument\""); - var found2 = doc.Children.Where("NodeTypeAlias == \"Home\""); + Assert.AreEqual(1, casted.Count()); - Assert.AreEqual(1, found1.Count()); - Assert.AreEqual(2, found2.Count()); - } + } - [Test] - public void Children_Order_By_Update_Date() - { - var asDynamic = GetDynamicNode(1173); + [Test] + public void Visible() + { + var asDynamicHidden = GetDynamicNode(1046); + var asDynamicVisible = GetDynamicNode(1173); - var ordered = asDynamic.Children.OrderBy("UpdateDate"); - var casted = (IEnumerable)ordered; + Assert.IsFalse(asDynamicHidden.Visible); + Assert.IsTrue(asDynamicVisible.Visible); + } - var correctOrder = new[] { 1178, 1177, 1174, 1176 }; - for (var i = 0; i < correctOrder.Length ;i++) - { - Assert.AreEqual(correctOrder[i], ((dynamic)casted.ElementAt(i)).Id); - } + [Test] + public void Ensure_TinyMCE_Converted_Type_User_Property() + { + var asDynamic = GetDynamicNode(1173); - } + Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(asDynamic.Content.GetType())); + Assert.AreEqual("
This is some content
", asDynamic.Content.ToString()); + } - [Test] - public void Children_Order_By_Update_Date_Descending() - { - var asDynamic = GetDynamicNode(1173); + [Test] + public void Get_Children_With_Pluralized_Alias() + { + var asDynamic = GetDynamicNode(1173); - var ordered = asDynamic.Children.OrderBy("UpdateDate desc"); - var casted = (IEnumerable)ordered; + Action doAssert = d => + { + Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(d)); + var casted = (IEnumerable) d; + Assert.AreEqual(2, casted.Count()); + }; - var correctOrder = new[] { 1176, 1174, 1177, 1178 }; - for (var i = 0; i < correctOrder.Length; i++) - { - Assert.AreEqual(correctOrder[i], ((dynamic)casted.ElementAt(i)).Id); - } + doAssert(asDynamic.Homes); //pluralized alias + doAssert(asDynamic.homes); //pluralized alias + doAssert(asDynamic.CustomDocuments); //pluralized alias + doAssert(asDynamic.customDocuments); //pluralized alias + } - } + [Test] + public void GetPropertyValue_Non_Reflected() + { + var asDynamic = GetDynamicNode(1174); - [Test] - public void HasProperty() - { - var asDynamic = GetDynamicNode(1173); + Assert.AreEqual("Custom data with same property name as the member name", asDynamic.GetPropertyValue("creatorName")); + Assert.AreEqual("Custom data with same property name as the member name", asDynamic.GetPropertyValue("CreatorName")); + } - var hasProp = asDynamic.HasProperty(Constants.Conventions.Content.UrlAlias); + [Test] + public void Get_User_Property_With_Same_Name_As_Member_Property() + { + var asDynamic = GetDynamicNode(1174); - Assert.AreEqual(true, (bool)hasProp); + Assert.AreEqual("Custom data with same property name as the member name", asDynamic.creatorName); - } + //because CreatorName is defined on DynamicNode, it will not return the user defined property + Assert.AreEqual("admin", asDynamic.CreatorName); + } - [Test] - public void Skip() - { - var asDynamic = GetDynamicNode(1173); + [Test] + public void Get_Member_Property() + { + var asDynamic = GetDynamicNode(1173); - var skip = asDynamic.Children.Skip(2); - var casted = (IEnumerable)skip; + Assert.AreEqual((int) 2, (int) asDynamic.Level); + Assert.AreEqual((int) 2, (int) asDynamic.level); - Assert.AreEqual(2, casted.Count()); - Assert.IsTrue(casted.Select(x => ((dynamic) x).Id).ContainsAll(new dynamic[] {1178, 1176})); + Assert.AreEqual((int) 1046, (int) asDynamic.ParentId); + Assert.AreEqual((int) 1046, (int) asDynamic.parentId); + } - } + [Test] + public void Get_Children() + { + var asDynamic = GetDynamicNode(1173); - [Test] - public void HasValue() - { - var asDynamic = GetDynamicNode(1173); + var children = asDynamic.Children; + Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(children)); - var hasValue = asDynamic.HasValue(Constants.Conventions.Content.UrlAlias); - var noValue = asDynamic.HasValue("blahblahblah"); + var childrenAsList = asDynamic.ChildrenAsList; //test ChildrenAsList too + Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(childrenAsList)); - Assert.IsTrue(hasValue); - Assert.IsFalse(noValue); - } + var castChildren = (IEnumerable) children; + Assert.AreEqual(4, castChildren.Count()); - [Test] - public void Take() - { - var asDynamic = GetDynamicNode(1173); - - var take = asDynamic.Children.Take(2); - var casted = (IEnumerable)take; + var castChildrenAsList = (IEnumerable) childrenAsList; + Assert.AreEqual(4, castChildrenAsList.Count()); + } - Assert.AreEqual(2, casted.Count()); - Assert.IsTrue(casted.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1174, 1177 })); - } + [Test] + public void Ancestor_Or_Self() + { + var asDynamic = GetDynamicNode(1173); - [Test] - public void Ancestors_Where_Visible() - { - var asDynamic = GetDynamicNode(1174); + var result = asDynamic.AncestorOrSelf(); - var whereVisible = asDynamic.Ancestors().Where("Visible"); - var casted = (IEnumerable)whereVisible; - - Assert.AreEqual(1, casted.Count()); - - } - - [Test] - public void Visible() - { - var asDynamicHidden = GetDynamicNode(1046); - var asDynamicVisible = GetDynamicNode(1173); - - Assert.IsFalse(asDynamicHidden.Visible); - Assert.IsTrue(asDynamicVisible.Visible); - } - - [Test] - public void Ensure_TinyMCE_Converted_Type_User_Property() - { - var asDynamic = GetDynamicNode(1173); - - Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(asDynamic.Content.GetType())); - Assert.AreEqual("
This is some content
", asDynamic.Content.ToString()); - } - - [Test] - public void Get_Children_With_Pluralized_Alias() - { - var asDynamic = GetDynamicNode(1173); - - Action doAssert = d => - { - Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(d)); - var casted = (IEnumerable)d; - Assert.AreEqual(2, casted.Count()); - }; - - doAssert(asDynamic.Homes); //pluralized alias - doAssert(asDynamic.homes); //pluralized alias - doAssert(asDynamic.CustomDocuments); //pluralized alias - doAssert(asDynamic.customDocuments); //pluralized alias - } - - [Test] - public void GetPropertyValue_Non_Reflected() - { - var asDynamic = GetDynamicNode(1174); - - Assert.AreEqual("Custom data with same property name as the member name", asDynamic.GetPropertyValue("creatorName")); - Assert.AreEqual("Custom data with same property name as the member name", asDynamic.GetPropertyValue("CreatorName")); - } - - [Test] - public void Get_User_Property_With_Same_Name_As_Member_Property() - { - var asDynamic = GetDynamicNode(1174); - - Assert.AreEqual("Custom data with same property name as the member name", asDynamic.creatorName); - - //because CreatorName is defined on DynamicNode, it will not return the user defined property - Assert.AreEqual("admin", asDynamic.CreatorName); - } - - [Test] - public void Get_Member_Property() - { - var asDynamic = GetDynamicNode(1173); - - Assert.AreEqual((int) 2, (int) asDynamic.Level); - Assert.AreEqual((int) 2, (int) asDynamic.level); - - Assert.AreEqual((int) 1046, (int) asDynamic.ParentId); - Assert.AreEqual((int) 1046, (int) asDynamic.parentId); - } - - [Test] - public void Get_Children() - { - var asDynamic = GetDynamicNode(1173); - - var children = asDynamic.Children; - Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(children)); - - var childrenAsList = asDynamic.ChildrenAsList; //test ChildrenAsList too - Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(childrenAsList)); - - var castChildren = (IEnumerable)children; - Assert.AreEqual(4, castChildren.Count()); - - var castChildrenAsList = (IEnumerable)childrenAsList; - Assert.AreEqual(4, castChildrenAsList.Count()); - } - - [Test] - public void Ancestor_Or_Self() - { - var asDynamic = GetDynamicNode(1173); - - var result = asDynamic.AncestorOrSelf(); - - Assert.IsNotNull(result); + Assert.IsNotNull(result); // ancestor-or-self has to be self! // but that's not what the "legacy" razor macro engine does... if (result is Umbraco.Web.Models.DynamicPublishedContent) - Assert.AreEqual(1173, (int)result.Id); // that one works + Assert.AreEqual(1173, (int) result.Id); // that one works else - Assert.AreEqual(1046, (int)result.Id); // that one still is fubar - } + Assert.AreEqual(1046, (int) result.Id); // that one still is fubar + } - [Test] - public void Ancestors_Or_Self() - { - var asDynamic = GetDynamicNode(1174); + [Test] + public void Ancestors_Or_Self() + { + var asDynamic = GetDynamicNode(1174); - var result = asDynamic.AncestorsOrSelf(); + var result = asDynamic.AncestorsOrSelf(); - Assert.IsNotNull(result); + Assert.IsNotNull(result); - var list = (IEnumerable)result; - Assert.AreEqual(3, list.Count()); - Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1174, 1173, 1046 })); - } + var list = (IEnumerable) result; + Assert.AreEqual(3, list.Count()); + Assert.IsTrue(list.Select(x => ((dynamic) x).Id).ContainsAll(new dynamic[] { 1174, 1173, 1046 })); + } - [Test] - public void Ancestors() - { - var asDynamic = GetDynamicNode(1174); + [Test] + public void Ancestors() + { + var asDynamic = GetDynamicNode(1174); - var result = asDynamic.Ancestors(); + var result = asDynamic.Ancestors(); - Assert.IsNotNull(result); + Assert.IsNotNull(result); - var list = (IEnumerable)result; - Assert.AreEqual(2, list.Count()); - Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1046 })); - } + var list = (IEnumerable) result; + Assert.AreEqual(2, list.Count()); + Assert.IsTrue(list.Select(x => ((dynamic) x).Id).ContainsAll(new dynamic[] { 1173, 1046 })); + } - [Test] - public void Descendants_Or_Self() - { - var asDynamic = GetDynamicNode(1046); + [Test] + public void Descendants_Or_Self() + { + var asDynamic = GetDynamicNode(1046); - var result = asDynamic.DescendantsOrSelf(); + var result = asDynamic.DescendantsOrSelf(); - Assert.IsNotNull(result); + Assert.IsNotNull(result); - var list = (IEnumerable)result; - Assert.AreEqual(9, list.Count()); - Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1046, 1173, 1174, 1176, 1175, 4444 })); - } + var list = (IEnumerable) result; + Assert.AreEqual(9, list.Count()); + Assert.IsTrue(list.Select(x => ((dynamic) x).Id).ContainsAll(new dynamic[] { 1046, 1173, 1174, 1176, 1175, 4444 })); + } - [Test] - public void Descendants() - { - var asDynamic = GetDynamicNode(1046); + [Test] + public void Descendants() + { + var asDynamic = GetDynamicNode(1046); - var result = asDynamic.Descendants(); + var result = asDynamic.Descendants(); - Assert.IsNotNull(result); + Assert.IsNotNull(result); - var list = (IEnumerable)result; - Assert.AreEqual(8, list.Count()); - Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1174, 1176, 1175, 4444 })); - } + var list = (IEnumerable) result; + Assert.AreEqual(8, list.Count()); + Assert.IsTrue(list.Select(x => ((dynamic) x).Id).ContainsAll(new dynamic[] { 1173, 1174, 1176, 1175, 4444 })); + } - [Test] - public void Up() - { - var asDynamic = GetDynamicNode(1173); + [Test] + public void Up() + { + var asDynamic = GetDynamicNode(1173); - var result = asDynamic.Up(); + var result = asDynamic.Up(); - Assert.IsNotNull(result); + Assert.IsNotNull(result); - Assert.AreEqual((int) 1046, (int) result.Id); - } + Assert.AreEqual((int) 1046, (int) result.Id); + } - [Test] - public void Down() - { - var asDynamic = GetDynamicNode(1173); + [Test] + public void Down() + { + var asDynamic = GetDynamicNode(1173); - var result = asDynamic.Down(); + var result = asDynamic.Down(); - Assert.IsNotNull(result); + Assert.IsNotNull(result); - Assert.AreEqual((int) 1174, (int) result.Id); - } + Assert.AreEqual((int) 1174, (int) result.Id); + } + } - [Test] - public void Next() - { - var asDynamic = GetDynamicNode(1173); - - var result = asDynamic.Next(); - - Assert.IsNotNull(result); - - Assert.AreEqual((int) 1175, (int) result.Id); - } - - [Test] - public void Next_Without_Sibling() - { - var asDynamic = GetDynamicNode(1176); - - Assert.IsNull(asDynamic.Next()); - } - - [Test] - public void Previous_Without_Sibling() - { - var asDynamic = GetDynamicNode(1173); - - Assert.IsNull(asDynamic.Previous()); - } - - [Test] - public void Previous() - { - var asDynamic = GetDynamicNode(1176); - - var result = asDynamic.Previous(); - - Assert.IsNotNull(result); - - Assert.AreEqual((int)1178, (int)result.Id); - } - } - - /// + /// /// Extension methods used in tests /// public static class TestExtensionMethods diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs index 22abc00084..a05c549faa 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs @@ -91,75 +91,39 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual("Content 1", content.Name); } - [Test] - public void DefaultContentSetIsSiblings() - { - var content = UmbracoContext.Current.ContentCache.GetAtRoot().First(); - Assert.AreEqual(0, content.Index()); - Assert.IsTrue(content.IsFirst()); - } - - [Test] - public void RunOnLatestContentSet() - { - // get first content - var content = UmbracoContext.Current.ContentCache.GetAtRoot().First(); - var id = content.Id; - Assert.IsTrue(content.IsFirst()); - - // reverse => should be last, but set has not changed => still first - content = UmbracoContext.Current.ContentCache.GetAtRoot().Reverse().First(x => x.Id == id); - Assert.IsTrue(content.IsFirst()); - Assert.IsFalse(content.IsLast()); - - // reverse + new set => now it's last - content = UmbracoContext.Current.ContentCache.GetAtRoot().Reverse().ToContentSet().First(x => x.Id == id); - Assert.IsFalse(content.IsFirst()); - Assert.IsTrue(content.IsLast()); - - // reverse that set => should be first, but no new set => still last - content = UmbracoContext.Current.ContentCache.GetAtRoot().Reverse().ToContentSet().Reverse().First(x => x.Id == id); - Assert.IsFalse(content.IsFirst()); - Assert.IsTrue(content.IsLast()); - } - [Test] public void Distinct() { - var content = UmbracoContext.Current.ContentCache.GetAtRoot() + var items = UmbracoContext.Current.ContentCache.GetAtRoot() .Distinct() .Distinct() - .ToContentSet() - .First(); + .ToIndexedArray(); - Assert.AreEqual("Content 1", content.Name); - Assert.IsTrue(content.IsFirst()); - Assert.IsFalse(content.IsLast()); + var item = items[0]; + Assert.AreEqual("Content 1", item.Content.Name); + Assert.IsTrue(item.IsFirst()); + Assert.IsFalse(item.IsLast()); - content = content.Next(); - Assert.AreEqual("Content 2", content.Name); - Assert.IsFalse(content.IsFirst()); - Assert.IsFalse(content.IsLast()); + item = items[1]; + Assert.AreEqual("Content 2", item.Content.Name); + Assert.IsFalse(item.IsFirst()); + Assert.IsFalse(item.IsLast()); - content = content.Next(); - Assert.AreEqual("Content 2Sub", content.Name); - Assert.IsFalse(content.IsFirst()); - Assert.IsTrue(content.IsLast()); + item = items[2]; + Assert.AreEqual("Content 2Sub", item.Content.Name); + Assert.IsFalse(item.IsFirst()); + Assert.IsTrue(item.IsLast()); } [Test] public void OfType1() { - var content = UmbracoContext.Current.ContentCache.GetAtRoot() + var items = UmbracoContext.Current.ContentCache.GetAtRoot() .OfType() .Distinct() - .ToArray(); - Assert.AreEqual(2, content.Count()); - Assert.IsInstanceOf(content.First()); - var set = content.ToContentSet(); - Assert.IsInstanceOf(set.First()); - Assert.AreSame(set, set.First().ContentSet); - Assert.IsInstanceOf(set.First().Next()); + .ToIndexedArray(); + Assert.AreEqual(2, items.Length); + Assert.IsInstanceOf(items.First().Content); } [Test] @@ -168,11 +132,9 @@ namespace Umbraco.Tests.PublishedContent var content = UmbracoContext.Current.ContentCache.GetAtRoot() .OfType() .Distinct() - .ToArray(); - Assert.AreEqual(1, content.Count()); - Assert.IsInstanceOf(content.First()); - var set = content.ToContentSet(); - Assert.IsInstanceOf(set.First()); + .ToIndexedArray(); + Assert.AreEqual(1, content.Length); + Assert.IsInstanceOf(content.First().Content); } [Test] @@ -188,17 +150,16 @@ namespace Umbraco.Tests.PublishedContent [Test] public void Position() { - var content = UmbracoContext.Current.ContentCache.GetAtRoot() + var items = UmbracoContext.Current.ContentCache.GetAtRoot() .Where(x => x.GetPropertyValue("prop1") == 1234) - .ToContentSet() - .ToArray(); + .ToIndexedArray(); - Assert.IsTrue(content.First().IsFirst()); - Assert.IsFalse(content.First().IsLast()); - Assert.IsFalse(content.First().Next().IsFirst()); - Assert.IsFalse(content.First().Next().IsLast()); - Assert.IsFalse(content.First().Next().Next().IsFirst()); - Assert.IsTrue(content.First().Next().Next().IsLast()); + Assert.IsTrue(items.First().IsFirst()); + Assert.IsFalse(items.First().IsLast()); + Assert.IsFalse(items.Skip(1).First().IsFirst()); + Assert.IsFalse(items.Skip(1).First().IsLast()); + Assert.IsFalse(items.Skip(2).First().IsFirst()); + Assert.IsTrue(items.Skip(2).First().IsLast()); } [Test] diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs index 5ee9f29305..5b2967c661 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs @@ -199,14 +199,6 @@ namespace Umbraco.Tests.PublishedContent public PublishedItemType ItemType { get { return PublishedItemType.Content; } } public bool IsDraft { get; set; } - public int GetIndex() - { - var index = this.Siblings().FindIndex(x => x.Id == Id); - if (index < 0) - throw new IndexOutOfRangeException("Failed to find content in its siblings collection?!"); - return index; - } - #endregion #region Tree @@ -219,12 +211,6 @@ namespace Umbraco.Tests.PublishedContent #endregion - #region ContentSet - - public IEnumerable ContentSet { get { return this.Siblings(); } } - - #endregion - #region ContentType public PublishedContentType ContentType { get; private set; } diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index b083fa60eb..e1057bfdc3 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -118,49 +118,16 @@ namespace Umbraco.Tests.PublishedContent return doc; } - [Test] - [Ignore("IPublishedContent currently (6.1 as of april 25, 2013) has bugs")] - public void Fails() - { - var content = GetNode(1173); - - var c1 = content.Children.First(x => x.Id == 1177); - Assert.IsFalse(c1.IsFirst()); - - var c2 = content.Children.Where(x => x.DocumentTypeAlias == "CustomDocument").First(x => x.Id == 1177); - Assert.IsTrue(c2.IsFirst()); - - // First is not implemented - var c2a = content.Children.First(x => x.DocumentTypeAlias == "CustomDocument" && x.Id == 1177); - Assert.IsTrue(c2a.IsFirst()); // so here it's luck - - c1 = content.Children.First(x => x.Id == 1177); - Assert.IsFalse(c1.IsFirst()); // and here it fails - - // but even using supported (where) method... - // do not replace by First(x => ...) here since it's not supported at the moment - c1 = content.Children.Where(x => x.Id == 1177).First(); - c2 = content.Children.Where(x => x.DocumentTypeAlias == "CustomDocument" && x.Id == 1177).First(); - - Assert.IsFalse(c1.IsFirst()); // here it fails because c2 has corrupted it - - // so there's only 1 IPublishedContent instance - // which keeps changing collection, ie being modified - // which is *bad* from a cache point of vue - // and from a consistency point of vue... - // => we want clones! - } - [Test] public void Is_Last_From_Where_Filter_Dynamic_Linq() { var doc = GetNode(1173); - var items = doc.Children.Where("Visible").ToContentSet(); + var items = doc.Children.Where("Visible").ToIndexedArray(); foreach (var item in items) { - if (item.Id != 1178) + if (item.Content.Id != 1178) { Assert.IsFalse(item.IsLast()); } @@ -179,13 +146,13 @@ namespace Umbraco.Tests.PublishedContent var items = doc .Children .Where(x => x.IsVisible()) - .ToContentSet(); + .ToIndexedArray(); - Assert.AreEqual(3, items.Count()); + Assert.AreEqual(3, items.Length); foreach (var d in items) { - switch (d.Id) + switch (d.Content.Id) { case 1174: Assert.IsTrue(d.IsFirst()); @@ -228,14 +195,13 @@ namespace Umbraco.Tests.PublishedContent .OfType() // ours, return IEnumerable (actually a PublishedContentSet) .Where(x => x.IsVisible()) // so, here it's linq again :-( - .ToContentSet() // so, we need that one for the test to pass - .ToArray(); + .ToIndexedArray(); // so, we need that one for the test to pass Assert.AreEqual(1, items.Count()); foreach (var d in items) { - switch (d.Id) + switch (d.Content.Id) { case 1174: Assert.IsTrue(d.IsFirst()); @@ -253,11 +219,11 @@ namespace Umbraco.Tests.PublishedContent { var doc = GetNode(1173); - var items = doc.Children.Take(3).ToContentSet(); + var items = doc.Children.Take(3).ToIndexedArray(); foreach (var item in items) { - if (item.Id != 1178) + if (item.Content.Id != 1178) { Assert.IsFalse(item.IsLast()); } @@ -273,9 +239,9 @@ namespace Umbraco.Tests.PublishedContent { var doc = GetNode(1173); - foreach (var d in doc.Children.Skip(1)) + foreach (var d in doc.Children.Skip(1).ToIndexedArray()) { - if (d.Id != 1176) + if (d.Content.Id != 1176) { Assert.IsFalse(d.IsLast()); } @@ -293,11 +259,11 @@ namespace Umbraco.Tests.PublishedContent var items = doc.Children .Concat(new[] { GetNode(1175), GetNode(4444) }) - .ToContentSet(); + .ToIndexedArray(); foreach (var item in items) { - if (item.Id != 4444) + if (item.Content.Id != 4444) { Assert.IsFalse(item.IsLast()); } @@ -362,58 +328,6 @@ namespace Umbraco.Tests.PublishedContent Assert.IsNotNull(result); } - [Test] - public void Index() - { - var doc = GetNode(1173); - Assert.AreEqual(0, doc.Index()); - doc = GetNode(1176); - Assert.AreEqual(3, doc.Index()); - doc = GetNode(1177); - Assert.AreEqual(1, doc.Index()); - doc = GetNode(1178); - Assert.AreEqual(2, doc.Index()); - } - - [Test] - public void Is_First() - { - var doc = GetNode(1046); //test root nodes - Assert.IsTrue(doc.IsFirst()); - doc = GetNode(1172); - Assert.IsFalse(doc.IsFirst()); - doc = GetNode(1173); //test normal nodes - Assert.IsTrue(doc.IsFirst()); - doc = GetNode(1175); - Assert.IsFalse(doc.IsFirst()); - } - - [Test] - public void Is_Not_First() - { - var doc = GetNode(1046); //test root nodes - Assert.IsFalse(doc.IsNotFirst()); - doc = GetNode(1172); - Assert.IsTrue(doc.IsNotFirst()); - doc = GetNode(1173); //test normal nodes - Assert.IsFalse(doc.IsNotFirst()); - doc = GetNode(1175); - Assert.IsTrue(doc.IsNotFirst()); - } - - [Test] - public void Is_Position() - { - var doc = GetNode(1046); //test root nodes - Assert.IsTrue(doc.IsPosition(0)); - doc = GetNode(1172); - Assert.IsTrue(doc.IsPosition(1)); - doc = GetNode(1173); //test normal nodes - Assert.IsTrue(doc.IsPosition(0)); - doc = GetNode(1175); - Assert.IsTrue(doc.IsPosition(1)); - } - [Test] public void Children_GroupBy_DocumentTypeAlias() { @@ -617,46 +531,6 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual((int)1174, (int)result.Id); } - [Test] - public void Next() - { - var doc = GetNode(1173); - - var result = doc.Next(); - - Assert.IsNotNull(result); - - Assert.AreEqual((int)1175, (int)result.Id); - } - - [Test] - public void Next_Without_Sibling() - { - var doc = GetNode(1176); - - Assert.IsNull(doc.Next()); - } - - [Test] - public void Previous_Without_Sibling() - { - var doc = GetNode(1173); - - Assert.IsNull(doc.Previous()); - } - - [Test] - public void Previous() - { - var doc = GetNode(1176); - - var result = doc.Previous(); - - Assert.IsNotNull(result); - - Assert.AreEqual((int)1178, (int)result.Id); - } - [Test] public void DetachedProperty1() { diff --git a/src/Umbraco.Tests/PublishedContent/RootNodeTests.cs b/src/Umbraco.Tests/PublishedContent/RootNodeTests.cs index aca34766d5..bab3477324 100644 --- a/src/Umbraco.Tests/PublishedContent/RootNodeTests.cs +++ b/src/Umbraco.Tests/PublishedContent/RootNodeTests.cs @@ -22,10 +22,6 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual(1, content.Level); Assert.IsNull(content.Parent); - // and yet is has siblings, etc. - var siblings = content.Siblings(); - Assert.AreEqual(2, siblings.Count()); - // non-existing content is null content = ctx.ContentCache.GetById(666); Assert.IsNull(content); diff --git a/src/Umbraco.Web/ExamineExtensions.cs b/src/Umbraco.Web/ExamineExtensions.cs index 00002ed4a7..f52b185d8b 100644 --- a/src/Umbraco.Web/ExamineExtensions.cs +++ b/src/Umbraco.Web/ExamineExtensions.cs @@ -14,14 +14,13 @@ namespace Umbraco.Web /// internal static class ExamineExtensions { - internal static PublishedContentSet ConvertSearchResultToPublishedContent(this IEnumerable results, IPublishedCache cache) + internal static IEnumerable ConvertSearchResultToPublishedContent(this IEnumerable results, IPublishedCache cache) { //TODO: The search result has already returned a result which SHOULD include all of the data to create an IPublishedContent, // however this is currently not the case: // http://examine.codeplex.com/workitem/10350 var list = new List(); - var set = new PublishedContentSet(list); foreach (var result in results.OrderByDescending(x => x.Score)) { @@ -36,16 +35,17 @@ namespace Umbraco.Web // returned by the cache, in case the cache can create real types. // so we have to ask it to please extend itself. - list.Add(content); - var extend = set.MapContent(content); + //var extend = set.MapContent(content); + var extend = PublishedContentExtended.Extend(content); + list.Add(extend); - var property = new PropertyResult("examineScore", + var property = new PropertyResult("examineScore", result.Score, PropertyResultType.CustomProperty); extend.AddProperty(property); } - return set; + return list; } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Models/DynamicPublishedContent.cs b/src/Umbraco.Web/Models/DynamicPublishedContent.cs index f8cd6fc060..2dd1e338ea 100644 --- a/src/Umbraco.Web/Models/DynamicPublishedContent.cs +++ b/src/Umbraco.Web/Models/DynamicPublishedContent.cs @@ -28,13 +28,6 @@ namespace Umbraco.Web.Models protected internal IPublishedContent PublishedContent { get; private set; } private DynamicPublishedContentList _contentList; - // must implement that one if we implement IPublishedContent - public IEnumerable ContentSet - { - // that is a definitively non-efficient way of doing it, though it should work - get { return _contentList ?? (_contentList = new DynamicPublishedContentList(PublishedContent.ContentSet)); } - } - public PublishedContentType ContentType { get { return PublishedContent.ContentType; } } #region Constructors @@ -435,11 +428,6 @@ namespace Umbraco.Web.Models get { return PublishedContent.IsDraft; } } - int IPublishedContent.GetIndex() - { - return PublishedContent.GetIndex(); - } - ICollection IPublishedContent.Properties { get { return PublishedContent.Properties; } @@ -775,20 +763,6 @@ namespace Umbraco.Web.Models #endregion - #region IPublishedContente extension methods - ContentSet - - public int Position() - { - return Index(); - } - - public int Index() - { - return PublishedContent.GetIndex(); - } - - #endregion - #region IPublishedContent extension methods - IsSomething: misc public bool Visible @@ -818,160 +792,6 @@ namespace Umbraco.Web.Models #endregion - #region IPublishedContent extension methods - IsSomething: position in set - - public bool IsFirst() - { - return PublishedContent.IsFirst(); - } - - public HtmlString IsFirst(string valueIfTrue) - { - return PublishedContent.IsFirst(valueIfTrue); - } - - public HtmlString IsFirst(string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsFirst(valueIfTrue, valueIfFalse); - } - - public bool IsNotFirst() - { - return PublishedContent.IsNotFirst(); - } - - public HtmlString IsNotFirst(string valueIfTrue) - { - return PublishedContent.IsNotFirst(valueIfTrue); - } - - public HtmlString IsNotFirst(string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsNotFirst(valueIfTrue, valueIfFalse); - } - - public bool IsPosition(int index) - { - return PublishedContent.IsPosition(index); - } - - public HtmlString IsPosition(int index, string valueIfTrue) - { - return PublishedContent.IsPosition(index, valueIfTrue); - } - - public HtmlString IsPosition(int index, string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsPosition(index, valueIfTrue, valueIfFalse); - } - - public bool IsModZero(int modulus) - { - return PublishedContent.IsModZero(modulus); - } - - public HtmlString IsModZero(int modulus, string valueIfTrue) - { - return PublishedContent.IsModZero(modulus, valueIfTrue); - } - - public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsModZero(modulus, valueIfTrue, valueIfFalse); - } - - public bool IsNotModZero(int modulus) - { - return PublishedContent.IsNotModZero(modulus); - } - - public HtmlString IsNotModZero(int modulus, string valueIfTrue) - { - return PublishedContent.IsNotModZero(modulus, valueIfTrue); - } - - public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsNotModZero(modulus, valueIfTrue, valueIfFalse); - } - - public bool IsNotPosition(int index) - { - return PublishedContent.IsNotPosition(index); - } - - public HtmlString IsNotPosition(int index, string valueIfTrue) - { - return PublishedContent.IsNotPosition(index, valueIfTrue); - } - - public HtmlString IsNotPosition(int index, string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsNotPosition(index, valueIfTrue, valueIfFalse); - } - - public bool IsLast() - { - return PublishedContent.IsLast(); - } - - public HtmlString IsLast(string valueIfTrue) - { - return PublishedContent.IsLast(valueIfTrue); - } - - public HtmlString IsLast(string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsLast(valueIfTrue, valueIfFalse); - } - - public bool IsNotLast() - { - return PublishedContent.IsNotLast(); - } - - public HtmlString IsNotLast(string valueIfTrue) - { - return PublishedContent.IsNotLast(valueIfTrue); - } - - public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsNotLast(valueIfTrue, valueIfFalse); - } - - public bool IsEven() - { - return PublishedContent.IsEven(); - } - - public HtmlString IsEven(string valueIfTrue) - { - return PublishedContent.IsEven(valueIfTrue); - } - - public HtmlString IsEven(string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsEven(valueIfTrue, valueIfFalse); - } - - public bool IsOdd() - { - return PublishedContent.IsOdd(); - } - - public HtmlString IsOdd(string valueIfTrue) - { - return PublishedContent.IsOdd(valueIfTrue); - } - - public HtmlString IsOdd(string valueIfTrue, string valueIfFalse) - { - return PublishedContent.IsOdd(valueIfTrue, valueIfFalse); - } - - #endregion - #region IPublishedContent extension methods - IsSomething: equality public bool IsEqual(DynamicPublishedContent other) @@ -1209,46 +1029,6 @@ namespace Umbraco.Web.Models return PublishedContent.Down(contentTypeAlias).AsDynamicOrNull(); } - public DynamicPublishedContent Next() - { - return PublishedContent.Next().AsDynamicOrNull(); - } - - public DynamicPublishedContent Next(int number) - { - return PublishedContent.Next(number).AsDynamicOrNull(); - } - - public DynamicPublishedContent Next(string contentTypeAlias) - { - return PublishedContent.Next(contentTypeAlias).AsDynamicOrNull(); - } - - public DynamicPublishedContent Previous() - { - return PublishedContent.Previous().AsDynamicOrNull(); - } - - public DynamicPublishedContent Previous(int number) - { - return PublishedContent.Previous(number).AsDynamicOrNull(); - } - - public DynamicPublishedContent Previous(string contentTypeAlias) - { - return PublishedContent.Previous(contentTypeAlias).AsDynamicOrNull(); - } - - public DynamicPublishedContent Sibling(int number) - { - return PublishedContent.Previous(number).AsDynamicOrNull(); - } - - public DynamicPublishedContent Sibling(string contentTypeAlias) - { - return PublishedContent.Previous(contentTypeAlias).AsDynamicOrNull(); - } - #endregion #region Parent diff --git a/src/Umbraco.Web/Models/DynamicPublishedContentList.cs b/src/Umbraco.Web/Models/DynamicPublishedContentList.cs index ef794737a5..8af08bc080 100644 --- a/src/Umbraco.Web/Models/DynamicPublishedContentList.cs +++ b/src/Umbraco.Web/Models/DynamicPublishedContentList.cs @@ -19,7 +19,6 @@ namespace Umbraco.Web.Models public class DynamicPublishedContentList : DynamicObject, IEnumerable { private readonly List _content; - private readonly PublishedContentSet _contentSet; internal readonly List Items; #region Constructor @@ -27,22 +26,19 @@ namespace Umbraco.Web.Models public DynamicPublishedContentList() { _content = new List(); - _contentSet = new PublishedContentSet(_content); Items = new List(); } public DynamicPublishedContentList(IEnumerable items) { _content = items.ToList(); - _contentSet = new PublishedContentSet(_content); - Items = _contentSet.Select(x => new DynamicPublishedContent(x, this)).ToList(); + Items = _content.Select(x => new DynamicPublishedContent(x, this)).ToList(); } public DynamicPublishedContentList(IEnumerable items) { _content = items.Select(x => x.PublishedContent).ToList(); - _contentSet = new PublishedContentSet(_content); - Items = _contentSet.Select(x => new DynamicPublishedContent(x, this)).ToList(); + Items = _content.Select(x => new DynamicPublishedContent(x, this)).ToList(); } #endregion @@ -67,10 +63,7 @@ namespace Umbraco.Web.Models { var content = dynamicContent.PublishedContent; _content.Add(content); - _contentSet.SourceChanged(); - - var setContent = _contentSet.MapContent(content); - Items.Add(new DynamicPublishedContent(setContent, this)); + Items.Add(new DynamicPublishedContent(content, this)); } /// @@ -82,7 +75,6 @@ namespace Umbraco.Web.Models if (Items.Contains(dynamicContent) == false) return; Items.Remove(dynamicContent); _content.Remove(dynamicContent.PublishedContent); - _contentSet.SourceChanged(); } #endregion diff --git a/src/Umbraco.Web/Models/PublishedContentBase.cs b/src/Umbraco.Web/Models/PublishedContentBase.cs index 857d3150c0..a726851f21 100644 --- a/src/Umbraco.Web/Models/PublishedContentBase.cs +++ b/src/Umbraco.Web/Models/PublishedContentBase.cs @@ -115,14 +115,6 @@ namespace Umbraco.Web.Models public abstract bool IsDraft { get; } - public int GetIndex() - { - var index = this.Siblings().FindIndex(x => x.Id == Id); - if (index < 0) - throw new IndexOutOfRangeException("Could not find content in the content set."); - return index; - } - #endregion #region Tree @@ -140,16 +132,6 @@ namespace Umbraco.Web.Models #endregion - #region ContentSet - - public virtual IEnumerable ContentSet - { - // the default content set of a content is its siblings - get { return this.Siblings(); } - } - - #endregion - #region ContentType public abstract PublishedContentType ContentType { get; } diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index c2b078ebcb..7344de2abe 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -452,28 +452,14 @@ namespace Umbraco.Web #endregion - #region ToContentSet + #region ToIndexedArray - /// - /// Returns the content enumerable as a content set. - /// - /// The content enumerable. - /// A content set wrapping the content enumerable. - public static PublishedContentSet ToContentSet(this IEnumerable source) - where T : class, IPublishedContent + public static IndexedArrayItem[] ToIndexedArray(this IEnumerable source) + where TContent : class, IPublishedContent { - return new PublishedContentSet(source); - } - - /// - /// Returns the ordered content enumerable as an ordered content set. - /// - /// The ordered content enumerable. - /// A ordered content set wrapping the ordered content enumerable. - public static PublishedContentOrderedSet ToContentSet(this IOrderedEnumerable source) - where T : class, IPublishedContent - { - return new PublishedContentOrderedSet(source); + var set = source.Select((content, index) => new IndexedArrayItem(content, index)).ToArray(); + foreach (var setItem in set) setItem.TotalCount = set.Length; + return set; } #endregion @@ -552,28 +538,6 @@ namespace Umbraco.Web #endregion - #region ContentSet - - public static int Position(this IPublishedContent content) - { - return content.GetIndex(); - } - - public static int Index(this IPublishedContent content) - { - return content.GetIndex(); - } - - private static int GetIndex(this IPublishedContent content, IEnumerable set) - { - var index = set.FindIndex(n => n.Id == content.Id); - if (index < 0) - throw new IndexOutOfRangeException("Could not find content in the content set."); - return index; - } - - #endregion - #region IsSomething: misc. /// @@ -646,160 +610,6 @@ namespace Umbraco.Web #endregion - #region IsSomething: position in set - - public static bool IsFirst(this IPublishedContent content) - { - return content.GetIndex() == 0; - } - - public static HtmlString IsFirst(this IPublishedContent content, string valueIfTrue) - { - return content.IsFirst(valueIfTrue, string.Empty); - } - - public static HtmlString IsFirst(this IPublishedContent content, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsFirst() ? valueIfTrue : valueIfFalse); - } - - public static bool IsNotFirst(this IPublishedContent content) - { - return content.IsFirst() == false; - } - - public static HtmlString IsNotFirst(this IPublishedContent content, string valueIfTrue) - { - return content.IsNotFirst(valueIfTrue, string.Empty); - } - - public static HtmlString IsNotFirst(this IPublishedContent content, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsNotFirst() ? valueIfTrue : valueIfFalse); - } - - public static bool IsPosition(this IPublishedContent content, int index) - { - return content.GetIndex() == index; - } - - public static HtmlString IsPosition(this IPublishedContent content, int index, string valueIfTrue) - { - return content.IsPosition(index, valueIfTrue, string.Empty); - } - - public static HtmlString IsPosition(this IPublishedContent content, int index, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsPosition(index) ? valueIfTrue : valueIfFalse); - } - - public static bool IsModZero(this IPublishedContent content, int modulus) - { - return content.GetIndex() % modulus == 0; - } - - public static HtmlString IsModZero(this IPublishedContent content, int modulus, string valueIfTrue) - { - return content.IsModZero(modulus, valueIfTrue, string.Empty); - } - - public static HtmlString IsModZero(this IPublishedContent content, int modulus, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsModZero(modulus) ? valueIfTrue : valueIfFalse); - } - - public static bool IsNotModZero(this IPublishedContent content, int modulus) - { - return content.IsModZero(modulus) == false; - } - - public static HtmlString IsNotModZero(this IPublishedContent content, int modulus, string valueIfTrue) - { - return content.IsNotModZero(modulus, valueIfTrue, string.Empty); - } - - public static HtmlString IsNotModZero(this IPublishedContent content, int modulus, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsNotModZero(modulus) ? valueIfTrue : valueIfFalse); - } - - public static bool IsNotPosition(this IPublishedContent content, int index) - { - return content.IsPosition(index) == false; - } - - public static HtmlString IsNotPosition(this IPublishedContent content, int index, string valueIfTrue) - { - return content.IsNotPosition(index, valueIfTrue, string.Empty); - } - - public static HtmlString IsNotPosition(this IPublishedContent content, int index, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsNotPosition(index) ? valueIfTrue : valueIfFalse); - } - - public static bool IsLast(this IPublishedContent content) - { - return content.GetIndex() == content.ContentSet.Count() - 1; - } - - public static HtmlString IsLast(this IPublishedContent content, string valueIfTrue) - { - return content.IsLast(valueIfTrue, string.Empty); - } - - public static HtmlString IsLast(this IPublishedContent content, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsLast() ? valueIfTrue : valueIfFalse); - } - - public static bool IsNotLast(this IPublishedContent content) - { - return content.IsLast() == false; - } - - public static HtmlString IsNotLast(this IPublishedContent content, string valueIfTrue) - { - return content.IsNotLast(valueIfTrue, string.Empty); - } - - public static HtmlString IsNotLast(this IPublishedContent content, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsNotLast() ? valueIfTrue : valueIfFalse); - } - - public static bool IsEven(this IPublishedContent content) - { - return content.GetIndex() % 2 == 0; - } - - public static HtmlString IsEven(this IPublishedContent content, string valueIfTrue) - { - return content.IsEven(valueIfTrue, string.Empty); - } - - public static HtmlString IsEven(this IPublishedContent content, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsEven() ? valueIfTrue : valueIfFalse); - } - - public static bool IsOdd(this IPublishedContent content) - { - return content.GetIndex() % 2 == 1; - } - - public static HtmlString IsOdd(this IPublishedContent content, string valueIfTrue) - { - return content.IsOdd(valueIfTrue, string.Empty); - } - - public static HtmlString IsOdd(this IPublishedContent content, string valueIfTrue, string valueIfFalse) - { - return new HtmlString(content.IsOdd() ? valueIfTrue : valueIfFalse); - } - - #endregion - #region IsSomething: equality public static bool IsEqual(this IPublishedContent content, IPublishedContent other) @@ -1440,250 +1250,6 @@ namespace Umbraco.Web return content.Descendant(contentTypeAlias); } - // next pseudo-axe ~ following within the content set - // bogus, kept for backward compatibility but we should get rid of it - - public static IPublishedContent Next(this IPublishedContent content) - { - return content.ContentSet.ElementAtOrDefault(content.GetIndex() + 1); - } - - public static IPublishedContent Next(this IPublishedContent current, Func func) { - IPublishedContent next = current.Next(); - while (next != null) { - if (func(next)) return next; - next = next.Next(); - } - return null; - } - - public static IPublishedContent Next(this IPublishedContent content, int number) - { - if (number < 0) - throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero."); - return number == 0 ? content : content.ContentSet.ElementAtOrDefault(content.GetIndex() + number); - } - - public static IPublishedContent Next(this IPublishedContent content, string contentTypeAlias) - { - return content.Next(contentTypeAlias, false); - } - - public static IPublishedContent Next(this IPublishedContent content, string contentTypeAlias, bool wrap) - { - return content.Next(content.ContentSet, x => x.DocumentTypeAlias.InvariantEquals(contentTypeAlias), wrap); - } - - public static T Next(this IPublishedContent content) - where T : class, IPublishedContent - { - return content.Next(false); - } - - public static T Next(this IPublishedContent content, bool wrap) - where T : class, IPublishedContent - { - return content.Next(content.ContentSet, x => x is T, wrap) as T; - } - - static IPublishedContent Next(this IPublishedContent content, IEnumerable axis, Func predicate, bool wrap) - { - var b4 = true; - IPublishedContent wrapped = null; - foreach (var c in axis) - { - if (b4) - { - if (c.Id == content.Id) - b4 = false; - else if (wrap && wrapped == null && predicate(c)) - wrapped = c; - continue; - } - if (predicate(c)) - return c; - } - - return wrapped; - } - - // previous pseudo-axe ~ preceding within the content set - // bogus, kept for backward compatibility but we should get rid of it - - public static IPublishedContent Previous(this IPublishedContent content) - { - return content.ContentSet.ElementAtOrDefault(content.GetIndex() - 1); - } - - public static IPublishedContent Previous(this IPublishedContent current, Func func) { - IPublishedContent prev = current.Previous(); - while (prev != null) { - if (func(prev)) return prev; - prev = prev.Previous(); - } - return null; - } - - public static IPublishedContent Previous(this IPublishedContent content, int number) - { - if (number < 0) - throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero."); - return number == 0 ? content : content.ContentSet.ElementAtOrDefault(content.GetIndex() - number); - } - - public static IPublishedContent Previous(this IPublishedContent content, string contentTypeAlias) - { - return content.Previous(contentTypeAlias, false); - } - - public static IPublishedContent Previous(this IPublishedContent content, string contentTypeAlias, bool wrap) - { - return content.Next(content.ContentSet.Reverse(), x => x.DocumentTypeAlias.InvariantEquals(contentTypeAlias), wrap); - } - - public static T Previous(this IPublishedContent content) - where T : class, IPublishedContent - { - return content.Previous(false); - } - - public static T Previous(this IPublishedContent content, bool wrap) - where T : class, IPublishedContent - { - return content.Next(content.ContentSet.Reverse(), x => x is T, wrap) as T; - } - - // - - [Obsolete("Obsolete, use FollowingSibling or PrecedingSibling instead.")] - public static IPublishedContent Sibling(this IPublishedContent content, int number) - { - if (number < 0) - throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero."); - number += 1; // legacy is zero-based - return content.FollowingSibling(number); - } - - // contentTypeAlias is case-insensitive - [Obsolete("Obsolete, use FollowingSibling or PrecedingSibling instead.")] - public static IPublishedContent Sibling(this IPublishedContent content, string contentTypeAlias) - { - // note: the original implementation seems to loop on all siblings - // ie if it reaches the end of the set, it starts again at the beginning. - // so here we wrap, although it's not consistent... but anyway those - // methods should be obsoleted. - - return content.FollowingSibling(contentTypeAlias, true); - } - - // following-sibling, preceding-sibling axes - - public static IPublishedContent FollowingSibling(this IPublishedContent content) - { - return content.Siblings().ElementAtOrDefault(content.GetIndex(content.Siblings()) + 1); - } - - public static IPublishedContent FollowingSibling(this IPublishedContent content, int number) - { - if (number < 0) - throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero."); - return number == 0 ? content : content.Siblings().ElementAtOrDefault(content.GetIndex(content.Siblings()) + number); - } - - // contentTypeAlias is case-insensitive - public static IPublishedContent FollowingSibling(this IPublishedContent content, string contentTypeAlias) - { - return content.FollowingSibling(contentTypeAlias, false); - } - - // contentTypeAlias is case-insensitive - // note: not sure that one makes a lot of sense but it is here for backward compatibility - public static IPublishedContent FollowingSibling(this IPublishedContent content, string contentTypeAlias, bool wrap) - { - return content.Next(content.Siblings(), x => x.DocumentTypeAlias.InvariantEquals(contentTypeAlias), wrap); - } - - public static T FollowingSibling(this IPublishedContent content) - where T : class, IPublishedContent - { - return content.FollowingSibling(false); - } - - public static T FollowingSibling(this IPublishedContent content, bool wrap) - where T : class, IPublishedContent - { - return content.Next(content.Siblings(), x => x is T, wrap) as T; - } - - public static IPublishedContent PrecedingSibling(this IPublishedContent content) - { - return content.Siblings().ElementAtOrDefault(content.GetIndex(content.Siblings()) - 1); - } - - public static IPublishedContent PrecedingSibling(this IPublishedContent content, int number) - { - if (number < 0) - throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero."); - return number == 0 ? content : content.Siblings().ElementAtOrDefault(content.GetIndex(content.Siblings()) - number); - } - - // contentTypeAlias is case-insensitive - public static IPublishedContent PrecedingSibling(this IPublishedContent content, string contentTypeAlias) - { - return content.PrecedingSibling(contentTypeAlias, false); - } - - // contentTypeAlias is case-insensitive - // note: not sure that one makes a lot of sense but it is here for backward compatibility - public static IPublishedContent PrecedingSibling(this IPublishedContent content, string contentTypeAlias, bool wrap) - { - return content.Next(content.Siblings().Reverse(), x => x.DocumentTypeAlias.InvariantEquals(contentTypeAlias), wrap); - } - - public static T PrecedingSibling(this IPublishedContent content) - where T : class, IPublishedContent - { - return content.PrecedingSibling(false); - } - - public static T PrecedingSibling(this IPublishedContent content, bool wrap) - where T : class, IPublishedContent - { - return content.Next(content.Siblings().Reverse(), x => x is T, wrap) as T; - } - - // following, preceding axes - NOT IMPLEMENTED - - // utilities - - public static IEnumerable Siblings(this IPublishedContent content) - { - // content.Parent, content.Children and cache.GetAtRoot() should be fast enough, - // or cached by the content cache, so that we don't have to implement cache here. - - // returns the true tree siblings, even if the content is in a set - // get the root docs if parent is null - - // note: I don't like having to refer to the "current" content cache here, but - // what else? would need root content to have a special, non-null but hidden, - // parent... - - - - var siblings = content.Parent == null - ? content.ItemType == PublishedItemType.Media ? UmbracoContext.Current.MediaCache.GetAtRoot() : UmbracoContext.Current.ContentCache.GetAtRoot() - : content.Parent.Children; - - // make sure we run it once - return siblings.ToArray(); - } - - public static IEnumerable Siblings(this IPublishedContent content) - where T : class, IPublishedContent - { - return content.Siblings().OfType(); - } - #endregion #region Axes: parent