private bool CompareArrayItems(ComparisonContext context, ValueComparison comparison, int currentDimension, int[] currentIndices) { var actual = (Array)comparison.ActualValue; var expected = (Array)comparison.ExpectedValue; var length = expected.GetLength(currentDimension); var areEqual = true; for (var i = 0; i < length; i++) { currentIndices[currentDimension] = i; if (currentDimension == currentIndices.Length - 1) { // Last dimension, get value and compare var actualValue = actual.GetValue(currentIndices); var expectedValue = expected.GetValue(currentIndices); var indicesString = this.GetArrayIndicesString(currentIndices); var propertyPath = new PropertyPathItem(indicesString, comparison.PropertyPathItem); if (!context.CompareItem(expectedValue, actualValue, propertyPath)) { areEqual = false; } } else { if (!this.CompareArrayItems(context, comparison, currentDimension + 1, currentIndices)) { areEqual = false; } } } return areEqual; }
public bool Compare(ComparisonContext context, ValueComparison comparison) { if (comparison.PropertyType == null) { throw new ArgumentException("Could not determine type to reflect.", "comparison"); } var areEqual = true; var properties = comparison.PropertyType .GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var property in properties) { var propertyPathItem = new PropertyPathItem(property, comparison.PropertyPathItem); var expectedPropValue = property.GetValue(comparison.ExpectedValue, null); var actualPropValue = property.GetValue(comparison.ActualValue, null); if (!context.CompareItem(expectedPropValue, actualPropValue, propertyPathItem)) { areEqual = false; } } return areEqual; }
public bool Compare(ComparisonContext context, ValueComparison valueComparison) { bool areEqual; var options = context.Rules.GetOptions<FloatValueComparatorOptions>(valueComparison); if (valueComparison.PropertyInfo.PropertyType == typeof(float)) { areEqual = this.CompareFloats( (float)valueComparison.ExpectedValue, (float)valueComparison.ActualValue, options.FloatEpsilon); } else { areEqual = this.CompareDoubles( (double)valueComparison.ExpectedValue, (double)valueComparison.ActualValue, options.DoubleEpsilon); } if (!areEqual) { context.AddDifference(valueComparison); } return areEqual; }
public bool Compare(ComparisonContext comparisonContext, ValueComparison valueComparison) { var actual = (IDictionary)valueComparison.ActualValue; var expected = (IDictionary)valueComparison.ExpectedValue; if (!this.AreKeysEqual(expected, actual, comparisonContext, valueComparison)) { return false; } foreach (var key in expected.Keys) { var actualValue = actual[key]; var expectedValue = expected[key]; // TODO: Why is this immediately picked up by the recursive comparator // TODO: Create a valid use case test for the recursive comparator // TODO: Both values null in the dictionary // TODO: Comple objects in the dictionary var propertyPath = new PropertyPathItem(key.ToString(), valueComparison.PropertyPathItem); comparisonContext.CompareItem(expectedValue, actualValue, propertyPath); } return true; }
public void Missing_actual_entry() { var context = new ComparisonContext(); context.AddDifference(new MissingEntryDifference(MissingSide.Actual, "Index", "Value")); AssertExceptionMessage(context, @" Comparison Failed: The following 1 differences were found. Actual[""Index""] not found (Expected[""Index""] = ""Value"")"); }
public bool Compare(ComparisonContext context, ValueComparison comparison) { var areEqual = object.Equals(comparison.ExpectedValue, comparison.ActualValue); if (!areEqual) { context.AddDifference(comparison); } return areEqual; }
public void Long_string_difference_start() { var context = new ComparisonContext(); context.AddDifference( "01234567890123456789012345678901234567890123456789", "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"); AssertExceptionMessage(context, @" Comparison Failed: The following 1 differences were found. Actual != Expected (""01234567890123456789..."" != ""abcdefghijabcdefghij..."")"); }
public void Long_string_difference_end_2() { var context = new ComparisonContext(); context.AddDifference( "01234567890123456789012345678901234567890123", "01234567890123456789012345678901234567890123456789"); AssertExceptionMessage(context, @" Comparison Failed: The following 1 differences were found. Actual != Expected (""...45678901234567890123"" != ""...01234567890123456789"")"); }
public bool Compare(ComparisonContext context, ValueComparison comparison) { var areEqual = ReferenceEquals(comparison.ExpectedValue, comparison.ActualValue); if (!areEqual) { comparison.Message = "The instances are different, reference equals failed."; context.AddDifference(comparison); } return areEqual; }
public void Long_string_difference_middle() { var context = new ComparisonContext(); context.AddDifference( "01234567890123456789012345first678901234567890123456789", "01234567890123456789012345second678901234567890123456789"); AssertExceptionMessage(context, @" Comparison Failed: The following 1 differences were found. Actual != Expected (""...6789012345first67890..."" != ""...6789012345second6789..."")"); }
public bool Compare(ComparisonContext context, ValueComparison comparison) { var maxDimentions = comparison.PropertyType.GetArrayRank(); var currentIndices = new int[maxDimentions]; if (!this.CompareArrayDimensionLengths(comparison, maxDimentions)) { context.AddDifference(comparison); return false; } return this.CompareArrayItems(context, comparison, 0, currentIndices); }
public void List_int_difference() { var context = new ComparisonContext(); var innerContext = context.VisitingIndex(2); innerContext.AddDifference(1, 2); innerContext = context.VisitingIndex(4); innerContext.AddDifference(4, 5); AssertExceptionMessage(context, @" Comparison Failed: The following 2 differences were found. Actual[2] != Expected[2] (1 != 2) Actual[4] != Expected[4] (4 != 5)"); }
public bool Compare(ComparisonContext comparisonContext, ValueComparison valueComparison) { var expected = (IComparable)valueComparison.ExpectedValue; var actual = (IComparable)valueComparison.ActualValue; var areEqual = expected.CompareTo(actual) == 0; if (!areEqual) { comparisonContext.AddDifference(valueComparison); } return areEqual; }
public bool Compare(ComparisonContext context, ValueComparison valueComparison) { var options = context.Rules.GetOptions<StringValueComparatorOptions>(valueComparison); var areEqual = string.Equals( (string)valueComparison.ExpectedValue, (string)valueComparison.ActualValue, options.ComparisonType); if (!areEqual) { context.AddDifference(valueComparison); } return areEqual; }
public bool Compare(ComparisonContext context, ValueComparison comparison) { var areSame = this.customCompare.Invoke(comparison, context); if (!areSame) { if (string.IsNullOrEmpty(comparison.Message)) { comparison.Message = "Custom comparator returned false"; } context.AddDifference(comparison); } return areSame; }
public bool Compare(ComparisonContext context, ValueComparison comparison) { var areEqual = true; var options = context.Rules.GetOptions<CollectionValueComparatorOptions>(comparison); var actual = (IEnumerable)comparison.ActualValue; var expected = (IEnumerable)comparison.ExpectedValue; if (options.OrderFunction != null) { actual = options.OrderFunction.Invoke(actual); expected = options.OrderFunction.Invoke(expected); } var actualEnumerator = actual.GetEnumerator(); var expectedEnumerator = expected.GetEnumerator(); var actualHasNext = actualEnumerator.MoveNext(); var expectedHasNext = expectedEnumerator.MoveNext(); var itemCounter = 0; while (actualHasNext && expectedHasNext) { var propertyPath = new PropertyPathItem(itemCounter.ToString(), comparison.PropertyPathItem); if (!context.CompareItem(expectedEnumerator.Current, actualEnumerator.Current, propertyPath)) { areEqual = false; } expectedHasNext = expectedEnumerator.MoveNext(); actualHasNext = actualEnumerator.MoveNext(); itemCounter++; } if (actualHasNext != expectedHasNext) { comparison.Message = string.Format( "The collections have a different number of items, expected: {0}, actual: {1}.", expected.Cast<object>().Count(), actual.Cast<object>().Count()); context.AddDifference(comparison); areEqual = false; } return areEqual; }
/// <summary> /// Compare a modified document node (this) to a previous one and look for breaking as well as non-breaking changes. /// </summary> /// <param name="context">The modified document context.</param> /// <param name="previous">The original document model.</param> /// <returns>A list of messages from the comparison.</returns> public override IEnumerable <ComparisonMessage> Compare(ComparisonContext context, SwaggerBase previous) { var priorParameter = previous as SwaggerParameter; if (priorParameter == null) { throw new ArgumentNullException("priorVersion"); } if (context == null) { throw new ArgumentNullException("context"); } context.Direction = DataDirection.Request; base.Compare(context, previous); if (In != priorParameter.In) { context.LogBreakingChange(ComparisonMessages.ParameterInHasChanged, priorParameter.In.ToString().ToLower(), In.ToString().ToLower()); } if (this.IsConstant != priorParameter.IsConstant) { context.LogBreakingChange(ComparisonMessages.ConstantStatusHasChanged); } if (Reference != null && !Reference.Equals(priorParameter.Reference)) { context.LogBreakingChange(ComparisonMessages.ReferenceRedirection); } if (Schema != null && priorParameter.Schema != null) { Schema.Compare(context, priorParameter.Schema); } context.Direction = DataDirection.None; return(context.Messages); }
public void Set_difference_actual() { var context = new ComparisonContext() .AddDifference(new SetDifference( breadcrumb: ".Set", expected: new List <object>(), extra: new List <object> { 1, 2, 3 } )); AssertExceptionMessage( context, expectedMessage: @" Comparison Failed: The following 1 differences were found. Actual.Set != Expected.Set Actual.Set contains the following unmatched elements: 1 2 3" ); }
/// <summary> /// Comapares list of required properties of this model /// </summary> /// <param name="context">Comaprision Context</param> /// <param name="priorSchema">Schema of the old model</param> private void CompareRequired(ComparisonContext context, Schema priorSchema) { if (Required == null) { return; } if (Required != null && priorSchema.Required == null) { context.LogBreakingChange(ComparisonMessages.AddedRequiredProperty, string.Join(", ", Required)); return; } var addedRequiredProperties = Required.Except(priorSchema.Required).ToList(); if (addedRequiredProperties.Count > 0) { context.LogBreakingChange(ComparisonMessages.AddedRequiredProperty, string.Join(", ", addedRequiredProperties)); } }
/// <summary>Determines whether two collections are equal by comparing the nodes.</summary> /// <param name="first">A collection of <see cref="Expression"/> to compare.</param> /// <param name="second">A collection of <see cref="Expression"/> to compare to the first sequence.</param> /// <param name="context"></param> /// <returns>true if the two nodes sequences are of equal length and their corresponding elements are equal; otherwise, false.</returns> protected bool Equals( [AllowNull][AllowItemNull] ReadOnlyCollection <Expression?>?first, [AllowNull][AllowItemNull] ReadOnlyCollection <Expression?>?second, [DisallowNull] ComparisonContext context ) { if (ReferenceEquals(first, second)) { return(true); } if (first == null || second == null) { return(false); } using (var e1 = first.GetEnumerator()) using (var e2 = second.GetEnumerator()) { while (e1.MoveNext()) { if (!e2.MoveNext()) { return(false); } if (!Equals(e1.Current, e2.Current, context)) { return(false); } } if (e2.MoveNext()) { return(false); } } return(true); }
public void OpenApiSecurityRequirementComparerShouldSucceed( string testCaseName, OpenApiSecurityRequirement source, OpenApiSecurityRequirement target, List <OpenApiDifference> expectedDifferences) { _output.WriteLine(testCaseName); var comparisonContext = new ComparisonContext(new OpenApiComparerFactory(), _sourceDocument, _targetDocument); var comparer = new OpenApiSecurityRequirementComparer(); comparer.Compare(source, target, comparisonContext); var differences = comparisonContext.OpenApiDifferences.ToList(); differences.Count().Should().Be(expectedDifferences.Count); differences.Should().BeEquivalentTo(expectedDifferences); }
public void Comparing_values(object value1, object value2, ComparisonResult expected) { "Given a Fixture" .x(() => Fixture = new Fixture()); "And an EnumComparer" .x(() => SUT = Fixture.Create <EnumComparison>()); "And a Comparison context object" .x(() => { Context = new ComparisonContext("Property"); }); "When calling Compare({0}, {1})" .x(() => Result = SUT.Compare(Context, value1, value2)); "Then it should return {2}" .x(() => Result.ShouldBe(expected)); if (expected == ComparisonResult.Pass) { "And it should not add any differences" .x(() => Context.Differences.Count.ShouldBe(0)); } else { var expectedDifference = new Difference { Breadcrumb = "Property", Value1 = value1, Value2 = value2 }; "And it should add a differences" .x(() => Context.Differences[0].ShouldBe(expectedDifference)); } }
public void Compares_floats_within_tolarance( double doubleTolerance, float singleTolerance, object value1, object value2, ComparisonResult result) { "Given a DefaultComparison".x(() => SUT = new FloatComparison(doubleTolerance, singleTolerance) ); "And a Comparison context object".x(() => Context = new ComparisonContext() ); "When calling Compare".x(() => (Result, _) = SUT.Compare(Context, value1, value2) ); "And it should return Pass".x(() => Result.ShouldBe(result) ); }
public ComparisonContext comparison() { ComparisonContext _localctx = new ComparisonContext(Context, State); EnterRule(_localctx, 12, RULE_comparison); try { EnterOuterAlt(_localctx, 1); { State = 52; selector(); State = 53; comparator(); State = 54; arguments(); } } catch (RecognitionException re) { _localctx.exception = re; ErrorHandler.ReportError(this, re); ErrorHandler.Recover(this, re); } finally { ExitRule(); } return(_localctx); }
public void Comparing_objects_calls_Equals_method() { var object1 = default(EqualsSpy); var object2 = default(EqualsSpy); "Given a DefaultComparison" .Given(() => SUT = new DefaultComparison()); "And 2 objects to compare" .And(() => { object1 = new EqualsSpy(); object2 = new EqualsSpy(); }); "And a Comparison context object" .And(() => Context = new ComparisonContext()); "When calling Compare" .When(() => Result = SUT.Compare(Context, object1, object2)); "Then it should call Equals" .Then(() => object1.Calls[0].ShouldBeSameAs(object2)); }
public void Comparing_incompatible_types_returns_Inconclusive() { var object1 = default(object); var object2 = default(int); "Given a DefaultComparison" .Given(() => SUT = new DefaultComparison()); "And 2 objects to compare" .And(() => { object1 = new object(); object2 = 123; }); "And a Comparison context object" .And(() => Context = new ComparisonContext()); "When calling Compare" .When(() => Result = SUT.Compare(Context, object1, object2)); "Then it should return Inconclusive" .Then(() => Result.ShouldBe(ComparisonResult.Inconclusive)); }
private void CompareProperties(ComparisonContext context, Schema priorSchema) { // Were any properties removed? if (priorSchema.Properties != null) { foreach (var def in priorSchema.Properties) { Schema model = null; if (Properties == null || !Properties.TryGetValue(def.Key, out model)) { context.LogBreakingChange(ComparisonMessages.RemovedProperty1, def.Key); } else { context.PushProperty(def.Key); model.Compare(context, def.Value); context.Pop(); } } } // Were any required properties added? if (Properties != null) { foreach (var def in Properties.Keys) { Schema model = null; if (priorSchema.Properties == null || !priorSchema.Properties.TryGetValue(def, out model) && Required.Contains(def)) { context.LogBreakingChange(ComparisonMessages.AddedRequiredProperty1, def); } } } }
public void SetUp() { "Given a fixture" .Given(() => { Fixture = new Fixture(); Fixture.Customize(new AutoMoqCustomization()); }); "And an inner comparison" .And(() => { Inner = Fixture.Freeze <Mock <IComparison> >(); Inner.Setup(x => x.Compare(It.IsAny <IComparisonContext>(), It.IsAny <object>(), It.IsAny <object>())) .Returns <IComparisonContext, object, object>( (c, v1, v2) => { if (v1.Equals(v2)) { return(ComparisonResult.Pass); } c.AddDifference(new Difference()); return(ComparisonResult.Fail); }); }); "And a ComplexObjectComparison" .And(() => SUT = Fixture.Build <ComplexObjectComparison>() .OmitAutoProperties() .Create()); "And a Comparison context object" .And(() => Context = new ComparisonContext("Property")); }
public static void ShouldDeepEqual( this object actual, object expected, IComparison comparison, IDifferenceFormatterFactory formatterFactory) { var builder = new ComparisonBuilder(); comparison = comparison ?? builder.Create(); formatterFactory = formatterFactory ?? builder.GetFormatterFactory(); var context = new ComparisonContext(); var(result, newContext) = comparison.Compare(context, actual, expected); if (result != ComparisonResult.Fail) { return; } var message = new DeepEqualExceptionMessageBuilder(newContext, formatterFactory).GetMessage(); throw new DeepEqualException(message, newContext); }
private void SetUp() { "Given a fixture".x(() => { Fixture = new Fixture(); Fixture.Customize(new AutoMoqCustomization()); }); "And an inner comparison".x(() => { Inner = new MockComparison(); Fixture.Inject <IComparison>(Inner); }); "And a ComplexObjectComparison".x(() => SUT = Fixture.Build <ComplexObjectComparison>() .OmitAutoProperties() .Create() ); "And a Comparison context object".x(() => Context = new ComparisonContext("Property") ); }
private void CompareAllOfs(ComparisonContext <ServiceDefinition> context, Schema priorSchema) { var different = 0; foreach (var schema in priorSchema.AllOf) { if (!AllOf.Select(s => s.Reference).ToArray().Contains(schema.Reference)) { different += 1; } } foreach (var schema in AllOf) { if (!priorSchema.AllOf.Select(s => s.Reference).ToArray().Contains(schema.Reference)) { different += 1; } } if (different > 0) { context.LogBreakingChange(ComparisonMessages.DifferentAllOf); } }
private bool AreKeysEqual(IDictionary expected, IDictionary actual, ComparisonContext comparisonContext, ValueComparison valueComparison) { var notInExpected = actual.Keys .Cast<object>() .Where(x => !expected.Contains(x)); var notInActual = expected.Keys .Cast<object>() .Where(x => !actual.Contains(x)); var result = true; foreach (var key in notInActual) { var keyComparison = this.CreateKeyNamedComparison( valueComparison, key.ToString(), "The dictionaries differ, the key '{0}' is missing in the actual value."); comparisonContext.AddDifference(keyComparison); result = false; } foreach (var key in notInExpected) { var keyComparison = this.CreateKeyNamedComparison( valueComparison, key.ToString(), "The dictionaries differ, there is an extra key '{0}' in the actual value."); comparisonContext.AddDifference(keyComparison); result = false; } return result; }
public void No_differences_recorded() { var context = new ComparisonContext(); AssertExceptionMessage(context, "Comparison Failed"); }
protected void CompareConstraints(ComparisonContext context, SwaggerObject prior) { if (prior == null) { throw new ArgumentNullException("prior"); } if (context == null) { throw new ArgumentNullException("context"); } if ((prior.MultipleOf == null && MultipleOf != null) || (prior.MultipleOf != null && !prior.MultipleOf.Equals(MultipleOf))) { context.LogBreakingChange(ComparisonMessages.ConstraintChanged, "multipleOf"); } if ((prior.Maximum == null && Maximum != null) || (prior.Maximum != null && !prior.Maximum.Equals(Maximum)) || prior.ExclusiveMaximum != ExclusiveMaximum) { // Flag stricter constraints for requests and relaxed constraints for responses. if (prior.ExclusiveMaximum != ExclusiveMaximum || context.Direction == DataDirection.None) { context.LogBreakingChange(ComparisonMessages.ConstraintChanged, "maximum"); } else if (context.Direction == DataDirection.Request && Narrows(prior.Maximum, Maximum, true)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsStronger, "maximum"); } else if (context.Direction == DataDirection.Response && Widens(prior.Maximum, Maximum, true)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsWeaker, "maximum"); } else if (Narrows(prior.Maximum, Maximum, false)) { context.LogInfo(ComparisonMessages.ConstraintIsStronger, "maximum"); } else if (Widens(prior.Maximum, Maximum, false)) { context.LogInfo(ComparisonMessages.ConstraintIsWeaker, "maximum"); } } if ((prior.Minimum == null && Minimum != null) || (prior.Minimum != null && !prior.Minimum.Equals(Minimum)) || prior.ExclusiveMinimum != ExclusiveMinimum) { // Flag stricter constraints for requests and relaxed constraints for responses. if (prior.ExclusiveMinimum != ExclusiveMinimum || context.Direction == DataDirection.None) { context.LogBreakingChange(ComparisonMessages.ConstraintChanged, "minimum"); } else if (context.Direction == DataDirection.Request && Narrows(prior.Minimum, Minimum, true)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsStronger, "minimum"); } else if (context.Direction == DataDirection.Response && Widens(prior.Minimum, Minimum, true)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsWeaker, "minimum"); } else if (Narrows(prior.Minimum, Minimum, false)) { context.LogInfo(ComparisonMessages.ConstraintIsStronger, "minimum"); } else if (Widens(prior.Minimum, Minimum, false)) { context.LogInfo(ComparisonMessages.ConstraintIsWeaker, "minimum"); } } if ((prior.MaxLength == null && MaxLength != null) || (prior.MaxLength != null && !prior.MaxLength.Equals(MaxLength))) { // Flag stricter constraints for requests and relaxed constraints for responses. if (context.Direction == DataDirection.None) { context.LogBreakingChange(ComparisonMessages.ConstraintChanged, "maxLength"); } else if (context.Direction == DataDirection.Request && Narrows(prior.MaxLength, MaxLength, false)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsStronger, "maxLength"); } else if (context.Direction == DataDirection.Response && Widens(prior.MaxLength, MaxLength, false)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsWeaker, "maxLength"); } else if (Narrows(prior.MaxLength, MaxLength, false)) { context.LogInfo(ComparisonMessages.ConstraintIsStronger, "maxLength"); } else if (Widens(prior.MaxLength, MaxLength, false)) { context.LogInfo(ComparisonMessages.ConstraintIsWeaker, "maxLength"); } } if ((prior.MinLength == null && MinLength != null) || (prior.MinLength != null && !prior.MinLength.Equals(MinLength))) { // Flag stricter constraints for requests and relaxed constraints for responses. if (context.Direction == DataDirection.None) { context.LogBreakingChange(ComparisonMessages.ConstraintChanged, "minLength"); } else if (context.Direction == DataDirection.Request && Narrows(prior.MinLength, MinLength, true)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsStronger, "minimum"); } else if (context.Direction == DataDirection.Response && Widens(prior.MinLength, MinLength, true)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsWeaker, "minimum"); } else if (Narrows(prior.MinLength, MinLength, false)) { context.LogInfo(ComparisonMessages.ConstraintIsStronger, "minLength"); } else if (Widens(prior.MinLength, MinLength, false)) { context.LogInfo(ComparisonMessages.ConstraintIsWeaker, "minLength"); } } if ((prior.Pattern == null && Pattern != null) || (prior.Pattern != null && !prior.Pattern.Equals(Pattern))) { context.LogBreakingChange(ComparisonMessages.ConstraintChanged, "pattern"); } if ((prior.MaxItems == null && MaxItems != null) || (prior.MaxItems != null && !prior.MaxItems.Equals(MaxItems))) { // Flag stricter constraints for requests and relaxed constraints for responses. if (context.Direction == DataDirection.None) { context.LogBreakingChange(ComparisonMessages.ConstraintChanged, "maxItems"); } else if (context.Direction == DataDirection.Request && Narrows(prior.MaxItems, MaxItems, false)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsStronger, "maxItems"); } else if (context.Direction == DataDirection.Response && Widens(prior.MaxItems, MaxItems, false)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsWeaker, "maxItems"); } else if (Narrows(prior.MaxItems, MaxItems, false)) { context.LogInfo(ComparisonMessages.ConstraintIsStronger, "maxItems"); } else if (Widens(prior.MaxItems, MaxItems, false)) { context.LogInfo(ComparisonMessages.ConstraintIsWeaker, "maxItems"); } } if ((prior.MinItems == null && MinItems != null) || (prior.MinItems != null && !prior.MinItems.Equals(MinItems))) { // Flag stricter constraints for requests and relaxed constraints for responses. if (context.Direction == DataDirection.None) { context.LogBreakingChange(ComparisonMessages.ConstraintChanged, "minItems"); } else if (context.Direction == DataDirection.Request && Narrows(prior.MinItems, MinItems, true)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsStronger, "minItems"); } else if (context.Direction == DataDirection.Response && Widens(prior.MinItems, MinItems, true)) { context.LogBreakingChange(ComparisonMessages.ConstraintIsWeaker, "minItems"); } else if (Narrows(prior.MinItems, MinItems, true)) { context.LogInfo(ComparisonMessages.ConstraintIsStronger, "minItems"); } else if (Widens(prior.MinItems, MinItems, true)) { context.LogInfo(ComparisonMessages.ConstraintIsWeaker, "minItems"); } } if (prior.UniqueItems != UniqueItems) { context.LogBreakingChange(ComparisonMessages.ConstraintChanged, "uniqueItems"); } }
/// <summary> /// Compare a modified document node (this) to a previous one and look for breaking as well as non-breaking changes. /// </summary> /// <param name="context">The modified document context.</param> /// <param name="previous">The original document model.</param> /// <returns>A list of messages from the comparison.</returns> public override IEnumerable <ComparisonMessage> Compare(ComparisonContext context, SwaggerBase previous) { var prior = previous as SwaggerObject; if (prior == null) { throw new ArgumentNullException("priorVersion"); } if (context == null) { throw new ArgumentNullException("context"); } base.Compare(context, previous); if (Reference != null && !Reference.Equals(prior.Reference)) { context.LogBreakingChange(ComparisonMessages.ReferenceRedirection); } if (IsRequired != prior.IsRequired) { if (context.Direction != DataDirection.Response) { if (IsRequired && !prior.IsRequired) { context.LogBreakingChange(ComparisonMessages.RequiredStatusChange); } else { context.LogInfo(ComparisonMessages.RequiredStatusChange); } } } // Are the types the same? if (prior.Type.HasValue != Type.HasValue || (Type.HasValue && prior.Type.Value != Type.Value)) { context.LogBreakingChange(ComparisonMessages.TypeChanged); } // What about the formats? CompareFormats(context, prior); CompareItems(context, prior); if (Default != null && !Default.Equals(prior.Default) || (Default == null && !string.IsNullOrEmpty(prior.Default))) { context.LogBreakingChange(ComparisonMessages.DefaultValueChanged); } if (Type.HasValue && Type.Value == DataType.Array && prior.CollectionFormat != CollectionFormat) { context.LogBreakingChange(ComparisonMessages.ArrayCollectionFormatChanged); } CompareConstraints(context, prior); CompareProperties(context, prior); CompareEnums(context, prior); return(context.Messages); }
public void Strings_around_same_length_as_max_length(string value1, string value2, string expected1, string expected2) { var context = new ComparisonContext(); context.AddDifference( value1, value2); AssertExceptionMessage(context, string.Format(@" Comparison Failed: The following 1 differences were found. Actual != Expected (""{0}"" != ""{1}"")", expected1, expected2)); }
public void Single_int_difference() { var context = new ComparisonContext(); context.AddDifference(1, 2); AssertExceptionMessage(context, @" Comparison Failed: The following 1 differences were found. Actual != Expected (1 != 2)"); }
/// <summary> /// Check that no parameters were removed or reordered, and compare them if it's not the case /// </summary> /// <param name="context">Comaprision Context</param> /// <param name="priorOperation">Operation object of old swagger</param> private void CheckParameters(ComparisonContext <ServiceDefinition> context, Operation priorOperation) { // Check that no parameters were removed or reordered, and compare them if it's not the case. var currentRoot = context.CurrentRoot; var previousRoot = context.PreviousRoot; context.PushProperty("parameters"); var priorOperationParameters = priorOperation.Parameters.Select(param => string.IsNullOrWhiteSpace(param.Reference) ? param : FindReferencedParameter(param.Reference, previousRoot.Parameters) ); var currentOperationParameters = Parameters.Select(param => string.IsNullOrWhiteSpace(param.Reference) ? param : FindReferencedParameter(param.Reference, currentRoot.Parameters)); for (int i = 0; i < currentOperationParameters.Count(); i++) { var curOriginalParameter = Parameters.ElementAt(i); var curParameter = currentOperationParameters.ElementAt(i); curParameter.Extensions.TryGetValue("x-ms-long-running-operation", out var curParameterLocation); if ( !string.IsNullOrWhiteSpace(curOriginalParameter.Reference) && (curParameterLocation == null || !curParameterLocation.Equals("method")) ) { continue; } var priorIndex = FindParameterIndex(curParameter, priorOperationParameters); if (priorIndex != -1 && priorIndex != i) { context.LogBreakingChange(ComparisonMessages.ChangedParameterOrder, curParameter.Name); } } foreach (var oldParam in priorOperationParameters) { SwaggerParameter newParam = FindParameterEx(oldParam, Parameters, currentRoot.Parameters); // we should use PushItemByName instead of PushProperty because Swagger `parameters` is // an array of paremters. context.PushItemByName(oldParam.Name); if (newParam != null) { newParam.Compare(context, oldParam); } else if (oldParam.IsRequired) { // Removed required parameter context.LogBreakingChange(ComparisonMessages.RemovedRequiredParameter, oldParam.Name); } else { // Removed optional parameter context.LogBreakingChange(ComparisonMessages.RemovedOptionalParameter, oldParam.Name); } context.Pop(); } // Check that no required or optional parameters were added. var allParamters = Parameters.Select(param => string.IsNullOrWhiteSpace(param.Reference) ? param : FindReferencedParameter(param.Reference, currentRoot.Parameters)) .Where(p => p != null); foreach (var newParam in allParamters) { if (newParam == null) { continue; } SwaggerParameter oldParam = FindParameterEx(newParam, priorOperation.Parameters, previousRoot.Parameters); if (oldParam == null) { // Did not find required parameter in the old swagger i.e required parameter is added context.PushItemByName(newParam.Name); if (newParam.IsRequired) { context.LogBreakingChange(ComparisonMessages.AddingRequiredParameter, newParam.Name); } else { context.LogBreakingChange(ComparisonMessages.AddingOptionalParameter, newParam.Name); } context.Pop(); } } context.Pop(); }
/// <summary>Determines whether the children of the two CatchBlock are equal.</summary> /// <param name="x">The first CatchBlock to compare.</param> /// <param name="y">The second CatchBlock to compare.</param> /// <param name="context"></param> /// <returns>true if the specified CatchBlock are equal; otherwise, false.</returns> protected virtual bool EqualsCatchBlock([DisallowNull] CatchBlock x, [DisallowNull] CatchBlock y, [DisallowNull] ComparisonContext context) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } return(x.Test == y.Test && Equals(x.Body, y.Body, context) && Equals(x.Filter, y.Filter, context) && Equals(x.Variable, y.Variable, context)); }
/// <summary>Determines whether the children of the two extension <see cref="Expression"/> are equal.</summary> /// <param name="x">The first extension <see cref="Expression"/> to compare.</param> /// <param name="y">The second extension <see cref="Expression"/> to compare.</param> /// <param name="context"></param> /// <returns>true if the specified extension <see cref="Expression"/> are equal; otherwise, false.</returns> protected virtual bool EqualsExtension([DisallowNull] Expression x, [DisallowNull] Expression y, [DisallowNull] ComparisonContext context) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } return(Equals(x.ReduceExtensions(), y.ReduceExtensions(), context)); }
public void When_comparing_sets(IEnumerable value1, IEnumerable value2, ComparisonResult expected) { var list1 = value1.Cast<object>().ToArray(); var list2 = value2.Cast<object>().ToArray(); "Given a fixture" .Given(() => { Fixture = new Fixture(); Fixture.Customize(new AutoMoqCustomization()); }); "And an inner comparison" .And(() => { Inner = Fixture.Freeze<Mock<IComparison>>(); Inner .Setup(x => x.CanCompare(It.IsAny<Type>(), It.IsAny<Type>())) .Returns(true); Inner .Setup(x => x.Compare(It.IsAny<IComparisonContext>(), It.IsAny<object>(), It.IsAny<object>())) .Returns<IComparisonContext, object, object>((c, v1, v2) => v1.Equals(v2) ? ComparisonResult.Pass : ComparisonResult.Fail); }); "And a SetComparison" .And(() => SUT = Fixture.Create<SetComparison>()); "And a Comparison context object" .And(() => Context = new ComparisonContext("Set")); "When comparing enumerables" .When(() => Result = SUT.Compare(Context, value1, value2)); "Then it should return {2}" .Then(() => Result.ShouldBe(expected)); if (list1.Length == list2.Length) { "And it should call the inner comparison Compare for each element in the set" .And(() => { for (var i = 0; i < list1.Length; i++) { var local = i; Inner.Verify(x => x.Compare( It.IsAny<ComparisonContext>(), list1[local], It.IsAny<object>()), Times.AtLeastOnce()); } }); if (expected == ComparisonResult.Fail) { "And it should add a SetDifference" .And(() => Context.Differences[0].ShouldBeTypeOf<SetDifference>()); } } else { var expectedDifference = new Difference { Breadcrumb = "Set", ChildProperty = "Count", Value1 = list1.Length, Value2 = list2.Length }; "And it should add a Difference" .And(() => Context.Differences[0].ShouldBe(expectedDifference)); } }
/// <summary>Determines whether the children of the two <see cref="ListInitExpression"/> are equal.</summary> /// <param name="x">The first <see cref="ListInitExpression"/> to compare.</param> /// <param name="y">The second <see cref="ListInitExpression"/> to compare.</param> /// <param name="context"></param> /// <returns>true if the specified <see cref="ListInitExpression"/> are equal; otherwise, false.</returns> protected virtual bool EqualsListInit([DisallowNull] ListInitExpression x, [DisallowNull] ListInitExpression y, [DisallowNull] ComparisonContext context) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } return(x.Type == y.Type && Equals(x.NewExpression, y.NewExpression, context) && Equals(x.Initializers, y.Initializers, EqualsElementInit, context)); }
/// <summary>Determines whether the children of the two <see cref="RuntimeVariablesExpression"/> are equal.</summary> /// <param name="x">The first <see cref="RuntimeVariablesExpression"/> to compare.</param> /// <param name="y">The second <see cref="RuntimeVariablesExpression"/> to compare.</param> /// <param name="context"></param> /// <returns>true if the specified <see cref="RuntimeVariablesExpression"/> are equal; otherwise, false.</returns> protected virtual bool EqualsRuntimeVariables([DisallowNull] RuntimeVariablesExpression x, [DisallowNull] RuntimeVariablesExpression y, [DisallowNull] ComparisonContext context) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } return(x.Type == y.Type && Equals(x.Variables, y.Variables, EqualsParameter, context)); }
public DeepEqualExceptionMessageBuilder(ComparisonContext context) { this.context = context; formatterFactory = new DifferenceFormatterFactory(); }
public void Single_string_difference() { var context = new ComparisonContext(); context.AddDifference("a", "b"); AssertExceptionMessage(context, @" Comparison Failed: The following 1 differences were found. Actual != Expected (""a"" != ""b"")"); }
private static void AssertExceptionMessage(ComparisonContext context, string expectedMessage) { expectedMessage = expectedMessage.Trim().Replace("\r\n", "\n"); var messageBuilder = new DeepEqualExceptionMessageBuilder(context); var message = messageBuilder.GetMessage().Replace("\r\n", "\n"); Assert.Equal(expectedMessage, message); }
/// <summary> /// Compare a modified document node (this) to a previous one and look for breaking as well as non-breaking changes. /// </summary> /// <param name="context">The modified document context.</param> /// <param name="previous">The original document model.</param> /// <returns>A list of messages from the comparison.</returns> public override IEnumerable <ComparisonMessage> Compare( ComparisonContext <ServiceDefinition> context, Operation previous ) { var priorOperation = previous; var currentRoot = context.CurrentRoot; var previousRoot = context.PreviousRoot; if (priorOperation == null) { throw new ArgumentException("previous"); } base.Compare(context, previous); if (OperationId != priorOperation.OperationId) { context.LogBreakingChange(ComparisonMessages.ModifiedOperationId, priorOperation.OperationId, OperationId); } Extensions.TryGetValue("x-ms-long-running-operation", out var currentLongrunningOperationValue); priorOperation.Extensions.TryGetValue("x-ms-long-running-operation", out var priorLongrunningOperationValue); currentLongrunningOperationValue = currentLongrunningOperationValue == null ? false : currentLongrunningOperationValue; priorLongrunningOperationValue = priorLongrunningOperationValue == null ? false : priorLongrunningOperationValue; if (!currentLongrunningOperationValue.Equals(priorLongrunningOperationValue)) { context.LogBreakingChange(ComparisonMessages.XmsLongRunningOperationChanged); } CheckParameters(context, priorOperation); // Check that all the request body formats that were accepted still are. context.PushProperty("consumes"); foreach (var format in priorOperation.Consumes) { if (!Consumes.Contains(format)) { context.LogBreakingChange(ComparisonMessages.RequestBodyFormatNoLongerSupported, format); } } context.Pop(); // Check that all the response body formats were also supported by the old version. context.PushProperty("produces"); foreach (var format in Produces) { if (!priorOperation.Produces.Contains(format)) { context.LogBreakingChange(ComparisonMessages.ResponseBodyFormatNowSupported, format); } } context.Pop(); if (Responses != null && priorOperation.Responses != null) { context.PushProperty("responses"); foreach (var response in Responses) { var oldResponse = priorOperation.FindResponse(response.Key, priorOperation.Responses); context.PushProperty(response.Key); if (oldResponse == null) { context.LogBreakingChange(ComparisonMessages.AddingResponseCode, response.Key); } else { response.Value.Compare(context, oldResponse); } context.Pop(); } foreach (var response in priorOperation.Responses) { var newResponse = this.FindResponse(response.Key, this.Responses); if (newResponse == null) { context.PushProperty(response.Key); context.LogBreakingChange(ComparisonMessages.RemovedResponseCode, response.Key); context.Pop(); } } context.Pop(); } return(context.Messages); }
public void SetUp() { "Given a fixture" .Given(() => { Fixture = new Fixture(); Fixture.Customize(new AutoMoqCustomization()); }); "And an inner comparison" .And(() => { Inner = Fixture.Freeze<Mock<IComparison>>(); Inner.Setup(x => x.Compare(It.IsAny<IComparisonContext>(), It.IsAny<object>(), It.IsAny<object>())) .Returns<IComparisonContext, object, object>( (c, v1, v2) => { if (v1.Equals(v2)) { return ComparisonResult.Pass; } c.AddDifference(new Difference()); return ComparisonResult.Fail; }); }); "And a ComplexObjectComparison" .And(() => SUT = Fixture.Build<ComplexObjectComparison>() .OmitAutoProperties() .Create()); "And a Comparison context object" .And(() => Context = new ComparisonContext("Property")); }
/// <summary>Determines whether the children of the two <see cref="TryExpression"/> are equal.</summary> /// <param name="x">The first <see cref="TryExpression"/> to compare.</param> /// <param name="y">The second <see cref="TryExpression"/> to compare.</param> /// <param name="context"></param> /// <returns>true if the specified <see cref="TryExpression"/> are equal; otherwise, false.</returns> protected virtual bool EqualsTry([DisallowNull] TryExpression x, [DisallowNull] TryExpression y, [DisallowNull] ComparisonContext context) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } return(x.Type == y.Type && Equals(x.Body, y.Body, context) && Equals(x.Fault, y.Fault, context) && Equals(x.Finally, y.Finally, context) && Equals(x.Handlers, y.Handlers, EqualsCatchBlock, context)); }
/// <summary>Determines whether the children of the two <see cref="TypeBinaryExpression"/> are equal.</summary> /// <param name="x">The first <see cref="TypeBinaryExpression"/> to compare.</param> /// <param name="y">The second <see cref="TypeBinaryExpression"/> to compare.</param> /// <param name="context"></param> /// <returns>true if the specified <see cref="TypeBinaryExpression"/> are equal; otherwise, false.</returns> protected virtual bool EqualsTypeBinary([DisallowNull] TypeBinaryExpression x, [DisallowNull] TypeBinaryExpression y, [DisallowNull] ComparisonContext context) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } return(x.Type == y.Type && x.TypeOperand == y.TypeOperand && Equals(x.Expression, y.Expression, context)); }
public DeepEqualException(ComparisonContext context) : this(new DeepEqualExceptionMessageBuilder(context).GetMessage()) { Context = context; }
public void Set_difference_expected() { var context = new ComparisonContext(); context.AddDifference(new SetDifference(".Set", new List<object>{1,2,3}, new List<object>())); AssertExceptionMessage(context, @" Comparison Failed: The following 1 differences were found. Actual.Set != Expected.Set Expected.Set contains the following unmatched elements: 1 2 3"); }
public void Comparing_value_types_returns_Pass_or_Fail(object value1, object value2, bool expected) { "Given a DefaultComparison" .Given(() => SUT = new DefaultComparison()); "And a Comparison context object" .And(() => Context = new ComparisonContext("Root")); "When calling Compare" .When(() => Result = SUT.Compare(Context, value1, value2)); "The result should be Pass or Fail" .Then(() => Result.ShouldBe(expected ? ComparisonResult.Pass : ComparisonResult.Fail)); if (!expected) { var expectedDifference = new Difference { Breadcrumb = "Root", Value1 = value1, Value2 = value2 }; "And it should add a difference" .And(() => Context.Differences[0].ShouldBe(expectedDifference)); } }
/// <summary>Determines whether the children of the two <see cref="MemberExpression"/> are equal.</summary> /// <param name="x">The first <see cref="MemberExpression"/> to compare.</param> /// <param name="y">The second <see cref="MemberExpression"/> to compare.</param> /// <param name="context"></param> /// <returns>true if the specified <see cref="MemberExpression"/> are equal; otherwise, false.</returns> protected virtual bool EqualsMember([DisallowNull] MemberExpression x, [DisallowNull] MemberExpression y, [DisallowNull] ComparisonContext context) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } return(x.Type == y.Type && Equals(x.Member, y.Member) && Equals(x.Expression, y.Expression, context)); }
/// <summary> /// Compare a modified document node (this) to a previous one and look for breaking as well as non-breaking changes. /// </summary> /// <param name="context">The modified document context.</param> /// <param name="previous">The original document model.</param> /// <returns>A list of messages from the comparison.</returns> public override IEnumerable <ComparisonMessage> Compare(ComparisonContext context, SwaggerBase previous) { if (previous == null) { throw new ArgumentNullException("previous"); } context.CurrentRoot = this; context.PreviousRoot = previous; base.Compare(context, previous); var previousDefinition = previous as ServiceDefinition; if (previousDefinition == null) { throw new ArgumentException("Comparing a service definition with something else."); } if (Info != null && previousDefinition.Info != null) { context.PushProperty("info"); context.PushProperty("version"); CompareVersions(context, Info.Version, previousDefinition.Info.Version); context.Pop(); context.Pop(); } if (context.Strict) { // There was no version change between the documents. This is not an error, but noteworthy. context.LogInfo(ComparisonMessages.NoVersionChange); } // Check that all the protocols of the old version are supported by the new version. context.PushProperty("schemes"); foreach (var scheme in previousDefinition.Schemes) { if (!Schemes.Contains(scheme)) { context.LogBreakingChange(ComparisonMessages.ProtocolNoLongerSupported, scheme); } } context.Pop(); // Check that all the request body formats that were accepted still are. context.PushProperty("consumes"); foreach (var format in previousDefinition.Consumes) { if (!Consumes.Contains(format)) { context.LogBreakingChange(ComparisonMessages.RequestBodyFormatNoLongerSupported, format); } } context.Pop(); // Check that all the response body formats were also supported by the old version. context.PushProperty("produces"); foreach (var format in Produces) { if (!previousDefinition.Produces.Contains(format)) { context.LogBreakingChange(ComparisonMessages.ResponseBodyFormatNowSupported, format); } } context.Pop(); // Check that no paths were removed, and compare the paths that are still there. var newPaths = RemovePathVariables(Paths); context.PushProperty("paths"); foreach (var path in previousDefinition.Paths.Keys) { var p = Regex.Replace(path, @"\{\w*\}", @"{}"); context.PushProperty(path); Dictionary <string, Operation> operations = null; if (!newPaths.TryGetValue(p, out operations)) { context.LogBreakingChange(ComparisonMessages.RemovedPath, path); } else { Dictionary <string, Operation> previousOperations = previousDefinition.Paths[path]; foreach (var previousOperation in previousOperations) { Operation newOperation = null; if (!operations.TryGetValue(previousOperation.Key, out newOperation)) { context.LogBreakingChange(ComparisonMessages.RemovedOperation, previousOperation.Value.OperationId); } } foreach (var operation in operations) { Operation previousOperation = null; if (previousDefinition.Paths[path].TryGetValue(operation.Key, out previousOperation)) { context.PushProperty(operation.Key); operation.Value.Compare(context, previousOperation); context.Pop(); } } } context.Pop(); } context.Pop(); newPaths = RemovePathVariables(CustomPaths); context.PushProperty("x-ms-paths"); foreach (var path in previousDefinition.CustomPaths.Keys) { var p = Regex.Replace(path, @"\{\w*\}", @"{}"); context.PushProperty(path); Dictionary <string, Operation> operations = null; if (!newPaths.TryGetValue(p, out operations)) { context.LogBreakingChange(ComparisonMessages.RemovedPath, path); } else { Dictionary <string, Operation> previousOperations = previousDefinition.CustomPaths[path]; foreach (var previousOperation in previousOperations) { Operation newOperation = null; if (!operations.TryGetValue(previousOperation.Key, out newOperation)) { context.LogBreakingChange(ComparisonMessages.RemovedOperation, previousOperation.Value.OperationId); } } foreach (var operation in operations) { Operation previousOperation = null; if (previousDefinition.CustomPaths[path].TryGetValue(operation.Key, out previousOperation)) { context.PushProperty(operation.Key); operation.Value.Compare(context, previousOperation); context.Pop(); } } } context.Pop(); } context.Pop(); ReferenceTrackSchemas(this); ReferenceTrackSchemas(previousDefinition); context.PushProperty("parameters"); foreach (var def in previousDefinition.Parameters.Keys) { SwaggerParameter parameter = null; if (!Parameters.TryGetValue(def, out parameter)) { context.LogBreakingChange(ComparisonMessages.RemovedClientParameter, def); } else { context.PushProperty(def); parameter.Compare(context, previousDefinition.Parameters[def]); context.Pop(); } } context.Pop(); context.PushProperty("responses"); foreach (var def in previousDefinition.Responses.Keys) { OperationResponse response = null; if (!Responses.TryGetValue(def, out response)) { context.LogBreakingChange(ComparisonMessages.RemovedDefinition, def); } else { context.PushProperty(def); response.Compare(context, previousDefinition.Responses[def]); context.Pop(); } } context.Pop(); context.PushProperty("definitions"); foreach (var def in previousDefinition.Definitions.Keys) { Schema schema = null; Schema oldSchema = previousDefinition.Definitions[def]; if (!Definitions.TryGetValue(def, out schema)) { if (oldSchema.IsReferenced) { // It's only an error if the definition is referenced in the old service. context.LogBreakingChange(ComparisonMessages.RemovedDefinition, def); } } else if (schema.IsReferenced && oldSchema.IsReferenced) { context.PushProperty(def); schema.Compare(context, previousDefinition.Definitions[def]); context.Pop(); } } context.Pop(); context.Pop(); return(context.Messages); }
/// <inheritdoc /> /// <summary> /// Compare a modified document node (this) to a previous one and look for breaking as well as non-breaking changes. /// </summary> /// <param name="context">The modified document context.</param> /// <param name="previous">The original document model.</param> /// <returns>A list of messages from the comparison.</returns> public override IEnumerable <ComparisonMessage> Compare( ComparisonContext <ServiceDefinition> context, Schema previous ) { var priorSchema = previous; if (priorSchema == null) { throw new ArgumentNullException("priorVersion"); } if (context == null) { throw new ArgumentNullException("context"); } int referenced = 0; var thisSchema = this; if (!string.IsNullOrWhiteSpace(thisSchema.Reference)) { thisSchema = FindReferencedSchema(thisSchema.Reference, context.CurrentRoot.Definitions); referenced += 1; if (thisSchema == null) { return(context.Messages); } } if (!string.IsNullOrWhiteSpace(priorSchema.Reference)) { priorSchema = FindReferencedSchema(priorSchema.Reference, context.PreviousRoot.Definitions); referenced += 1; if (priorSchema == null) { return(context.Messages); } } // Avoid doing the comparison repeatedly by marking for which direction it's already been done. if (context.Direction != DataDirection.None && referenced == 2) { // Comparing two referenced schemas in the context of a parameter or response -- did we already do this? if (thisSchema._compareDirection == context.Direction || thisSchema._compareDirection == DataDirection.Both) { return(new ComparisonMessage[0]); } _compareDirection |= context.Direction; } if (thisSchema != this || priorSchema != previous) { if (_visitedSchemas.Contains(priorSchema)) { return(context.Messages); } _visitedSchemas.AddFirst(priorSchema); return(thisSchema.Compare(context, priorSchema)); } base.Compare(context, previous); if (priorSchema.ReadOnly != ReadOnly) { context.LogBreakingChange(ComparisonMessages.ReadonlyPropertyChanged, priorSchema.ReadOnly.ToString().ToLower(), ReadOnly.ToString().ToLower()); } if ((priorSchema.Discriminator == null && Discriminator != null) || (priorSchema.Discriminator != null && !priorSchema.Discriminator.Equals(Discriminator))) { context.LogBreakingChange(ComparisonMessages.DifferentDiscriminator); } if ((priorSchema.Extends == null && Extends != null) || (priorSchema.Extends != null && !priorSchema.Extends.Equals(Extends))) { context.LogBreakingChange(ComparisonMessages.DifferentExtends); } if ((priorSchema.AllOf == null && AllOf != null) || (priorSchema.AllOf != null && AllOf == null)) { context.LogBreakingChange(ComparisonMessages.DifferentAllOf); } else if (priorSchema.AllOf != null) { CompareAllOfs(context, priorSchema); } // Compare each properties of the model context.PushProperty("properties"); CompareProperties(context, priorSchema); context.Pop(); // Compare `required` list of properties of the model CompareRequired(context, priorSchema); return(context.Messages); }
public ComparisonContext comparison() { ComparisonContext _localctx = new ComparisonContext(Context, State); EnterRule(_localctx, 106, RULE_comparison); int _la; try { EnterOuterAlt(_localctx, 1); { State = 719; star_expr(); State = 725; ErrorHandler.Sync(this); _la = TokenStream.La(1); while (((((_la - 15)) & ~0x3f) == 0 && ((1L << (_la - 15)) & ((1L << (IN - 15)) | (1L << (NOT - 15)) | (1L << (IS - 15)) | (1L << (LESS_THAN - 15)) | (1L << (GREATER_THAN - 15)) | (1L << (EQUALS - 15)) | (1L << (GT_EQ - 15)) | (1L << (LT_EQ - 15)) | (1L << (NOT_EQ_1 - 15)) | (1L << (NOT_EQ_2 - 15)))) != 0)) { { { State = 720; comp_op(); State = 721; star_expr(); } } State = 727; ErrorHandler.Sync(this); _la = TokenStream.La(1); } } } catch (RecognitionException re) { _localctx.exception = re; ErrorHandler.ReportError(this, re); ErrorHandler.Recover(this, re); } finally { ExitRule(); } return _localctx; }
public void Comparing_objects_calls_Equals_method() { var object1 = default (EqualsSpy); var object2 = default (EqualsSpy); "Given a DefaultComparison" .Given(() => SUT = new DefaultComparison()); "And 2 objects to compare" .And(() => { object1 = new EqualsSpy(); object2 = new EqualsSpy(); }); "And a Comparison context object" .And(() => Context = new ComparisonContext()); "When calling Compare" .When(() => Result = SUT.Compare(Context, object1, object2)); "Then it should call Equals" .Then(() => object1.Calls[0].ShouldBeSameAs(object2)); }
public void null_difference() { var context = new ComparisonContext(); context.AddDifference(null, new object()); AssertExceptionMessage(context, @" Comparison Failed: The following 1 differences were found. Actual != Expected ((null) != System.Object)"); }