public void DictionaryHashedConsistently() { var dictionary = new Dictionary <String, Object> { { "Value 1", 1 }, { "Value 2", 2 }, { "Value 3", 3 } }; Assert.Equal(ObjectHasher.Hash(dictionary), ObjectHasher.Hash(dictionary)); }
public void IgnoreFieldsMarkedWithNonHashedAttribute() { var graph = new CustomObject(); graph.NonHashedField = ObjectHasher.Hash(graph); Assert.Equal(graph.NonHashedField, ObjectHasher.Hash(graph)); }
public void HashFieldsWithNoAttributes() { var graph = new CustomObject(); graph.NonHashedField = ObjectHasher.Hash(graph); graph.NoAttributeField = Guid.NewGuid(); Assert.NotEqual(graph.NonHashedField, ObjectHasher.Hash(graph)); }
public void HashImpactedByDictionaryKeyOrder() { Assert.NotEqual( ObjectHasher.Hash(new Dictionary <String, Object> { { "Value 2", 2 }, { "Value 3", 3 }, { "Value 1", 1 } }), ObjectHasher.Hash(new Dictionary <String, Object> { { "Value 1", 1 }, { "Value 2", 2 }, { "Value 3", 3 } }) ); }
public void CircularReferenceDoesNotResultInStackOverflow() { var dictionary = new Dictionary <String, Object> { { "Value 1", 1 }, { "Value 2", 2 }, { "Value 3", 3 } }; //NOTE: When `Keys` is accessed, a `KeyCollection` instance is created that holds a reference to the underlying `dictionary` and // would cause a `StackOverflowException` to be thrown if not handled correctly. Assert.NotNull(dictionary.Keys); Assert.NotEqual(Guid.Empty, ObjectHasher.Hash(dictionary)); }
/// <summary> /// Validates the <see cref="Aggregate"/> state against the current checksum (state hash). If <see cref="UpdateHash"/> has not been /// previously called the aggregate state is assumed to be valid and the checksum is set for future reference. /// </summary> /// <remarks> /// Fields marked with <see cref="IgnoreDataMemberAttribute"/>, <see cref="NonSerializedAttribute"/> and/or <see cref="XmlIgnoreAttribute"/> will not /// be included when calculating the MD5 hash of this non-recursive object graph. /// </remarks> protected internal virtual void VerifyHash() { if (checksum == Guid.Empty) { UpdateHash(); } else { if (checksum != ObjectHasher.Hash(this)) { throw new MemberAccessException(Exceptions.StateAccessException.FormatWith(Id)); } } }
/// <summary> /// Update the aggregate checksum based on the currently known <see cref="Aggregate"/> state. /// </summary> /// <remarks> /// Fields marked with <see cref="IgnoreDataMemberAttribute"/>, <see cref="NonSerializedAttribute"/> and/or <see cref="XmlIgnoreAttribute"/> will not /// be included when calculating the MD5 hash of this non-recursive object graph. /// </remarks> protected internal virtual void UpdateHash() { checksum = ObjectHasher.Hash(this); }
public void HashDependentOnValueOrder() { Assert.NotEqual(ObjectHasher.Hash(new[] { 1, 2, 3 }), ObjectHasher.Hash(new[] { 3, 2, 1 })); }
public void CanHashMultiDimensionArray() { Assert.Equal(Guid.Parse("db536ce4-08dc-5aa1-46b5-c2f5d95a14b0"), ObjectHasher.Hash(new[, ] { { 1, 2, 3 }, { 4, 5, 6 } })); }
public void CanHashSingleDimensionArray() { Assert.Equal(Guid.Parse("e1d11d2a-9de5-380a-4c26-951e316cd7e6"), ObjectHasher.Hash(new[] { 1, 2, 3 })); }
public void CanHashEmptyArray() { Assert.Equal(Guid.Parse("d98c1dd4-008f-04b2-e980-0998ecf8427e"), ObjectHasher.Hash(new Object[0])); }
public void AlwaysReturnConsistentHash(String guid, Object value) { Assert.Equal(Guid.Parse(guid), ObjectHasher.Hash(value)); }
public void AlwaysReturnConsistentHash() { Assert.Equal(Guid.Parse("ad85b893-0dfe-89a0-cdf6-34904fd59f71"), ObjectHasher.Hash(null)); }