More code and tests written for deep cloning.
This commit is contained in:
@@ -42,5 +42,27 @@ namespace Umbraco.Core.Models
|
||||
clone.Id = new Lazy<int>(() => id);
|
||||
return clone;
|
||||
}
|
||||
|
||||
protected bool Equals(ContentTypeSort other)
|
||||
{
|
||||
return Id.Value.Equals(other.Id.Value) && string.Equals(Alias, other.Alias);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((ContentTypeSort) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (Id.GetHashCode()*397) ^ Alias.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
@@ -96,5 +97,12 @@ namespace Umbraco.Core.Models
|
||||
if(ParentId == Guid.Empty)
|
||||
_parentId = new Guid("41c7638d-f529-4bff-853e-59a0c2fb1bde");
|
||||
}
|
||||
|
||||
public override object DeepClone()
|
||||
{
|
||||
var clone = (DictionaryItem)base.DeepClone();
|
||||
clone.Translations = Translations.Select(x => (IDictionaryTranslation) x.DeepClone()).ToList();
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,5 +65,12 @@ namespace Umbraco.Core.Models
|
||||
}, _value, ValueSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public override object DeepClone()
|
||||
{
|
||||
var clone = (DictionaryTranslation)base.DeepClone();
|
||||
clone.Language = (ILanguage)Language.DeepClone();
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,5 +107,12 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get { return _relationType.Id; }
|
||||
}
|
||||
|
||||
public override object DeepClone()
|
||||
{
|
||||
var clone = (Relation)base.DeepClone();
|
||||
clone.RelationType = (RelationType)RelationType.DeepClone();
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,5 +118,6 @@ namespace Umbraco.Core.Models
|
||||
}, _childObjectType, ChildObjectTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
@@ -34,7 +35,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
UpdateDate = updateDate;
|
||||
CreateDate = createDate;
|
||||
Key = Id.ToString().EncodeAsGuid();
|
||||
Key = Id.ToString(CultureInfo.InvariantCulture).EncodeAsGuid();
|
||||
Id = id;
|
||||
ServerAddress = serverAddress;
|
||||
ComputerName = computerName;
|
||||
@@ -51,7 +52,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
CreateDate = createDate;
|
||||
UpdateDate = createDate;
|
||||
Key = 0.ToString().EncodeAsGuid();
|
||||
Key = 0.ToString(CultureInfo.InvariantCulture).EncodeAsGuid();
|
||||
ServerAddress = serverAddress;
|
||||
ComputerName = computerName;
|
||||
}
|
||||
|
||||
@@ -132,5 +132,12 @@ namespace Umbraco.Core.Models
|
||||
}, _comment, CommentSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public override object DeepClone()
|
||||
{
|
||||
var clone = (Task) base.DeepClone();
|
||||
clone.TaskType = (TaskType)TaskType.DeepClone();
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
@@ -46,17 +47,20 @@ namespace Umbraco.Core.Models
|
||||
public UmbracoEntity()
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
UmbracoProperties = new List<UmbracoProperty>();
|
||||
}
|
||||
|
||||
public UmbracoEntity(bool trashed)
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
UmbracoProperties = new List<UmbracoProperty>();
|
||||
Trashed = trashed;
|
||||
}
|
||||
|
||||
public UmbracoEntity(int trashed)
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
UmbracoProperties = new List<UmbracoProperty>();
|
||||
Trashed = trashed == 1;
|
||||
}
|
||||
|
||||
@@ -287,10 +291,45 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
public IList<UmbracoProperty> UmbracoProperties { get; set; }
|
||||
|
||||
internal class UmbracoProperty
|
||||
public override object DeepClone()
|
||||
{
|
||||
var clone = (UmbracoEntity)base.DeepClone();
|
||||
clone.UmbracoProperties = UmbracoProperties.Select(x => (UmbracoProperty) x.DeepClone()).ToList();
|
||||
return clone;
|
||||
}
|
||||
|
||||
internal class UmbracoProperty : IDeepCloneable
|
||||
{
|
||||
public Guid DataTypeControlId { get; set; }
|
||||
public string Value { get; set; }
|
||||
public object DeepClone()
|
||||
{
|
||||
//Memberwise clone on Entity will work since it doesn't have any deep elements
|
||||
// for any sub class this will work for standard properties as well that aren't complex object's themselves.
|
||||
var clone = MemberwiseClone();
|
||||
return clone;
|
||||
}
|
||||
|
||||
protected bool Equals(UmbracoProperty other)
|
||||
{
|
||||
return DataTypeControlId.Equals(other.DataTypeControlId) && string.Equals(Value, other.Value);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((UmbracoProperty) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (DataTypeControlId.GetHashCode()*397) ^ (Value != null ? Value.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
253
src/Umbraco.Tests/Models/Collections/Item.cs
Normal file
253
src/Umbraco.Tests/Models/Collections/Item.cs
Normal file
@@ -0,0 +1,253 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Tests.Models.Collections
|
||||
{
|
||||
public abstract class Item : IEntity, ICanBeDirty
|
||||
{
|
||||
private bool _hasIdentity;
|
||||
private int? _hash;
|
||||
private int _id;
|
||||
private Guid _key;
|
||||
|
||||
protected Item()
|
||||
{
|
||||
_propertyChangedInfo = new Dictionary<string, bool>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Integer Id
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
_id = value;
|
||||
HasIdentity = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Guid based Id
|
||||
/// </summary>
|
||||
/// <remarks>The key is currectly used to store the Unique Id from the
|
||||
/// umbracoNode table, which many of the entities are based on.</remarks>
|
||||
[DataMember]
|
||||
public Guid Key
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_key == Guid.Empty)
|
||||
return _id.ToGuid();
|
||||
|
||||
return _key;
|
||||
}
|
||||
set { _key = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Created Date
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Modified Date
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime UpdateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the WasCancelled flag, which is used to track
|
||||
/// whether some action against an entity was cancelled through some event.
|
||||
/// This only exists so we have a way to check if an event was cancelled through
|
||||
/// the new api, which also needs to take effect in the legacy api.
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
internal bool WasCancelled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Property changed event
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on a property setter.
|
||||
/// </summary>
|
||||
/// <param name="propertyInfo">The property info.</param>
|
||||
protected virtual void OnPropertyChanged(PropertyInfo propertyInfo)
|
||||
{
|
||||
_propertyChangedInfo[propertyInfo.Name] = true;
|
||||
|
||||
if (PropertyChanged != null)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void ResetIdentity()
|
||||
{
|
||||
_hasIdentity = false;
|
||||
_id = default(int);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on entity saved when first added
|
||||
/// </summary>
|
||||
internal virtual void AddingEntity()
|
||||
{
|
||||
CreateDate = DateTime.Now;
|
||||
UpdateDate = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on entity saved/updated
|
||||
/// </summary>
|
||||
internal virtual void UpdatingEntity()
|
||||
{
|
||||
UpdateDate = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the properties that have changed
|
||||
/// </summary>
|
||||
//private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
|
||||
private IDictionary<string, bool> _propertyChangedInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a specific property on the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property to check</param>
|
||||
/// <returns>True if Property is dirty, otherwise False</returns>
|
||||
public virtual bool IsPropertyDirty(string propertyName)
|
||||
{
|
||||
return _propertyChangedInfo.Any(x => x.Key == propertyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <returns>True if entity is dirty, otherwise False</returns>
|
||||
public virtual bool IsDirty()
|
||||
{
|
||||
return _propertyChangedInfo.Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets dirty properties by clearing the dictionary used to track changes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that resetting the dirty properties could potentially
|
||||
/// obstruct the saving of a new or updated entity.
|
||||
/// </remarks>
|
||||
public virtual void ResetDirtyProperties()
|
||||
{
|
||||
_propertyChangedInfo.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity has an identity, eg. Id.
|
||||
/// </summary>
|
||||
public virtual bool HasIdentity
|
||||
{
|
||||
get
|
||||
{
|
||||
return _hasIdentity;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
_hasIdentity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(Item left, Item right)
|
||||
{
|
||||
/*if (ReferenceEquals(null, left))
|
||||
return false;
|
||||
|
||||
if(ReferenceEquals(null, right))
|
||||
return false;*/
|
||||
|
||||
return ReferenceEquals(left, right);
|
||||
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Item left, Item right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/*public virtual bool SameIdentityAs(IEntity other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
return false;
|
||||
if (ReferenceEquals(this, other))
|
||||
return true;
|
||||
|
||||
return SameIdentityAs(other as Entity);
|
||||
}
|
||||
|
||||
public virtual bool Equals(Entity other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
return false;
|
||||
if (ReferenceEquals(this, other))
|
||||
return true;
|
||||
|
||||
return SameIdentityAs(other);
|
||||
}
|
||||
|
||||
public virtual Type GetRealType()
|
||||
{
|
||||
return GetType();
|
||||
}
|
||||
|
||||
public virtual bool SameIdentityAs(Entity other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
return false;
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
return true;
|
||||
|
||||
if (GetType() == other.GetRealType() && HasIdentity && other.HasIdentity)
|
||||
return other.Id.Equals(Id);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
return false;
|
||||
if (ReferenceEquals(this, obj))
|
||||
return true;
|
||||
|
||||
return SameIdentityAs(obj as IEntity);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (!_hash.HasValue)
|
||||
_hash = !HasIdentity ? new int?(base.GetHashCode()) : new int?(Id.GetHashCode() * 397 ^ GetType().GetHashCode());
|
||||
return _hash.Value;
|
||||
}*/
|
||||
|
||||
public object DeepClone()
|
||||
{
|
||||
return this.MemberwiseClone();
|
||||
}
|
||||
}
|
||||
}
|
||||
42
src/Umbraco.Tests/Models/Collections/OrderItem.cs
Normal file
42
src/Umbraco.Tests/Models/Collections/OrderItem.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Tests.Models.Collections
|
||||
{
|
||||
public class OrderItem : Item
|
||||
{
|
||||
public readonly int PartNumber;
|
||||
public readonly string Description;
|
||||
public readonly double UnitPrice;
|
||||
|
||||
private int _quantity = 0;
|
||||
|
||||
public OrderItem(int partNumber, string description,
|
||||
int quantity, double unitPrice)
|
||||
{
|
||||
this.PartNumber = partNumber;
|
||||
this.Description = description;
|
||||
this.Quantity = quantity;
|
||||
this.UnitPrice = unitPrice;
|
||||
}
|
||||
|
||||
public int Quantity
|
||||
{
|
||||
get { return _quantity; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentException("Quantity cannot be negative.");
|
||||
|
||||
_quantity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format(
|
||||
"{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}",
|
||||
PartNumber, _quantity, Description, UnitPrice,
|
||||
UnitPrice * _quantity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Tests.TestHelpers.Entities;
|
||||
|
||||
namespace Umbraco.Tests.Models.Collections
|
||||
@@ -71,358 +64,4 @@ namespace Umbraco.Tests.Models.Collections
|
||||
Assert.That(contentType.PropertyGroups.Any(x => x.Name.InvariantEquals("Test")), Is.False);
|
||||
}
|
||||
}
|
||||
|
||||
public class SimpleOrder : KeyedCollection<int, OrderItem>, INotifyCollectionChanged
|
||||
{
|
||||
// The parameterless constructor of the base class creates a
|
||||
// KeyedCollection with an internal dictionary. For this code
|
||||
// example, no other constructors are exposed.
|
||||
//
|
||||
public SimpleOrder() : base() { }
|
||||
|
||||
public SimpleOrder(IEnumerable<OrderItem> properties)
|
||||
{
|
||||
Reset(properties);
|
||||
}
|
||||
|
||||
// This is the only method that absolutely must be overridden,
|
||||
// because without it the KeyedCollection cannot extract the
|
||||
// keys from the items. The input parameter type is the
|
||||
// second generic type argument, in this case OrderItem, and
|
||||
// the return value type is the first generic type argument,
|
||||
// in this case int.
|
||||
//
|
||||
protected override int GetKeyForItem(OrderItem item)
|
||||
{
|
||||
// In this example, the key is the part number.
|
||||
return item.PartNumber;
|
||||
}
|
||||
|
||||
internal void Reset(IEnumerable<OrderItem> properties)
|
||||
{
|
||||
Clear();
|
||||
properties.ForEach(Add);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, OrderItem item)
|
||||
{
|
||||
base.SetItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
var removed = this[index];
|
||||
base.RemoveItem(index);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removed));
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, OrderItem item)
|
||||
{
|
||||
base.InsertItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
base.ClearItems();
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
public new bool Contains(int partNumber)
|
||||
{
|
||||
return this.Any(x => x.PartNumber == partNumber);
|
||||
}
|
||||
|
||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||
|
||||
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
|
||||
{
|
||||
if (CollectionChanged != null)
|
||||
{
|
||||
CollectionChanged(this, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class OrderItem : Item
|
||||
{
|
||||
public readonly int PartNumber;
|
||||
public readonly string Description;
|
||||
public readonly double UnitPrice;
|
||||
|
||||
private int _quantity = 0;
|
||||
|
||||
public OrderItem(int partNumber, string description,
|
||||
int quantity, double unitPrice)
|
||||
{
|
||||
this.PartNumber = partNumber;
|
||||
this.Description = description;
|
||||
this.Quantity = quantity;
|
||||
this.UnitPrice = unitPrice;
|
||||
}
|
||||
|
||||
public int Quantity
|
||||
{
|
||||
get { return _quantity; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentException("Quantity cannot be negative.");
|
||||
|
||||
_quantity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format(
|
||||
"{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}",
|
||||
PartNumber, _quantity, Description, UnitPrice,
|
||||
UnitPrice * _quantity);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class Item : IEntity, ICanBeDirty
|
||||
{
|
||||
private bool _hasIdentity;
|
||||
private int? _hash;
|
||||
private int _id;
|
||||
private Guid _key;
|
||||
|
||||
protected Item()
|
||||
{
|
||||
_propertyChangedInfo = new Dictionary<string, bool>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Integer Id
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
_id = value;
|
||||
HasIdentity = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Guid based Id
|
||||
/// </summary>
|
||||
/// <remarks>The key is currectly used to store the Unique Id from the
|
||||
/// umbracoNode table, which many of the entities are based on.</remarks>
|
||||
[DataMember]
|
||||
public Guid Key
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_key == Guid.Empty)
|
||||
return _id.ToGuid();
|
||||
|
||||
return _key;
|
||||
}
|
||||
set { _key = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Created Date
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Modified Date
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime UpdateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the WasCancelled flag, which is used to track
|
||||
/// whether some action against an entity was cancelled through some event.
|
||||
/// This only exists so we have a way to check if an event was cancelled through
|
||||
/// the new api, which also needs to take effect in the legacy api.
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
internal bool WasCancelled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Property changed event
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on a property setter.
|
||||
/// </summary>
|
||||
/// <param name="propertyInfo">The property info.</param>
|
||||
protected virtual void OnPropertyChanged(PropertyInfo propertyInfo)
|
||||
{
|
||||
_propertyChangedInfo[propertyInfo.Name] = true;
|
||||
|
||||
if (PropertyChanged != null)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void ResetIdentity()
|
||||
{
|
||||
_hasIdentity = false;
|
||||
_id = default(int);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on entity saved when first added
|
||||
/// </summary>
|
||||
internal virtual void AddingEntity()
|
||||
{
|
||||
CreateDate = DateTime.Now;
|
||||
UpdateDate = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on entity saved/updated
|
||||
/// </summary>
|
||||
internal virtual void UpdatingEntity()
|
||||
{
|
||||
UpdateDate = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the properties that have changed
|
||||
/// </summary>
|
||||
//private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
|
||||
private IDictionary<string, bool> _propertyChangedInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a specific property on the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property to check</param>
|
||||
/// <returns>True if Property is dirty, otherwise False</returns>
|
||||
public virtual bool IsPropertyDirty(string propertyName)
|
||||
{
|
||||
return _propertyChangedInfo.Any(x => x.Key == propertyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <returns>True if entity is dirty, otherwise False</returns>
|
||||
public virtual bool IsDirty()
|
||||
{
|
||||
return _propertyChangedInfo.Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets dirty properties by clearing the dictionary used to track changes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that resetting the dirty properties could potentially
|
||||
/// obstruct the saving of a new or updated entity.
|
||||
/// </remarks>
|
||||
public virtual void ResetDirtyProperties()
|
||||
{
|
||||
_propertyChangedInfo.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity has an identity, eg. Id.
|
||||
/// </summary>
|
||||
public virtual bool HasIdentity
|
||||
{
|
||||
get
|
||||
{
|
||||
return _hasIdentity;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
_hasIdentity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(Item left, Item right)
|
||||
{
|
||||
/*if (ReferenceEquals(null, left))
|
||||
return false;
|
||||
|
||||
if(ReferenceEquals(null, right))
|
||||
return false;*/
|
||||
|
||||
return ReferenceEquals(left, right);
|
||||
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Item left, Item right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/*public virtual bool SameIdentityAs(IEntity other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
return false;
|
||||
if (ReferenceEquals(this, other))
|
||||
return true;
|
||||
|
||||
return SameIdentityAs(other as Entity);
|
||||
}
|
||||
|
||||
public virtual bool Equals(Entity other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
return false;
|
||||
if (ReferenceEquals(this, other))
|
||||
return true;
|
||||
|
||||
return SameIdentityAs(other);
|
||||
}
|
||||
|
||||
public virtual Type GetRealType()
|
||||
{
|
||||
return GetType();
|
||||
}
|
||||
|
||||
public virtual bool SameIdentityAs(Entity other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
return false;
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
return true;
|
||||
|
||||
if (GetType() == other.GetRealType() && HasIdentity && other.HasIdentity)
|
||||
return other.Id.Equals(Id);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
return false;
|
||||
if (ReferenceEquals(this, obj))
|
||||
return true;
|
||||
|
||||
return SameIdentityAs(obj as IEntity);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (!_hash.HasValue)
|
||||
_hash = !HasIdentity ? new int?(base.GetHashCode()) : new int?(Id.GetHashCode() * 397 ^ GetType().GetHashCode());
|
||||
return _hash.Value;
|
||||
}*/
|
||||
|
||||
public object DeepClone()
|
||||
{
|
||||
return this.MemberwiseClone();
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/Umbraco.Tests/Models/Collections/SimpleOrder.cs
Normal file
82
src/Umbraco.Tests/Models/Collections/SimpleOrder.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Tests.Models.Collections
|
||||
{
|
||||
public class SimpleOrder : KeyedCollection<int, OrderItem>, INotifyCollectionChanged
|
||||
{
|
||||
// The parameterless constructor of the base class creates a
|
||||
// KeyedCollection with an internal dictionary. For this code
|
||||
// example, no other constructors are exposed.
|
||||
//
|
||||
public SimpleOrder() : base() { }
|
||||
|
||||
public SimpleOrder(IEnumerable<OrderItem> properties)
|
||||
{
|
||||
Reset(properties);
|
||||
}
|
||||
|
||||
// This is the only method that absolutely must be overridden,
|
||||
// because without it the KeyedCollection cannot extract the
|
||||
// keys from the items. The input parameter type is the
|
||||
// second generic type argument, in this case OrderItem, and
|
||||
// the return value type is the first generic type argument,
|
||||
// in this case int.
|
||||
//
|
||||
protected override int GetKeyForItem(OrderItem item)
|
||||
{
|
||||
// In this example, the key is the part number.
|
||||
return item.PartNumber;
|
||||
}
|
||||
|
||||
internal void Reset(IEnumerable<OrderItem> properties)
|
||||
{
|
||||
Clear();
|
||||
properties.ForEach(Add);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, OrderItem item)
|
||||
{
|
||||
base.SetItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
var removed = this[index];
|
||||
base.RemoveItem(index);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removed));
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, OrderItem item)
|
||||
{
|
||||
base.InsertItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
base.ClearItems();
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
public new bool Contains(int partNumber)
|
||||
{
|
||||
return this.Any(x => x.PartNumber == partNumber);
|
||||
}
|
||||
|
||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||
|
||||
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
|
||||
{
|
||||
if (CollectionChanged != null)
|
||||
{
|
||||
CollectionChanged(this, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,25 @@ namespace Umbraco.Tests.Models
|
||||
[TestFixture]
|
||||
public class ContentTypeTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone_Content_Type_Sort()
|
||||
{
|
||||
var contentType = new ContentTypeSort(new Lazy<int>(() => 3), 4, "test");
|
||||
var clone = (ContentTypeSort) contentType.DeepClone();
|
||||
Assert.AreNotSame(clone, contentType);
|
||||
Assert.AreEqual(clone, contentType);
|
||||
Assert.AreEqual(clone.Id.Value, contentType.Id.Value);
|
||||
Assert.AreEqual(clone.SortOrder, contentType.SortOrder);
|
||||
Assert.AreEqual(clone.Alias, contentType.Alias);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(contentType, null));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Deep_Clone_Content_Type()
|
||||
{
|
||||
|
||||
54
src/Umbraco.Tests/Models/DataTypeDefinitionTests.cs
Normal file
54
src/Umbraco.Tests/Models/DataTypeDefinitionTests.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class DataTypeDefinitionTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var dtd = new DataTypeDefinition(9, Guid.NewGuid())
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CreatorId = 5,
|
||||
DatabaseType = DataTypeDatabaseType.Nvarchar,
|
||||
Id = 4,
|
||||
Key = Guid.NewGuid(),
|
||||
Level = 7,
|
||||
Name = "Test",
|
||||
ParentId = 9,
|
||||
Path = "-1,2",
|
||||
SortOrder = 8,
|
||||
Trashed = true,
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
var clone = (DataTypeDefinition) dtd.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, dtd);
|
||||
Assert.AreEqual(clone, dtd);
|
||||
Assert.AreEqual(clone.CreateDate, dtd.CreateDate);
|
||||
Assert.AreEqual(clone.CreatorId, dtd.CreatorId);
|
||||
Assert.AreEqual(clone.DatabaseType, dtd.DatabaseType);
|
||||
Assert.AreEqual(clone.Id, dtd.Id);
|
||||
Assert.AreEqual(clone.Key, dtd.Key);
|
||||
Assert.AreEqual(clone.Level, dtd.Level);
|
||||
Assert.AreEqual(clone.Name, dtd.Name);
|
||||
Assert.AreEqual(clone.ParentId, dtd.ParentId);
|
||||
Assert.AreEqual(clone.Path, dtd.Path);
|
||||
Assert.AreEqual(clone.SortOrder, dtd.SortOrder);
|
||||
Assert.AreEqual(clone.Trashed, dtd.Trashed);
|
||||
Assert.AreEqual(clone.UpdateDate, dtd.UpdateDate);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(dtd, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/Umbraco.Tests/Models/DictionaryItemTests.cs
Normal file
82
src/Umbraco.Tests/Models/DictionaryItemTests.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class DictionaryItemTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new DictionaryItem("blah")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 8,
|
||||
ItemKey = "blah",
|
||||
Key = Guid.NewGuid(),
|
||||
ParentId = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now,
|
||||
Translations = new[]
|
||||
{
|
||||
new DictionaryTranslation(new Language("en-AU")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "en",
|
||||
Id = 11,
|
||||
IsoCode = "AU",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
}, "colour")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 88,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
},
|
||||
new DictionaryTranslation(new Language("en-US")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "en",
|
||||
Id = 12,
|
||||
IsoCode = "US",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
}, "color")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 89,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
var clone = (DictionaryItem)item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.ItemKey, item.ItemKey);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.ParentId, item.ParentId);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
Assert.AreEqual(clone.Translations.Count(), item.Translations.Count());
|
||||
for (var i = 0; i < item.Translations.Count(); i++)
|
||||
{
|
||||
Assert.AreNotSame(clone.Translations.ElementAt(i), item.Translations.ElementAt(i));
|
||||
Assert.AreEqual(clone.Translations.ElementAt(i), item.Translations.ElementAt(i));
|
||||
}
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/Umbraco.Tests/Models/DictionaryTranslationTests.cs
Normal file
49
src/Umbraco.Tests/Models/DictionaryTranslationTests.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class DictionaryTranslationTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new DictionaryTranslation(new Language("en-AU")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "en",
|
||||
Id = 11,
|
||||
IsoCode = "AU",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
}, "colour")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 88,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
|
||||
var clone = (DictionaryTranslation) item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
Assert.AreNotSame(clone.Language, item.Language);
|
||||
Assert.AreEqual(clone.Language, item.Language);
|
||||
Assert.AreEqual(clone.Value, item.Value);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
src/Umbraco.Tests/Models/LanguageTests.cs
Normal file
41
src/Umbraco.Tests/Models/LanguageTests.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class LanguageTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new Language("en-AU")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "en",
|
||||
Id = 11,
|
||||
IsoCode = "AU",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
|
||||
var clone = (Language) item.DeepClone();
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.CultureName, item.CultureName);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.IsoCode, item.IsoCode);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
src/Umbraco.Tests/Models/RelationTests.cs
Normal file
48
src/Umbraco.Tests/Models/RelationTests.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class RelationTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new Relation(9, 8, new RelationType(Guid.NewGuid(), Guid.NewGuid(), "test")
|
||||
{
|
||||
Id = 66
|
||||
})
|
||||
{
|
||||
Comment = "test comment",
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 4,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
|
||||
var clone = (Relation) item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.ChildId, item.ChildId);
|
||||
Assert.AreEqual(clone.Comment, item.Comment);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.ParentId, item.ParentId);
|
||||
Assert.AreNotSame(clone.RelationType, item.RelationType);
|
||||
Assert.AreEqual(clone.RelationType, item.RelationType);
|
||||
Assert.AreEqual(clone.RelationTypeId, item.RelationTypeId);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/Umbraco.Tests/Models/RelationTypeTests.cs
Normal file
44
src/Umbraco.Tests/Models/RelationTypeTests.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class RelationTypeTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new RelationType(Guid.NewGuid(), Guid.NewGuid(), "test")
|
||||
{
|
||||
Id = 66,
|
||||
CreateDate = DateTime.Now,
|
||||
IsBidirectional = true,
|
||||
Key = Guid.NewGuid(),
|
||||
Name = "Test",
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
|
||||
var clone = (RelationType)item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.Alias, item.Alias);
|
||||
Assert.AreEqual(clone.ChildObjectType, item.ChildObjectType);
|
||||
Assert.AreEqual(clone.IsBidirectional, item.IsBidirectional);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.Name, item.Name);
|
||||
Assert.AreNotSame(clone.ParentObjectType, item.ParentObjectType);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
52
src/Umbraco.Tests/Models/TaskTests.cs
Normal file
52
src/Umbraco.Tests/Models/TaskTests.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class TaskTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new Task(new TaskType("test") {Id = 3})
|
||||
{
|
||||
AssigneeUserId = 4,
|
||||
Closed = true,
|
||||
Comment = "blah",
|
||||
CreateDate = DateTime.Now,
|
||||
EntityId = 99,
|
||||
Id = 2,
|
||||
Key = Guid.NewGuid(),
|
||||
OwnerUserId = 89,
|
||||
TaskType = new TaskType("asdf") {Id = 99},
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
|
||||
var clone = (Task) item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
Assert.AreEqual(clone.AssigneeUserId, item.AssigneeUserId);
|
||||
Assert.AreEqual(clone.Closed, item.Closed);
|
||||
Assert.AreEqual(clone.Comment, item.Comment);
|
||||
Assert.AreEqual(clone.EntityId, item.EntityId);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.OwnerUserId, item.OwnerUserId);
|
||||
Assert.AreNotSame(clone.TaskType, item.TaskType);
|
||||
Assert.AreEqual(clone.TaskType, item.TaskType);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
42
src/Umbraco.Tests/Models/TaskTypeTests.cs
Normal file
42
src/Umbraco.Tests/Models/TaskTypeTests.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class TaskTypeTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new TaskType("test")
|
||||
{
|
||||
Id = 3,
|
||||
Alias = "test",
|
||||
CreateDate = DateTime.Now,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
|
||||
var clone = (TaskType)item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.Alias, item.Alias);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
54
src/Umbraco.Tests/Models/TemplateTests.cs
Normal file
54
src/Umbraco.Tests/Models/TemplateTests.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class TemplateTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new Template("-1,2,3", "Test", "test")
|
||||
{
|
||||
Id = 3,
|
||||
CreateDate = DateTime.Now,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now,
|
||||
Content = "blah",
|
||||
CreatorId = 66,
|
||||
Level = 55,
|
||||
ParentId = 2,
|
||||
SortOrder = 99,
|
||||
MasterTemplateAlias = "master",
|
||||
MasterTemplateId = new Lazy<int>(() => 88)
|
||||
};
|
||||
|
||||
var clone = (Template)item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.Alias, item.Alias);
|
||||
Assert.AreEqual(clone.CreatorId, item.CreatorId);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.Level, item.Level);
|
||||
Assert.AreEqual(clone.MasterTemplateAlias, item.MasterTemplateAlias);
|
||||
Assert.AreEqual(clone.MasterTemplateId.Value, item.MasterTemplateId.Value);
|
||||
Assert.AreEqual(clone.Name, item.Name);
|
||||
Assert.AreEqual(clone.ParentId, item.ParentId);
|
||||
Assert.AreEqual(clone.SortOrder, item.SortOrder);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
@@ -18,5 +19,81 @@ namespace Umbraco.Tests.Models
|
||||
Assert.IsTrue(trashedWithBool.Trashed);
|
||||
Assert.IsTrue(trashedWithInt.Trashed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new UmbracoEntity()
|
||||
{
|
||||
Id = 3,
|
||||
ContentTypeAlias = "test1",
|
||||
CreatorId = 4,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now,
|
||||
CreateDate = DateTime.Now,
|
||||
Name = "Test",
|
||||
ParentId = 5,
|
||||
SortOrder = 6,
|
||||
Path = "-1,23",
|
||||
Level = 7,
|
||||
ContentTypeIcon = "icon",
|
||||
ContentTypeThumbnail = "thumb",
|
||||
HasChildren = true,
|
||||
HasPendingChanges = true,
|
||||
IsDraft = true,
|
||||
IsPublished = true,
|
||||
NodeObjectTypeId = Guid.NewGuid()
|
||||
};
|
||||
item.AdditionalData.Add("test1", 3);
|
||||
item.AdditionalData.Add("test2", "valuie");
|
||||
item.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty()
|
||||
{
|
||||
Value = "test",
|
||||
DataTypeControlId = Guid.NewGuid()
|
||||
});
|
||||
item.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty()
|
||||
{
|
||||
Value = "test2",
|
||||
DataTypeControlId = Guid.NewGuid()
|
||||
});
|
||||
|
||||
var clone = (UmbracoEntity)item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.ContentTypeAlias, item.ContentTypeAlias);
|
||||
Assert.AreEqual(clone.CreatorId, item.CreatorId);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.Level, item.Level);
|
||||
Assert.AreEqual(clone.Name, item.Name);
|
||||
Assert.AreEqual(clone.ParentId, item.ParentId);
|
||||
Assert.AreEqual(clone.SortOrder, item.SortOrder);
|
||||
Assert.AreEqual(clone.Path, item.Path);
|
||||
Assert.AreEqual(clone.ContentTypeIcon, item.ContentTypeIcon);
|
||||
Assert.AreEqual(clone.ContentTypeThumbnail, item.ContentTypeThumbnail);
|
||||
Assert.AreEqual(clone.HasChildren, item.HasChildren);
|
||||
Assert.AreEqual(clone.HasPendingChanges, item.HasPendingChanges);
|
||||
Assert.AreEqual(clone.IsDraft, item.IsDraft);
|
||||
Assert.AreEqual(clone.IsPublished, item.IsPublished);
|
||||
Assert.AreEqual(clone.NodeObjectTypeId, item.NodeObjectTypeId);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
Assert.AreEqual(clone.AdditionalData.Count, item.AdditionalData.Count);
|
||||
Assert.AreEqual(clone.AdditionalData, item.AdditionalData);
|
||||
Assert.AreEqual(clone.UmbracoProperties.Count, item.UmbracoProperties.Count);
|
||||
for (var i = 0; i < clone.UmbracoProperties.Count; i++)
|
||||
{
|
||||
Assert.AreNotSame(clone.UmbracoProperties[i], item.UmbracoProperties[i]);
|
||||
Assert.AreEqual(clone.UmbracoProperties[i], item.UmbracoProperties[i]);
|
||||
}
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,9 +157,21 @@
|
||||
<Compile Include="Membership\MembershipProviderBaseTests.cs" />
|
||||
<Compile Include="Membership\UmbracoServiceMembershipProviderTests.cs" />
|
||||
<Compile Include="MockTests.cs" />
|
||||
<Compile Include="Models\Collections\Item.cs" />
|
||||
<Compile Include="Models\Collections\OrderItem.cs" />
|
||||
<Compile Include="Models\Collections\SimpleOrder.cs" />
|
||||
<Compile Include="Models\ContentTypeTests.cs" />
|
||||
<Compile Include="Models\DataTypeDefinitionTests.cs" />
|
||||
<Compile Include="Models\DictionaryItemTests.cs" />
|
||||
<Compile Include="Models\DictionaryTranslationTests.cs" />
|
||||
<Compile Include="Models\LanguageTests.cs" />
|
||||
<Compile Include="Models\PropertyGroupTests.cs" />
|
||||
<Compile Include="Models\PropertyTypeTests.cs" />
|
||||
<Compile Include="Models\RelationTests.cs" />
|
||||
<Compile Include="Models\RelationTypeTests.cs" />
|
||||
<Compile Include="Models\TaskTests.cs" />
|
||||
<Compile Include="Models\TaskTypeTests.cs" />
|
||||
<Compile Include="Models\TemplateTests.cs" />
|
||||
<Compile Include="Models\UmbracoEntityTests.cs" />
|
||||
<Compile Include="Mvc\UmbracoViewPageTests.cs" />
|
||||
<Compile Include="Persistence\Auditing\AuditTests.cs" />
|
||||
|
||||
Reference in New Issue
Block a user