diff --git a/src/Umbraco.Tests/PublishedContent/ModelsAndConvertersTests.cs b/src/Umbraco.Tests/PublishedContent/ModelsAndConvertersTests.cs index 665ab2c6af..1b07082ab5 100644 --- a/src/Umbraco.Tests/PublishedContent/ModelsAndConvertersTests.cs +++ b/src/Umbraco.Tests/PublishedContent/ModelsAndConvertersTests.cs @@ -16,15 +16,6 @@ namespace Umbraco.Tests.PublishedContent [TestFixture] public class ModelsAndConvertersTests { - // fixme - // naming: IPublishedProperty is IPropertySetProperty or IFacadeProperty of some sort - // naming: general naming sucks at the moment - // caching: re-think how properties are cached - // - for true NuCache content it probably is OK (but needs explanation) - // - for true Xml cache content it probably is OK (but needs explanation) - // - for pure sets, I have no idea - should at least cache at content level? - // hold on - PropertySetPropertyBase probably handles it - need to check - #region ModelType [Test] @@ -417,7 +408,9 @@ namespace Umbraco.Tests.PublishedContent .Setup(x => x.CreateSetProperty(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns((propertyType, set, previewing, refCacheLevel, value) => { + // ReSharper disable AccessToModifiedClosure return new TestPropertySetProperty(propertyType, set, previewing, refCacheLevel, value, () => snapshotCache, () => facadeCache); + // ReSharper restore AccessToModifiedClosure }); var facadeService = facadeServiceMock.Object; @@ -449,6 +442,7 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual(snapshotCount2, snapshotCache.Count); Assert.AreEqual(facadeCount2, facadeCache.Count); + Assert.AreEqual(facadeCount2, oldFacadeCache.Count); Assert.AreEqual((interConverts == 1 ? 1 : 3) + facadeCache.Count, converter.InterConverts); @@ -459,6 +453,7 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual(1, converter.SourceConverts); Assert.AreEqual(snapshotCount2, snapshotCache.Count); + Assert.AreEqual(snapshotCount2, oldSnapshotCache.Count); Assert.AreEqual(facadeCount2, facadeCache.Count); Assert.AreEqual((interConverts == 1 ? 1 : 4) + facadeCache.Count + snapshotCache.Count, converter.InterConverts); @@ -481,7 +476,7 @@ namespace Umbraco.Tests.PublishedContent Assert.Throws(() => { - var set1 = new PropertySet(setType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false); + var unused = new PropertySet(setType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false); }); } diff --git a/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/CallingMethodTests.cs b/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/CallingMethodTests.cs deleted file mode 100644 index 2c023743c1..0000000000 --- a/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/CallingMethodTests.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.CompilerServices; -using NUnit.Framework; - -namespace Umbraco.Tests.PublishedContent.StronglyTypedModels -{ - [TestFixture] - public class CallingMethodTests - { - private readonly Func _myProperty = MethodBase.GetCurrentMethod; - - public string AField - { - // that attribute is REQUIRED for the test to work in RELEASE mode - // and then it kills performance, probably, so that whole way of - // doing things is probably a Bad Thing. - [MethodImpl(MethodImplOptions.NoInlining)] - get { return Resolve(_myProperty()); } - } - - public string AField2 - { - get { return Resolve2(); } - } - - private string Resolve(MethodBase m) - { - return m.Name.Replace("get_", ""); - } - - // that would be the correct way of doing it, works in RELEASE mode - // as well as DEBUG and is optimized, etc - public string Resolve2([CallerMemberName] string memberName = null) - { - return memberName; - } - - [Test] - public void GetMyName() - { - Assert.AreEqual("AField", AField); - } - - [Test] - public void GetMyName2() - { - Assert.AreEqual("AField2", AField2); - } - } -} diff --git a/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/Subpage.cs b/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/Subpage.cs deleted file mode 100644 index f69488d308..0000000000 --- a/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/Subpage.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.Models; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Tests.PublishedContent.StronglyTypedModels -{ - /// - /// Represents a Subpage which acts as the strongly typed model for a Doc Type - /// with alias "Subpage" and "Subpage" as the allowed child type. - /// - /// Similar to the Textpage this model could also be generated, but it could also - /// act as a Code-First model by using the attributes shown on the various properties, - /// which decorate the model with information about the Document Type, its - /// Property Groups and Property Types. - /// - public class Subpage : TypedModelBase - { - public Subpage(IPublishedContent publishedContent) : base(publishedContent) - { - } - - public string Title { get { return Resolve(Property()); } } - - public string BodyText { get { return Resolve(Property()); } } - - public new Textpage Parent - { - get - { - return Parent(); - } - } - - public IEnumerable Subpages - { - get - { - return Children(ContentTypeAlias()); - } - } - } -} diff --git a/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/Textpage.cs b/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/Textpage.cs deleted file mode 100644 index 26b4d7d72f..0000000000 --- a/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/Textpage.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using Umbraco.Core.Models; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Tests.PublishedContent.StronglyTypedModels -{ - /// - /// Represents a Textpage which acts as the strongly typed model for a Doc Type - /// with alias "Textpage" and "Subpage" as the allowed child type. - /// - /// The basic properties are resolved by convention using the Resolve-Type-PropertyTypeAlias - /// convention available through the base class' protected Resolve-method and Property-delegate. - /// - /// The Textpage allows the use of Subpage and Textpage as child doc types, which are exposed as a - /// collection using the Children-Type-ContentTypeAlias convention available through the - /// base class' protected Children-method and ContentTypeAlias-delegate. - /// - /// - /// This code can easily be generated using simple conventions for the types and names - /// of the properties that this type of strongly typed model exposes. - /// - public class Textpage : TypedModelBase - { - public Textpage(IPublishedContent publishedContent) : base(publishedContent) - { - } - - public string Title { get { return Resolve(Property()); } } - - public string BodyText { get { return Resolve(Property()); } } - - public string AuthorName { get { return Resolve(Property()); } } - - public DateTime Date { get { return Resolve(Property()); } } - - public new Textpage Parent - { - get - { - return Parent(); - } - } - - public IEnumerable Textpages - { - get - { - return Children(ContentTypeAlias()); - } - } - - public IEnumerable Subpages - { - get - { - return Children(ContentTypeAlias()); - } - } - } -} diff --git a/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/TypedModelBase.cs b/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/TypedModelBase.cs deleted file mode 100644 index 12eea94f7c..0000000000 --- a/src/Umbraco.Tests/PublishedContent/StronglyTypedModels/TypedModelBase.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data.Entity.Design.PluralizationServices; -using System.Globalization; -using System.Reflection; -using System.Linq; -using Umbraco.Core; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web; - -namespace Umbraco.Tests.PublishedContent.StronglyTypedModels -{ - /// - /// Represents the abstract base class for a 'TypedModel', which basically wraps IPublishedContent - /// underneath a strongly typed model like "Textpage" and "Subpage". - /// Because IPublishedContent is used under the hood there is no need for additional mapping, so the - /// only added cost should be the creation of the objects, which the IPublishedContent instance is - /// passed into. - /// - /// This base class exposes a simple way to write property getters by convention without - /// using the string alias of a PropertyType (this is resolved by the use of the Property delegate). - /// - /// This base class also exposes query options like Parent, Children, Ancestors and Descendants, - /// which can be used for collections of strongly typed child models/objects. These types of collections - /// typically corresponds to 'allowed child content types' on a Doc Type (at different levels). - /// - /// The IPublishedContent properties are also exposed through this base class, but only - /// by casting the typed model to IPublishedContent, so the properties doesn't show up by default: - /// ie. ((IPublishedContent)textpage).Url - /// - public abstract class TypedModelBase : PublishedContentWrapped // IPublishedContent - { - protected TypedModelBase(IPublishedContent publishedContent) - : base(publishedContent) - { } - - protected readonly Func Property = MethodBase.GetCurrentMethod; - protected readonly Func ContentTypeAlias = MethodBase.GetCurrentMethod; - - #region Properties - - protected T Resolve(MethodBase methodBase) - { - var propertyTypeAlias = methodBase.ToUmbracoAlias(); - return Resolve(propertyTypeAlias); - } - - protected T Resolve(string propertyTypeAlias) - { - return Content.Value(propertyTypeAlias); - } - - protected T Resolve(MethodBase methodBase, T ifCannotConvert) - { - var propertyTypeAlias = methodBase.ToUmbracoAlias(); - return Resolve(propertyTypeAlias, ifCannotConvert); - } - - protected T Resolve(string propertyTypeAlias, T ifCannotConvert) - { - return Content.Value(propertyTypeAlias, false, ifCannotConvert); - } - - protected T Resolve(MethodBase methodBase, bool recursive, T ifCannotConvert) - { - var propertyTypeAlias = methodBase.ToUmbracoAlias(); - return Resolve(propertyTypeAlias, recursive, ifCannotConvert); - } - - protected T Resolve(string propertyTypeAlias, bool recursive, T ifCannotConvert) - { - return Content.Value(propertyTypeAlias, recursive, ifCannotConvert); - } - #endregion - - #region Querying - protected T Parent() where T : TypedModelBase - { - var constructorInfo = typeof(T).GetConstructor(new[] { typeof(IPublishedContent) }); - if (constructorInfo == null) - throw new Exception("No valid constructor found"); - - return (T) constructorInfo.Invoke(new object[] {Content.Parent}); - } - - protected IEnumerable Children(MethodBase methodBase) where T : TypedModelBase - { - var docTypeAlias = methodBase.CleanCallingMethodName(); - return Children(docTypeAlias); - } - - protected IEnumerable Children(string docTypeAlias) where T : TypedModelBase - { - var constructorInfo = typeof(T).GetConstructor(new[] { typeof(IPublishedContent) }); - if(constructorInfo == null) - throw new Exception("No valid constructor found"); - - string singularizedDocTypeAlias = docTypeAlias.ToSingular(); - - return Content.Children.Where(x => x.DocumentTypeAlias == singularizedDocTypeAlias) - .Select(x => (T)constructorInfo.Invoke(new object[] { x })); - } - - protected IEnumerable Ancestors(MethodBase methodBase) where T : TypedModelBase - { - var docTypeAlias = methodBase.CleanCallingMethodName(); - return Ancestors(docTypeAlias); - } - - protected IEnumerable Ancestors(string docTypeAlias) where T : TypedModelBase - { - var constructorInfo = typeof(T).GetConstructor(new[] { typeof(IPublishedContent) }); - if (constructorInfo == null) - throw new Exception("No valid constructor found"); - - string singularizedDocTypeAlias = docTypeAlias.ToSingular(); - - return Content.Ancestors().Where(x => x.DocumentTypeAlias == singularizedDocTypeAlias) - .Select(x => (T)constructorInfo.Invoke(new object[] { x })); - } - - protected IEnumerable Descendants(MethodBase methodBase) where T : TypedModelBase - { - var docTypeAlias = methodBase.CleanCallingMethodName(); - return Descendants(docTypeAlias); - } - - protected IEnumerable Descendants(string docTypeAlias) where T : TypedModelBase - { - var constructorInfo = typeof(T).GetConstructor(new[] { typeof(IPublishedContent) }); - if (constructorInfo == null) - throw new Exception("No valid constructor found"); - - string singularizedDocTypeAlias = docTypeAlias.ToSingular(); - - return Content.Descendants().Where(x => x.DocumentTypeAlias == singularizedDocTypeAlias) - .Select(x => (T)constructorInfo.Invoke(new object[] { x })); - } - #endregion - } - - /// - /// Extension methods for MethodBase, which are used to clean the name of the calling method "get_BodyText" - /// to "BodyText" and then make it camel case according to the UmbracoAlias convention "bodyText". - /// There is also a string extension for making plural words singular, which is used when going from - /// something like "Subpages" to "Subpage" for Children/Ancestors/Descendants Doc Type aliases. - /// - public static class TypeExtensions - { - public static string CleanCallingMethodName(this MethodBase methodBase) - { - return methodBase.Name.Replace("get_", ""); - } - - public static string ToUmbracoAlias(this MethodBase methodBase) - { - return methodBase.CleanCallingMethodName().ToSafeAlias(); - } - - public static string ToSingular(this string pluralWord) - { - var service = PluralizationService.CreateService(new CultureInfo("en-US")); - if (service.IsPlural(pluralWord)) - return service.Singularize(pluralWord); - - return pluralWord; - } - } -} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 98407a72ec..af951bcd5b 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -374,10 +374,6 @@ - - - -