/// <summary> /// Asserts that an object can be serialized and deserialized using the binary serializer and that it stills retains /// the values of all members. /// </summary> /// <param name="assertions"></param> /// <param name="options"> /// A reference to the <see cref="EquivalencyAssertionOptions{TExpectation}"/> configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the /// <see cref="EquivalencyAssertionOptions{TExpectation}"/> class. The global defaults are determined by the /// <see cref="AssertionOptions"/> class. /// </param> /// <param name="because"> /// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion /// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. /// </param> /// <param name="becauseArgs"> /// Zero or more objects to format using the placeholders in <paramref name="because" />. /// </param> public static AndConstraint <ObjectAssertions> BeBinarySerializable <T>(this ObjectAssertions assertions, Func <EquivalencyAssertionOptions <T>, EquivalencyAssertionOptions <T> > options, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(options, nameof(options)); try { object deserializedObject = CreateCloneUsingBinarySerializer(assertions.Subject); EquivalencyAssertionOptions <T> defaultOptions = AssertionOptions.CloneDefaults <T>() .RespectingRuntimeTypes().IncludingFields().IncludingProperties(); ((T)deserializedObject).Should().BeEquivalentTo((T)assertions.Subject, _ => options(defaultOptions)); } catch (Exception exc) { Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {0} to be serializable{reason}, but serialization failed with:{1}{1}{2}.", assertions.Subject, Environment.NewLine, exc.Message); } return(new AndConstraint <ObjectAssertions>(assertions)); }
/// <summary> /// Asserts that an object is equivalent to another object. /// </summary> /// <remarks> /// Objects are equivalent when both object graphs have equally named properties with the same value, /// irrespective of the type of those objects. Two properties are also equal if one type can be converted to another and the result is equal. /// The type of a collection property is ignored as long as the collection implements <see cref="IEnumerable"/> and all /// items in the collection are structurally equal. /// </remarks> /// <param name="config"> /// A reference to the <see cref="EquivalencyAssertionOptions{TSubject}"/> configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the /// <see cref="EquivalencyAssertionOptions{TSubject}"/> class. The global defaults are determined by the /// <see cref="AssertionOptions"/> class. /// </param> /// <param name="because"> /// An optional formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the /// assertion is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. /// </param> /// <param name="reasonArgs"> /// Zero or more objects to format using the placeholders in <see cref="reason" />. /// </param> public static void ShouldBeEquivalentTo <T>(this T subject, object expectation, Func <EquivalencyAssertionOptions <T>, EquivalencyAssertionOptions <T> > config, string because = "", params object[] reasonArgs) { var context = new EquivalencyValidationContext { Subject = subject, Expectation = expectation, CompileTimeType = typeof(T), Reason = because, ReasonArgs = reasonArgs }; new EquivalencyValidator(config(AssertionOptions.CloneDefaults <T>())).AssertEquality(context); }
public static void ShouldAllBeEquivalentTo <T>(this IEnumerable <T> subject, IEnumerable expectation, Func <EquivalencyAssertionOptions <T>, EquivalencyAssertionOptions <T> > config, string because = "", params object[] becauseArgs) { var context = new EquivalencyValidationContext() { Subject = subject, Expectation = expectation, CompileTimeType = typeof(T), Because = because, BecauseArgs = becauseArgs }; new EquivalencyValidator(config(AssertionOptions.CloneDefaults <T>())).AssertEquality(context); }
/// <summary> /// Asserts that a collection of objects is equivalent to another collection of objects. /// </summary> /// <remarks> /// Objects within the collections are equivalent when both object graphs have equally named properties with the same /// value, irrespective of the type of those objects. Two properties are also equal if one type can be converted to another /// and the result is equal. /// The type of a collection property is ignored as long as the collection implements <see cref="IEnumerable"/> and all /// items in the collection are structurally equal. /// </remarks> /// <param name="config"> /// A reference to the <see cref="EquivalencyAssertionOptions{TSubject}"/> configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the /// <see cref="EquivalencyAssertionOptions{TSubject}"/> class. The global defaults are determined by the /// <see cref="AssertionOptions"/> class. /// </param> /// <param name="because"> /// An optional formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the /// assertion is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. /// </param> /// <param name="reasonArgs"> /// Zero or more objects to format using the placeholders in <see cref="reason" />. /// </param> public static void ShouldAllBeEquivalentTo <T>(this IEnumerable <T> subject, IEnumerable expectation, Func <EquivalencyAssertionOptions <T>, EquivalencyAssertionOptions <T> > config, string because = "", params object[] reasonArgs) { EquivalencyAssertionOptions <IEnumerable <T> > source = config(AssertionOptions.CloneDefaults <T>()).AsCollection(); var context = new EquivalencyValidationContext { Subject = subject, Expectation = expectation, RootIsCollection = true, CompileTimeType = typeof(IEnumerable <T>), Reason = because, ReasonArgs = reasonArgs }; new EquivalencyValidator(source).AssertEquality(context); }
/// <summary> /// Asserts that an object is equivalent to another object. /// </summary> /// <remarks> /// Objects are equivalent when both object graphs have equally named properties with the same value, /// irrespective of the type of those objects. Two properties are also equal if one type can be converted to another and the result is equal. /// The type of a collection property is ignored as long as the collection implements <see cref="IEnumerable"/> and all /// items in the collection are structurally equal. /// </remarks> /// <param name="config"> /// A reference to the <see cref="EquivalencyAssertionOptions{TSubject}"/> configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the /// <see cref="EquivalencyAssertionOptions{TSubject}"/> class. The global defaults are determined by the /// <see cref="AssertionOptions"/> class. /// </param> /// <param name="because"> /// An optional formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the /// assertion is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. /// </param> /// <param name="becauseArgs"> /// Zero or more objects to format using the placeholders in <see cref="because" />. /// </param> public static void ShouldBeEquivalentTo <T>(this T subject, object expectation, Func <EquivalencyAssertionOptions <T>, EquivalencyAssertionOptions <T> > config, string because = "", params object[] becauseArgs) { IEquivalencyAssertionOptions options = config(AssertionOptions.CloneDefaults <T>()); var context = new EquivalencyValidationContext { Subject = subject, Expectation = expectation, CompileTimeType = typeof(T), Because = because, BecauseArgs = becauseArgs, Tracer = options.TraceWriter }; new EquivalencyValidator(options).AssertEquality(context); }
/// <summary> /// Asserts that an object can be serialized and deserialized using the binary serializer and that it stills retains /// the values of all members. /// </summary> /// <param name="because"> /// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion /// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. /// </param> /// <param name="reasonArgs"> /// Zero or more objects to format using the placeholders in <see cref="reason" />. /// </param> public static AndConstraint <ObjectAssertions> BeBinarySerializable <T>(this ObjectAssertions assertions, Func <EquivalencyAssertionOptions <T>, EquivalencyAssertionOptions <T> > options, string because = "", params object[] reasonArgs) { try { object deserializedObject = CreateCloneUsingBinarySerializer(assertions.Subject); EquivalencyAssertionOptions <T> defaultOptions = AssertionOptions.CloneDefaults <T>() .RespectingRuntimeTypes().IncludingFields().IncludingProperties(); ((T)deserializedObject).ShouldBeEquivalentTo(assertions.Subject, _ => options(defaultOptions)); } catch (Exception exc) { Execute.Assertion .BecauseOf(because, reasonArgs) .FailWith("Expected {0} to be serializable{reason}, but serialization failed with:\r\n\r\n{1}", assertions.Subject, exc.Message); } return(new AndConstraint <ObjectAssertions>(assertions)); }