Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions src/Microsoft.OpenApi/Services/OpenApiComparerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Licensed under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Models;

namespace Microsoft.OpenApi.Services
Expand Down Expand Up @@ -46,6 +48,32 @@ internal void Compare(string source, string target, ComparisonContext comparison
}
}

/// <summary>
/// Compares two Uri object.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="target">The target.</param>
/// <param name="comparisonContext">The context under which to compare the objects.</param>
internal void Compare(Uri source, Uri target, ComparisonContext comparisonContext)
{
if (source == null && target == null)
{
return;
}

if (source != target)
{
comparisonContext.AddOpenApiDifference(new OpenApiDifference
{
OpenApiDifferenceOperation = OpenApiDifferenceOperation.Update,
OpenApiComparedElementType = typeof(Uri),
SourceValue = source,
TargetValue = target,
Pointer = comparisonContext.PathString
});
}
}

/// <summary>
/// Compares two boolean object.
/// </summary>
Expand Down Expand Up @@ -138,6 +166,67 @@ internal void Compare<TEnum>(Enum source, Enum target, ComparisonContext compari
}
}

/// <summary>
/// Compares <see cref="IDictionary{TKey,TValue}"/> where TKey is <see cref="string"/> and TValue is
/// <see cref="string"/>.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="target">The target.</param>
/// <param name="comparisonContext">The context under which to compare the objects.</param>
internal void Compare(IDictionary<string, string> source, IDictionary<string, string> target,
ComparisonContext comparisonContext)
{
if (source == null && target == null)
{
return;
}

if (source == null || target == null)
{
comparisonContext.AddOpenApiDifference(
new OpenApiDifference
{
OpenApiDifferenceOperation = OpenApiDifferenceOperation.Update,
SourceValue = source,
TargetValue = target,
OpenApiComparedElementType = typeof(IDictionary<string, T>),
Pointer = comparisonContext.PathString
});

return;
}

var newKeysInTarget = target.Keys.Except(source.Keys).ToList();

foreach (var newKeyInTarget in newKeysInTarget)
{
WalkAndAddOpenApiDifference(
comparisonContext,
newKeyInTarget,
new OpenApiDifference
{
OpenApiDifferenceOperation = OpenApiDifferenceOperation.Add,
TargetValue = target[newKeyInTarget],
OpenApiComparedElementType = typeof(string)
});
Copy link
Contributor

@PerthCharern PerthCharern Oct 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on this http://jsonpatch.com/, this should be

            WalkAndAddOpenApiDifference(
                comparisonContext,
                newKeyInTarget,
                new OpenApiDifference
                {
                    OpenApiDifferenceOperation = OpenApiDifferenceOperation.Add,
                    TargetValue = target[newKeyInTarget],
                    OpenApiComparedElementType = typeof(string)
                }); #Closed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see a dictionary example for json patch , so i am not sure if this is correct, can you point me to a dictionary example that you might have found?


In reply to: 223511856 [](ancestors = 223511856)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C# Dictionary should be treated as a JSON object.

The first example on http://jsonpatch.com/
See the second line:

{ "op": "add", "path": "/hello", "value": ["world"] }

and the third line:

{ "op": "remove", "path": "/foo" }


In reply to: 223857178 [](ancestors = 223857178,223511856)

}

var removedKeysFromSource = source.Keys.Except(target.Keys).ToList();

foreach (var removedKeyFromSource in removedKeysFromSource)
{
WalkAndAddOpenApiDifference(
comparisonContext,
removedKeyFromSource,
new OpenApiDifference
{
OpenApiDifferenceOperation = OpenApiDifferenceOperation.Remove,
SourceValue = source[removedKeyFromSource],
OpenApiComparedElementType = typeof(string)
});
Copy link
Contributor

@PerthCharern PerthCharern Oct 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

            WalkAndAddOpenApiDifference(
                comparisonContext,
                removedKeyFromSource,
                new OpenApiDifference
                {
                    OpenApiDifferenceOperation = OpenApiDifferenceOperation.Remove,
                    SourceValue = source[removedKeyFromSource],
                    OpenApiComparedElementType = typeof(string)
                }); #Closed

}
}

/// <summary>
/// Adds a segment to the context path to enable pointing to the current location in the document.
/// </summary>
Expand Down
17 changes: 16 additions & 1 deletion src/Microsoft.OpenApi/Services/OpenApiComparerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,29 @@ public class OpenApiComparerFactory
{typeof(IDictionary<string, OpenApiParameter>), new OpenApiDictionaryComparer<OpenApiParameter>()},
{typeof(IDictionary<string, OpenApiRequestBody>), new OpenApiDictionaryComparer<OpenApiRequestBody>()},
{typeof(IDictionary<string, OpenApiSchema>), new OpenApiDictionaryComparer<OpenApiSchema>()},
{
typeof(IDictionary<string, OpenApiSecurityScheme>),
new OpenApiDictionaryComparer<OpenApiSecurityScheme>()
},
{typeof(OpenApiHeader), new OpenApiHeaderComparer()},
{typeof(OpenApiRequestBody), new OpenApiRequestBodyComparer()},
{typeof(OpenApiResponse), new OpenApiResponseComparer()},
{typeof(OpenApiComponents), new OpenApiComponentsComparer()},
{typeof(OpenApiEncoding), new OpenApiEncodingComparer()},
{typeof(IList<OpenApiServer>), new OpenApiServersComparer()},
{typeof(OpenApiServer), new OpenApiServerComparer()},
{typeof(OpenApiServerVariable), new OpenApiServerVariableComparer()}
{typeof(OpenApiServerVariable), new OpenApiServerVariableComparer()},
{typeof(OpenApiOAuthFlow), new OpenApiOAuthFlowComparer()},
{typeof(OpenApiOAuthFlows), new OpenApiOAuthFlowsComparer()},
{typeof(OpenApiSecurityRequirement), new OpenApiSecurityRequirementComparer()},
{typeof(OpenApiInfo), new OpenApiInfoComparer()},
{typeof(OpenApiContact), new OpenApiContactComparer()},
{typeof(OpenApiLicense), new OpenApiLicenseComparer()},
{typeof(IList<OpenApiSecurityRequirement>), new OpenApiOrderedListComparer<OpenApiSecurityRequirement>()},
{typeof(IList<OpenApiTag>), new OpenApiOrderedListComparer<OpenApiTag>()},
{typeof(OpenApiExternalDocs), new OpenApiExternalDocsComparer()},
{typeof(OpenApiTag), new OpenApiTagComparer()},
{typeof(OpenApiSecurityScheme), new OpenApiSecuritySchemeComparer()}
};

private readonly Dictionary<Type, object> _typeToComparerMap = new Dictionary<Type, object>();
Expand Down
8 changes: 7 additions & 1 deletion src/Microsoft.OpenApi/Services/OpenApiComponentsComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,14 @@ public override void Compare(
.GetComparer<IDictionary<string, OpenApiHeader>>()
.Compare(sourceComponents.Headers, targetComponents.Headers, comparisonContext));

WalkAndCompare(
comparisonContext,
OpenApiConstants.SecuritySchemes,
() => comparisonContext
.GetComparer<IDictionary<string, OpenApiSecurityScheme>>()
.Compare(sourceComponents.SecuritySchemes, targetComponents.SecuritySchemes, comparisonContext));

// To Do compare Examples
// To Do compare SecuritySchemes
// To Do compare Links
// To Do compare Callbacks
// To Do compare Extensions
Expand Down
54 changes: 54 additions & 0 deletions src/Microsoft.OpenApi/Services/OpenApiContactComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.Models;

namespace Microsoft.OpenApi.Services
{
/// <summary>
/// Defines behavior for comparing properties of <see cref="OpenApiContact"/>.
/// </summary>
public class OpenApiContactComparer : OpenApiComparerBase<OpenApiContact>
{
/// <summary>
/// Executes comparision against source and target <see cref="OpenApiContact"/>.
/// </summary>
/// <param name="sourceContact">The source.</param>
/// <param name="targetContact">The target.</param>
/// <param name="comparisonContext">Context under which to compare the source and target.</param>
public override void Compare(
OpenApiContact sourceContact,
OpenApiContact targetContact,
ComparisonContext comparisonContext)
{
if (sourceContact == null && targetContact == null)
{
return;
}

if (sourceContact == null || targetContact == null)
{
comparisonContext.AddOpenApiDifference(
new OpenApiDifference
{
OpenApiDifferenceOperation = OpenApiDifferenceOperation.Update,
SourceValue = sourceContact,
TargetValue = targetContact,
OpenApiComparedElementType = typeof(OpenApiContact),
Pointer = comparisonContext.PathString
});

return;
}

WalkAndCompare(comparisonContext, OpenApiConstants.Name,
() => Compare(sourceContact.Name, targetContact.Name, comparisonContext));

WalkAndCompare(comparisonContext, OpenApiConstants.Email,
() => Compare(sourceContact.Email, targetContact.Email, comparisonContext));

WalkAndCompare(comparisonContext, OpenApiConstants.Url,
() => Compare(sourceContact.Url, targetContact.Url, comparisonContext));
}
}
}
10 changes: 4 additions & 6 deletions src/Microsoft.OpenApi/Services/OpenApiDictionaryComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@ public override void Compare(
new OpenApiDifference
{
OpenApiDifferenceOperation = OpenApiDifferenceOperation.Add,
TargetValue = new KeyValuePair<string, T>(
newKeyInTarget,
targetFragment[newKeyInTarget]),
OpenApiComparedElementType = typeof(KeyValuePair<string, T>)
TargetValue = targetFragment[newKeyInTarget],
OpenApiComparedElementType = typeof(T)
});
}

Expand All @@ -80,8 +78,8 @@ public override void Compare(
new OpenApiDifference
{
OpenApiDifferenceOperation = OpenApiDifferenceOperation.Remove,
SourceValue = source,
OpenApiComparedElementType = typeof(KeyValuePair<string, T>)
SourceValue = source.Value,
OpenApiComparedElementType = typeof(T)
});
}
}
Expand Down
33 changes: 28 additions & 5 deletions src/Microsoft.OpenApi/Services/OpenApiDocumentComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,34 @@ public override void Compare(
.GetComparer<IList<OpenApiServer>>()
.Compare(sourceDocument.Servers, targetDocument.Servers, comparisonContext));

// To Do Compare Info
// To Do Compare Security Requirements
// To Do Compare Tags
// To Do Compare External Docs
// To Do Compare Extensions
WalkAndCompare(
comparisonContext,
OpenApiConstants.Info,
() => comparisonContext
.GetComparer<OpenApiInfo>()
.Compare(sourceDocument.Info, targetDocument.Info, comparisonContext));

WalkAndCompare(
comparisonContext,
OpenApiConstants.Security,
() => comparisonContext
.GetComparer<IList<OpenApiSecurityRequirement>>()
.Compare(sourceDocument.SecurityRequirements, targetDocument.SecurityRequirements,
comparisonContext));

WalkAndCompare(
comparisonContext,
OpenApiConstants.Tags,
() => comparisonContext
.GetComparer<IList<OpenApiTag>>()
.Compare(sourceDocument.Tags, targetDocument.Tags, comparisonContext));

WalkAndCompare(
comparisonContext,
OpenApiConstants.ExternalDocs,
() => comparisonContext
.GetComparer<OpenApiExternalDocs>()
.Compare(sourceDocument.ExternalDocs, targetDocument.ExternalDocs, comparisonContext));
}
}
}
48 changes: 48 additions & 0 deletions src/Microsoft.OpenApi/Services/OpenApiExternalDocsComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.Models;

namespace Microsoft.OpenApi.Services
{
/// <summary>
/// Defines behavior for comparing properties of <see cref="OpenApiExternalDocs"/>.
/// </summary>
public class OpenApiExternalDocsComparer : OpenApiComparerBase<OpenApiExternalDocs>
{
/// <summary>
/// Executes comparision against source and target <see cref="OpenApiExternalDocs"/>.
/// </summary>
/// <param name="sourceDocs">The source.</param>
/// <param name="targetDocs">The target.</param>
/// <param name="comparisonContext">Context under which to compare the source and target.</param>
public override void Compare(OpenApiExternalDocs sourceDocs, OpenApiExternalDocs targetDocs,
ComparisonContext comparisonContext)
{
if (sourceDocs == null && targetDocs == null)
{
return;
}

if (sourceDocs == null || targetDocs == null)
{
comparisonContext.AddOpenApiDifference(
new OpenApiDifference
{
OpenApiDifferenceOperation = OpenApiDifferenceOperation.Update,
SourceValue = sourceDocs,
TargetValue = targetDocs,
OpenApiComparedElementType = typeof(OpenApiExternalDocs),
Pointer = comparisonContext.PathString
});
return;
}

WalkAndCompare(comparisonContext, OpenApiConstants.Description,
() => Compare(sourceDocs.Description, targetDocs.Description, comparisonContext));

WalkAndCompare(comparisonContext, OpenApiConstants.Url,
() => Compare(sourceDocs.Url, targetDocs.Url, comparisonContext));
}
}
}
Loading