Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring in changes from joschi/openapi-diff #159

Merged
merged 67 commits into from
Aug 27, 2020
Merged
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
7eb3317
Add swagger2 compatibility
quen2404 Jul 25, 2018
b2f7986
build(deps): bump maven-source-plugin from 3.1.0 to 3.2.1
dependabot-preview[bot] Jan 9, 2020
1f86a31
build(deps-dev): bump assertj-core from 3.14.0 to 3.15.0
dependabot-preview[bot] Jan 29, 2020
53b4149
build(deps): bump lombok from 1.18.10 to 1.18.12
dependabot-preview[bot] Feb 7, 2020
da2fd09
build(deps): bump maven-javadoc-plugin from 3.1.1 to 3.2.0
dependabot-preview[bot] Mar 16, 2020
5e27745
build(deps): bump githook-maven-plugin from 1.0.4 to 1.0.5
dependabot-preview[bot] Mar 23, 2020
25bd154
Fix Issue #136 new read-only property breaks PUT
Mar 24, 2020
3314a84
build(deps-dev): bump junit.jupiter.version from 5.5.2 to 5.6.2
dependabot-preview[bot] Apr 13, 2020
da4d555
Merge branch 'pr-128'
joschi Apr 16, 2020
1ba07ff
Merge branch 'pr-131'
joschi Apr 16, 2020
df2812c
Merge branch 'pr-133'
joschi Apr 16, 2020
d596966
Merge branch 'pr-135'
joschi Apr 16, 2020
dd3272b
Merge branch 'pr-141'
joschi Apr 16, 2020
72eaac9
Merge branch 'pr-137'
joschi Apr 16, 2020
7734db0
Adding oapi 2.x compatibility
Mar 16, 2019
8c4ddf7
Merge branch 'pr-54' into pr-70
joschi Apr 16, 2020
03b1646
Format code
joschi Apr 16, 2020
9bb3520
Disable failing Swagger2CompatibilityTest
joschi Apr 16, 2020
c355dca
Clean up POM
joschi Apr 16, 2020
8e837d1
Clean up Lombok usage
joschi Apr 16, 2020
65fa64f
Add wrapper script for Maven 3.6.3
joschi Apr 16, 2020
13951b1
Add GitHub Actions workflow for running tests
joschi Apr 16, 2020
cef8549
Remove Circle CI and Travis CI configuration
joschi Apr 16, 2020
3350900
Refactor output parameters
joschi Apr 16, 2020
f81e67b
Streamline Docker image build
joschi Apr 16, 2020
981c8f2
Add parameter to fail if API changed
joschi Apr 17, 2020
a0f81c9
swagger-parser 2.0.19
sullis May 3, 2020
0818dd5
Merge branch 'pr-156'
joschi May 4, 2020
cd37edf
build(deps-dev): bump assertj-core from 3.14.0 to 3.16.1
dependabot-preview[bot] May 11, 2020
036440f
Fix NPE when response changed from no schema to any schema (#1)
joschi May 11, 2020
0e49ce4
build(deps): bump swagger-parser-v3 from 2.0.17 to 2.0.20
dependabot-preview[bot] May 18, 2020
9453dc9
Merge branch 'pr-151'
joschi Jun 22, 2020
711201a
Merge branch 'pr-148'
joschi Jun 22, 2020
47ec0dc
Create Dependabot config file (#2)
dependabot-preview[bot] Jun 22, 2020
4e6e2b8
build(deps): bump maven-assembly-plugin from 3.2.0 to 3.3.0 (#3)
dependabot-preview[bot] Jun 22, 2020
0fffe53
Add Quentin Desramé to Thanks section in README.md
joschi Jun 22, 2020
be72782
Replace CircleCI badge with GitHub Actions badge
joschi Jun 22, 2020
8fccce8
Update Docker image in README.md
joschi Jun 22, 2020
a3e5789
Upgrae to fmt-maven-plugin 2.9.1
joschi Jun 22, 2020
842ea3c
Change SCM and group ID in POM
joschi Jun 22, 2020
9ec0290
Split openapi-diff into core and CLI modules (#5)
joschi Jun 22, 2020
7df69df
Streamline Docker image build process
joschi Jun 22, 2020
c55cb82
[maven-release-plugin] prepare release 2.0.0-beta.1
joschi Jun 23, 2020
3c6f9af
[maven-release-plugin] prepare for next development iteration
joschi Jun 23, 2020
d348630
Fix exception in ConsoleRender when property has been removed (#7)
joschi Jun 24, 2020
b86a0f9
Use HTTPS for SCM connections
joschi Jun 24, 2020
129937f
Add developer to POM
joschi Jun 24, 2020
de2b659
Restore version on maven-gpg-plugin in profile
joschi Jun 24, 2020
a4016b1
Add maven-deploy-plugin to pluginManagement
joschi Jun 24, 2020
3d3950f
[maven-release-plugin] prepare release 2.0.0-beta.2
joschi Jun 24, 2020
573fa4f
[maven-release-plugin] prepare for next development iteration
joschi Jun 24, 2020
0aaa1c2
Fix exceptions in HTML and Markdown renderers with removed property (#8)
joschi Jun 24, 2020
47b12b1
Fix NPE when description is empty
jlamaille Jul 6, 2020
e735f78
Clean imports
jlamaille Jul 6, 2020
0d8662f
Merge branch 'pr-155'
joschi Jul 13, 2020
3543fa5
[maven-release-plugin] prepare release 2.0.0-beta.3
joschi Jul 13, 2020
e406351
[maven-release-plugin] prepare for next development iteration
joschi Jul 13, 2020
320ddca
build(deps): bump commons-lang3 from 3.10 to 3.11 (#9)
dependabot[bot] Jul 21, 2020
074f882
build(deps): bump swagger-parser.version from 2.0.20 to 2.0.21 (#10)
dependabot[bot] Aug 11, 2020
793b393
[maven-release-plugin] prepare release 2.0.0-beta.4
joschi Aug 13, 2020
e4a9b11
[maven-release-plugin] prepare for next development iteration
joschi Aug 13, 2020
35fe0c7
Update README.md
joschi Aug 13, 2020
a6b076e
Use Maven profile "release" for releases
joschi Aug 13, 2020
5fe3a91
Allow optional discriminator
dang-gyg Aug 18, 2020
4f10108
Format source code
joschi Aug 18, 2020
726740a
Merge branch 'dang-gyg-optional-discriminator-29' into master
joschi Aug 18, 2020
c3ebfd9
Revert "Remove Circle CI configuration"
joschi Aug 27, 2020
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
16 changes: 11 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -14,17 +14,23 @@ jobs:
- restore_cache:
key: openapi-diff-{{ checksum "pom.xml" }}

- run: mvn dependency:go-offline
- run: ./mvnw package -X

- save_cache:
paths:
- ~/.m2
key: openapi-diff-{{ checksum "pom.xml" }}

- run: mvn package -X

- run:
name: Save test results
command: |
mkdir -p ~/test-results/junit/
find . -type f -regex ".*/target/surefire-reports/.*xml" -exec cp {} ~/test-results/junit/ \;
when: always
- store_test_results:
path: target/surefire-reports
path: ~/test-results

- store_artifacts:
path: target/openapi-diff-*-SNAPSHOT.jar
path: core/target/openapi-diff-*-SNAPSHOT.jar
- store_artifacts:
path: cli/target/openapi-diff-*-SNAPSHOT.jar
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: maven
directory: "/"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
33 changes: 33 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Test
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
runs-on: 'ubuntu-latest'
strategy:
fail-fast: false
matrix:
java_version: ['8', '11', '14']
env:
JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
steps:
- uses: actions/checkout@v2
- name: Set up JDK
uses: joschi/setup-jdk@v1
with:
java-version: ${{ matrix.java_version }}
- uses: actions/cache@v1
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Build with Maven
run: ./mvnw -V -B -ff install '-DskipTests=true' '-Dmaven.javadoc.skip=true'
- name: Run tests
run: ./mvnw -V -B -ff verify
Binary file added .mvn/wrapper/maven-wrapper.jar
Binary file not shown.
1 change: 1 addition & 0 deletions .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 changes: 0 additions & 2 deletions .travis.yml

This file was deleted.

18 changes: 5 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
FROM maven:3.5-jdk-8-alpine as build
WORKDIR /app
COPY ./ /app
RUN mvn install -q && \
mvn package -q && \
ls /app/target/ && \
MVN_VERSION=$(mvn -q \
-Dexec.executable="echo" \
-Dexec.args='${project.version}' \
--non-recursive \
org.codehaus.mojo:exec-maven-plugin:1.6.0:exec) && \
mv /app/target/openapi-diff-${MVN_VERSION}-jar-with-dependencies.jar /app/openapi-diff.jar
FROM openjdk:8-jdk-alpine AS build
WORKDIR /build
COPY ./ /build
RUN ./mvnw -V -B -ff -P docker package -q

FROM openjdk:8-jre-alpine
WORKDIR /app
COPY --from=0 /app/openapi-diff.jar /app
COPY --from=build /build/cli/target/openapi-diff-jar-with-dependencies.jar /app/openapi-diff.jar
ENTRYPOINT ["java", "-jar", "/app/openapi-diff.jar"]
CMD ["--help"]
78 changes: 57 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,63 @@
# OpenAPI-diff

Compare two OpenAPI specifications(3.x) and render the difference to html file or markdown file.
Compare two OpenAPI specifications (3.x) and render the difference to HTML plaintext, or Markdown files.

[![CircleCI](https://circleci.com/gh/quen2404/openapi-diff/tree/master.svg?style=svg)](https://circleci.com/gh/quen2404/openapi-diff/tree/master)
[![Test](https://github.com/joschi/openapi-diff/workflows/Test/badge.svg)](https://github.com/joschi/openapi-diff/actions?query=branch%3Amaster+workflow%3ATest+)

# Requirements
`jdk1.8+`

* Java 8

# Feature
* Supports OpenAPi spec v3.0.
* Depth comparison of parameters, responses, endpoint, http method(GET,POST,PUT,DELETE...)

* Supports OpenAPI spec v3.0.
* Depth comparison of parameters, responses, endpoint, http method (GET,POST,PUT,DELETE...)
* Supports swagger api Authorization
* Render difference of property with Expression Language
* html & markdown render
* HTML & Markdown render

# Maven

Available on [Maven Central](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.qdesrame%22%20AND%20a%3A%22openapi-diff%22)
Available on [Maven Central](https://search.maven.org/artifact/com.github.joschi.openapi-diff/core)

```xml
<dependency>
<groupId>com.qdesrame</groupId>
<artifactId>openapi-diff</artifactId>
<version>1.2.0</version>
<groupId>com.github.joschi.openapi-diff</groupId>
<artifactId>core</artifactId>
<version>${openapi-diff-version}</version>
</dependency>
```

# Docker

Available on [Docker Hub](https://hub.docker.com/r/quen2404/openapi-diff/) as `quen2404/openapi-diff`.
Available on [Docker Hub](https://hub.docker.com/r/joschi/openapi-diff/) as `joschi/openapi-diff`.

```bash
# docker run joschi/openapi-diff:latest
usage: openapi-diff <old> <new>
--debug Print debugging information
--error Print error information
--fail-on-changed Fail if API changed but is backward
compatible
--fail-on-incompatible Fail only if API changes broke backward
compatibility
-h,--help print this message
--header <property=value> use given header for authorisation
--html <file> export diff as html in given file
--info Print additional information
-l,--log <level> use given level for log (TRACE, DEBUG,
INFO, WARN, ERROR, OFF). Default: ERROR
--markdown <file> export diff as markdown in given file
--off No information printed
--query <property=value> use query param for authorisation
--state Only output diff state: no_changes,
incompatible, compatible
--text <file> export diff as text in given file
--trace be extra verbose
--version print the version information and exit
--warn Print warning information
```
## Build the image
@@ -42,19 +71,20 @@ You can replace the local image name `local-openapi-diff` by any name of your ch
## Run an instance
In this example the `$(pwd)/src/test/resources` directory is mounted in the `/specs` directory of the container
In this example the `$(pwd)/core/src/test/resources` directory is mounted in the `/specs` directory of the container
in readonly mode (`ro`).
```bash
docker run -t \
-v $(pwd)/src/test/resources:/specs:ro \
quen2404/openapi-diff /specs/path_1.yaml /specs/path_2.yaml
-v $(pwd)/core/src/test/resources:/specs:ro \
joschi/openapi-diff /specs/path_1.yaml /specs/path_2.yaml
```
The remote name `quen2404/openapi-diff` can be replaced with `local-openapi-diff` or the name you gave to your local image.
The remote name `joschi/openapi-diff` can be replaced with `local-openapi-diff` or the name you gave to your local image.
# Usage
OpenDiff can read swagger api spec from json file or http.
openapi-diff can read OpenAPI specs from JSON files or HTTP URLs.
## Command Line
@@ -70,13 +100,12 @@ usage: openapi-diff <old> <new>
-l,--log <level> use given level for log (TRACE, DEBUG,
INFO, WARN, ERROR, OFF). Default: ERROR
--markdown <file> export diff as markdown in given file
-o,--output <format=file> use given format (html, markdown) for
output in file
--off No information printed
--query <property=value> use query param for authorisation
--state Only output diff state: no_changes,
incompatible, compatible
--fail-on-incompatible Fail only if API changes broke backward compatibility
--fail-on-changed Fail if API changed but is backward compatible
--trace be extra verbose
--version print the version information and exit
--warn Print warning information
@@ -100,6 +129,7 @@ public class Main {
### Render difference
---
#### HTML
```java
String html = new HtmlRender("Changelog",
"http://deepoove.com/swagger-diff/stylesheets/demo.css")
@@ -117,6 +147,7 @@ try {
```
#### Markdown
```java
String render = new MarkdownRender().render(diff);
try {
@@ -131,11 +162,13 @@ try {
```
### Extensions
This project uses Java Service Provider Inteface (SPI) so additional extensions can be added.
To build your own extension, you simply need to create a `src/main/resources/META-INF/services/com.qdesrame.openapi.diff.compare.ExtensionDiff` file with the full classname of your implementation. Your class must also implement the `com.qdesrame.openapi.diff.compare.ExtensionDiff` interface. Then, including your library with the `openapi-diff` module will cause it to be triggered automatically.
To build your own extension, you simply need to create a `src/main/resources/META-INF/services/com.qdesrame.openapi.diff.core.compare.ExtensionDiff` file with the full classname of your implementation. Your class must also implement the `com.qdesrame.openapi.diff.core.compare.ExtensionDiff` interface. Then, including your library with the `openapi-diff` module will cause it to be triggered automatically.
# Examples
# Example
### CLI Output
```text
@@ -234,6 +267,7 @@ To build your own extension, you simply need to create a `src/main/resources/MET
```
### Markdown
```markdown
### What's New
---
@@ -308,10 +342,12 @@ To build your own extension, you simply need to create a `src/main/resources/MET
```
# License
openapi-diff is released under the Apache License 2.0.
# Thanks
* Adarsh Sharma / [adarshsharma](https://github.com/adarshsharma)
* Adarsh Sharma / [adarshsharma](https://github.com/adarshsharma)
* Quentin Desramé / [quen2404](https://github.com/quen2404)
* [Sayi](https://github.com/Sayi) for his project [swagger-diff](https://github.com/Sayi/swagger-diff)
which was a source of inspiration for this tool
67 changes: 67 additions & 0 deletions cli/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.github.joschi.openapi-diff</groupId>
<artifactId>parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>

<artifactId>cli</artifactId>
<packaging>jar</packaging>

<name>openapi-diff-cli</name>
<description>CLI for openapi-diff</description>

<dependencies>
<dependency>
<groupId>com.github.joschi.openapi-diff</groupId>
<artifactId>core</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.qdesrame.openapi.diff.cli.Main</mainClass>
</manifest>
</archive>
<finalName>openapi-diff</finalName>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package com.qdesrame.openapi.diff;
package com.qdesrame.openapi.diff.cli;

import com.qdesrame.openapi.diff.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.output.ConsoleRender;
import com.qdesrame.openapi.diff.output.HtmlRender;
import com.qdesrame.openapi.diff.output.MarkdownRender;
import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.output.ConsoleRender;
import com.qdesrame.openapi.diff.core.output.HtmlRender;
import com.qdesrame.openapi.diff.core.output.MarkdownRender;
import java.io.File;
import java.io.IOException;
import org.apache.commons.cli.*;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Level;
@@ -33,6 +40,11 @@ public static void main(String... args) {
.longOpt("fail-on-incompatible")
.desc("Fail only if API changes broke backward compatibility")
.build());
options.addOption(
Option.builder()
.longOpt("fail-on-changed")
.desc("Fail if API changed but is backward compatible")
.build());
options.addOption(Option.builder().longOpt("trace").desc("be extra verbose").build());
options.addOption(
Option.builder().longOpt("debug").desc("Print debugging information").build());
@@ -66,15 +78,6 @@ public static void main(String... args) {
.argName("property=value")
.desc("use query param for authorisation")
.build());
options.addOption(
Option.builder("o")
.longOpt("output")
.hasArgs()
.numberOfArgs(2)
.valueSeparator()
.argName("format=file")
.desc("use given format (html, markdown) for output in file")
.build());
options.addOption(
Option.builder()
.longOpt("markdown")
@@ -89,6 +92,13 @@ public static void main(String... args) {
.argName("file")
.desc("export diff as html in given file")
.build());
options.addOption(
Option.builder()
.longOpt("text")
.hasArg()
.argName("file")
.desc("export diff as text in given file")
.build());

final String message = "Hello logging!";
// create the parser
@@ -148,45 +158,29 @@ public static void main(String... args) {
if (!logLevel.equals("OFF")) {
System.out.println(consoleRender.render(result));
}
HtmlRender htmlRender = new HtmlRender();
MarkdownRender mdRender = new MarkdownRender();
String output = null;
String outputFile = null;
if (line.hasOption("html")) {
output = htmlRender.render(result);
outputFile = line.getOptionValue("html");
HtmlRender htmlRender = new HtmlRender();
String output = htmlRender.render(result);
String outputFile = line.getOptionValue("html");
writeOutput(output, outputFile);
}
if (line.hasOption("markdown")) {
output = mdRender.render(result);
outputFile = line.getOptionValue("markdown");
MarkdownRender mdRender = new MarkdownRender();
String output = mdRender.render(result);
String outputFile = line.getOptionValue("markdown");
writeOutput(output, outputFile);
}
if (line.hasOption("output")) {
String[] outputValues = line.getOptionValues("output");
if (outputValues[0].equalsIgnoreCase("markdown")) {
output = mdRender.render(result);
} else if (outputValues[0].equalsIgnoreCase("html")) {
output = htmlRender.render(result);
} else {
throw new ParseException("Invalid output format");
}
outputFile = outputValues[1];
}
if (output != null && outputFile != null) {
File file = new File(outputFile);
logger.debug("Output file: {}", file.getAbsolutePath());
try {
FileUtils.writeStringToFile(file, output);
} catch (IOException e) {
logger.error("Impossible to write output to file {}", outputFile, e);
System.exit(2);
}
if (line.hasOption("text")) {
String output = consoleRender.render(result);
String outputFile = line.getOptionValue("text");
writeOutput(output, outputFile);
}
if (line.hasOption("state")) {
System.out.println(result.isChanged().getValue());
System.exit(0);
} else if (line.hasOption("fail-on-incompatible")) {
System.exit(result.isCompatible() ? 0 : 1);
} else {
} else if (line.hasOption("fail-on-changed")) {
System.exit(result.isUnchanged() ? 0 : 1);
}
} catch (ParseException e) {
@@ -204,6 +198,17 @@ public static void main(String... args) {
}
}

private static void writeOutput(String output, String outputFile) {
File file = new File(outputFile);
logger.debug("Output file: {}", file.getAbsolutePath());
try {
FileUtils.writeStringToFile(file, output);
} catch (IOException e) {
logger.error("Impossible to write output to file {}", outputFile, e);
System.exit(2);
}
}

public static void printHelp(Options options) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("openapi-diff <old> <new>", options);
File renamed without changes.
66 changes: 66 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.github.joschi.openapi-diff</groupId>
<artifactId>parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>

<artifactId>core</artifactId>
<packaging>jar</packaging>

<name>openapi-diff-core</name>
<description>Library for comparing two OpenAPI specifications.</description>

<dependencies>
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser-v3</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser-v2-converter</artifactId>
</dependency>
<dependency>
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package com.qdesrame.openapi.diff;
package com.qdesrame.openapi.diff.core;

import com.qdesrame.openapi.diff.compare.OpenApiDiff;
import com.qdesrame.openapi.diff.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.compare.OpenApiDiff;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.OpenAPIV3Parser;
import io.swagger.v3.parser.core.models.AuthorizationValue;
import io.swagger.v3.parser.core.models.ParseOptions;
import java.io.File;
import java.util.List;

public class OpenApiCompare {

private static OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
private static OpenAPIParser openApiParser = new OpenAPIParser();
private static ParseOptions options = new ParseOptions();

static {
@@ -113,6 +113,6 @@ private static OpenAPI readContent(String content, List<AuthorizationValue> auth
}

private static OpenAPI readLocation(String location, List<AuthorizationValue> auths) {
return openApiParser.read(location, auths, options);
return openApiParser.readLocation(location, auths, options).getOpenAPI();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedApiResponse;
import com.qdesrame.openapi.diff.model.ChangedResponse;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.ChangedApiResponse;
import com.qdesrame.openapi.diff.core.model.ChangedResponse;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import java.util.LinkedHashMap;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.qdesrame.openapi.diff.core.compare;

import com.qdesrame.openapi.diff.core.model.DiffContext;
import lombok.Value;

@Value
public class CacheKey {

String left;
String right;
DiffContext context;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

public interface Comparable<T> {

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.utils.ChangedUtils.isUnchanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isUnchanged;

import com.qdesrame.openapi.diff.model.ChangedContent;
import com.qdesrame.openapi.diff.model.ChangedMediaType;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.ChangedContent;
import com.qdesrame.openapi.diff.core.model.ChangedMediaType;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.MediaType;
import java.util.*;
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import com.qdesrame.openapi.diff.model.Change;
import com.qdesrame.openapi.diff.model.Changed;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.Change;
import com.qdesrame.openapi.diff.core.model.Changed;
import com.qdesrame.openapi.diff.core.model.DiffContext;

public interface ExtensionDiff {

Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.utils.Copy.copyMap;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.Copy.copyMap;

import com.qdesrame.openapi.diff.model.Change;
import com.qdesrame.openapi.diff.model.Changed;
import com.qdesrame.openapi.diff.model.ChangedExtensions;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.Change;
import com.qdesrame.openapi.diff.core.model.Changed;
import com.qdesrame.openapi.diff.core.model.ChangedExtensions;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import java.util.*;
import java.util.function.Function;

@@ -29,9 +29,7 @@ public boolean isParentApplicable(
if (extensions.size() == 0) {
return true;
}
return extensions
.entrySet()
.stream()
return extensions.entrySet().stream()
.map(
entry ->
executeExtension(
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedHeader;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.model.ChangedHeader;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.headers.Header;
import java.util.HashSet;
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedHeader;
import com.qdesrame.openapi.diff.model.ChangedHeaders;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.ChangedHeader;
import com.qdesrame.openapi.diff.core.model.ChangedHeaders;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.headers.Header;
import java.util.LinkedHashMap;
import java.util.List;
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import com.qdesrame.openapi.diff.model.ChangedList;
import lombok.Getter;
import com.qdesrame.openapi.diff.core.model.ChangedList;

@Getter
public class ListDiff {

public static <K extends ChangedList<X>, X> K diff(K instance) {
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import java.util.ArrayList;
import java.util.LinkedHashMap;
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedMetadata;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.ChangedMetadata;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.Components;
import java.util.Optional;

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;
import static java.util.Optional.ofNullable;

import com.qdesrame.openapi.diff.model.ChangedOAuthFlow;
import com.qdesrame.openapi.diff.core.model.ChangedOAuthFlow;
import io.swagger.v3.oas.models.security.OAuthFlow;
import java.util.Map;
import java.util.Objects;
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;
import static java.util.Optional.ofNullable;

import com.qdesrame.openapi.diff.model.ChangedOAuthFlows;
import com.qdesrame.openapi.diff.core.model.ChangedOAuthFlows;
import io.swagger.v3.oas.models.security.OAuthFlows;
import java.util.Map;
import java.util.Optional;
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.compare.PathsDiff.valOrEmpty;
import static com.qdesrame.openapi.diff.core.compare.PathsDiff.valOrEmpty;

import com.qdesrame.openapi.diff.model.*;
import com.qdesrame.openapi.diff.model.ChangedExtensions;
import com.qdesrame.openapi.diff.utils.EndpointUtils;
import com.qdesrame.openapi.diff.core.model.ChangedExtensions;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.model.ChangedOperation;
import com.qdesrame.openapi.diff.core.model.ChangedPath;
import com.qdesrame.openapi.diff.core.model.ChangedPaths;
import com.qdesrame.openapi.diff.core.model.Endpoint;
import com.qdesrame.openapi.diff.core.utils.EndpointUtils;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.security.SecurityRequirement;
@@ -22,7 +26,7 @@ public class OpenApiDiff {

public static final String SWAGGER_VERSION_V2 = "2.0";

private static Logger logger = LoggerFactory.getLogger(OpenApiDiff.class);
private static final Logger logger = LoggerFactory.getLogger(OpenApiDiff.class);

private PathsDiff pathsDiff;
private PathDiff pathDiff;
@@ -44,8 +48,8 @@ public class OpenApiDiff {
private ExtensionsDiff extensionsDiff;
private MetadataDiff metadataDiff;

private OpenAPI oldSpecOpenApi;
private OpenAPI newSpecOpenApi;
private final OpenAPI oldSpecOpenApi;
private final OpenAPI newSpecOpenApi;
private List<Endpoint> newEndpoints;
private List<Endpoint> missingEndpoints;
private List<ChangedOperation> changedOperations;
@@ -138,27 +142,19 @@ private void preProcess(OpenAPI openApi) {
.values()
.forEach(
pathItem ->
pathItem
.readOperationsMap()
.values()
.stream()
pathItem.readOperationsMap().values().stream()
.filter(operation -> operation.getSecurity() != null)
.forEach(
operation ->
operation.setSecurity(
operation
.getSecurity()
.stream()
operation.getSecurity().stream()
.distinct()
.collect(Collectors.toList()))));
paths
.values()
.forEach(
pathItem ->
pathItem
.readOperationsMap()
.values()
.stream()
pathItem.readOperationsMap().values().stream()
.filter(operation -> operation.getSecurity() == null)
.forEach(operation -> operation.setSecurity(distinctSecurityRequirements)));
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedOperation;
import com.qdesrame.openapi.diff.model.ChangedParameters;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.ChangedOperation;
import com.qdesrame.openapi.diff.core.model.ChangedParameters;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.parameters.Parameter;
import java.util.List;
@@ -84,8 +84,7 @@ public void removePathParameters(Map<String, String> pathParameters, ChangedPara
}

public void removePathParameter(String name, List<Parameter> parameters) {
parameters
.stream()
parameters.stream()
.filter(p -> "path".equals(p.getIn()) && name.equals(p.getName()))
.findFirst()
.ifPresent(parameters::remove);
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedParameter;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.model.ChangedParameter;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.parameters.Parameter;
import java.util.HashSet;
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedParameters;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.model.ChangedParameters;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.parameters.Parameter;
import java.util.ArrayList;
@@ -39,8 +39,7 @@ public ParametersDiff(OpenApiDiff openApiDiff) {

public static Optional<Parameter> contains(
Components components, List<Parameter> parameters, Parameter parameter) {
return parameters
.stream()
return parameters.stream()
.filter(param -> same(refPointer.resolveRef(components, param, param.get$ref()), parameter))
.findFirst();
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedPath;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.ChangedPath;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import java.util.List;
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedPaths;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.ChangedPaths;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
import java.util.*;
@@ -42,9 +42,7 @@ public Optional<ChangedPaths> diff(
PathItem leftPath = left.get(url);
String template = normalizePath(url);
Optional<String> result =
right
.keySet()
.stream()
right.keySet().stream()
.filter(s -> normalizePath(s).equals(template))
.findFirst();
if (result.isPresent()) {
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;
import static java.util.Optional.ofNullable;

import com.qdesrame.openapi.diff.model.ChangedRequestBody;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.model.ChangedRequestBody;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.parameters.RequestBody;
import java.util.HashSet;
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedResponse;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.model.ChangedResponse;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.responses.ApiResponse;
import java.util.HashSet;
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static java.util.Optional.ofNullable;

import com.qdesrame.openapi.diff.compare.schemadiffresult.ArraySchemaDiffResult;
import com.qdesrame.openapi.diff.compare.schemadiffresult.ComposedSchemaDiffResult;
import com.qdesrame.openapi.diff.compare.schemadiffresult.SchemaDiffResult;
import com.qdesrame.openapi.diff.model.ChangedSchema;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.compare.schemadiffresult.ArraySchemaDiffResult;
import com.qdesrame.openapi.diff.core.compare.schemadiffresult.ComposedSchemaDiffResult;
import com.qdesrame.openapi.diff.core.compare.schemadiffresult.SchemaDiffResult;
import com.qdesrame.openapi.diff.core.model.ChangedSchema;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.media.ArraySchema;
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import com.qdesrame.openapi.diff.model.ChangedList;
import com.qdesrame.openapi.diff.core.model.ChangedList;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import java.util.List;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;

/** Created by adarsh.sharma on 11/01/18. */
@Getter
@Setter
@Data
@AllArgsConstructor
public class SecurityDiffInfo {

private String ref;
private SecurityScheme securityScheme;
private List<String> scopes;
@@ -30,8 +28,7 @@ public static SecurityRequirement getSecurityRequirement(

public static Optional<List<SecurityDiffInfo>> containsList(
List<List<SecurityDiffInfo>> securityRequirements, List<SecurityDiffInfo> leftSecurities) {
return securityRequirements
.stream()
return securityRequirements.stream()
.filter(rightSecurities -> sameList(leftSecurities, rightSecurities))
.findFirst();
}
@@ -44,14 +41,20 @@ public static boolean sameList(

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

SecurityDiffInfo that = (SecurityDiffInfo) o;

if (securityScheme != null
? !securityScheme.equals(that.securityScheme)
: that.securityScheme != null) return false;
: that.securityScheme != null) {
return false;
}
return scopes != null ? scopes.equals(that.scopes) : that.scopes == null;
}

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedSecurityRequirement;
import com.qdesrame.openapi.diff.model.ChangedSecurityScheme;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.ChangedSecurityRequirement;
import com.qdesrame.openapi.diff.core.model.ChangedSecurityScheme;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
@@ -30,9 +30,7 @@ public SecurityRequirementDiff(OpenApiDiff openApiDiff) {

public static SecurityRequirement getCopy(LinkedHashMap<String, List<String>> right) {
SecurityRequirement newSecurityRequirement = new SecurityRequirement();
right
.entrySet()
.stream()
right.entrySet().stream()
.forEach(e -> newSecurityRequirement.put(e.getKey(), new ArrayList<>(e.getValue())));
return newSecurityRequirement;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedSecurityRequirement;
import com.qdesrame.openapi.diff.model.ChangedSecurityRequirements;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.model.ChangedSecurityRequirement;
import com.qdesrame.openapi.diff.core.model.ChangedSecurityRequirements;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
@@ -39,8 +39,7 @@ public SecurityRequirementsDiff(OpenApiDiff openApiDiff) {

public Optional<SecurityRequirement> contains(
List<SecurityRequirement> securityRequirements, SecurityRequirement left) {
return securityRequirements
.stream()
return securityRequirements.stream()
.filter(rightSecurities -> same(left, rightSecurities))
.findFirst();
}
@@ -63,9 +62,7 @@ public boolean same(SecurityRequirement left, SecurityRequirement right) {

private List<Pair<SecurityScheme.Type, SecurityScheme.In>> getListOfSecuritySchemes(
Components components, SecurityRequirement securityRequirement) {
return securityRequirement
.keySet()
.stream()
return securityRequirement.keySet().stream()
.map(
x -> {
SecurityScheme result = components.getSecuritySchemes().get(x);
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.qdesrame.openapi.diff.compare;
package com.qdesrame.openapi.diff.core.compare;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;

import com.qdesrame.openapi.diff.model.ChangedSecurityScheme;
import com.qdesrame.openapi.diff.model.ChangedSecuritySchemeScopes;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.ChangedSecurityScheme;
import com.qdesrame.openapi.diff.core.model.ChangedSecuritySchemeScopes;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.security.SecurityScheme;
import java.util.HashSet;
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.qdesrame.openapi.diff.compare.schemadiffresult;
package com.qdesrame.openapi.diff.core.compare.schemadiffresult;

import com.qdesrame.openapi.diff.compare.OpenApiDiff;
import com.qdesrame.openapi.diff.model.ChangedSchema;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.core.compare.OpenApiDiff;
import com.qdesrame.openapi.diff.core.model.ChangedSchema;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.qdesrame.openapi.diff.compare.schemadiffresult;
package com.qdesrame.openapi.diff.core.compare.schemadiffresult;

import com.qdesrame.openapi.diff.compare.MapKeyDiff;
import com.qdesrame.openapi.diff.compare.OpenApiDiff;
import com.qdesrame.openapi.diff.model.ChangedOneOfSchema;
import com.qdesrame.openapi.diff.model.ChangedSchema;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.compare.MapKeyDiff;
import com.qdesrame.openapi.diff.core.compare.OpenApiDiff;
import com.qdesrame.openapi.diff.core.model.ChangedOneOfSchema;
import com.qdesrame.openapi.diff.core.model.ChangedSchema;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Discriminator;
@@ -42,15 +42,15 @@ public <T extends Schema<X>, X> Optional<ChangedSchema> diff(

Discriminator leftDis = leftComposedSchema.getDiscriminator();
Discriminator rightDis = rightComposedSchema.getDiscriminator();
if (leftDis == null
|| rightDis == null
|| leftDis.getPropertyName() == null
|| rightDis.getPropertyName() == null) {
throw new IllegalArgumentException(
"discriminator or property not found for oneOf schema");
} else if (!leftDis.getPropertyName().equals(rightDis.getPropertyName())
|| (CollectionUtils.isEmpty(leftComposedSchema.getOneOf())
|| CollectionUtils.isEmpty(rightComposedSchema.getOneOf()))) {
if ((leftDis == null && rightDis != null)
|| (leftDis != null && rightDis == null)
|| (leftDis != null
&& rightDis != null
&& ((leftDis.getPropertyName() == null && rightDis.getPropertyName() != null)
|| (leftDis.getPropertyName() != null && rightDis.getPropertyName() == null)
|| (leftDis.getPropertyName() != null
&& rightDis.getPropertyName() != null
&& !leftDis.getPropertyName().equals(rightDis.getPropertyName()))))) {
changedSchema.setOldSchema(left);
changedSchema.setNewSchema(right);
changedSchema.setDiscriminatorPropertyChanged(true);
@@ -109,15 +109,14 @@ private Map<String, String> getMapping(ComposedSchema composedSchema) {
reverseMapping.put(ref, schemaName);
}

if (composedSchema.getDiscriminator().getMapping() != null) {
if (composedSchema.getDiscriminator() != null
&& composedSchema.getDiscriminator().getMapping() != null) {
for (String ref : composedSchema.getDiscriminator().getMapping().keySet()) {
reverseMapping.put(composedSchema.getDiscriminator().getMapping().get(ref), ref);
}
}

return reverseMapping
.entrySet()
.stream()
return reverseMapping.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.qdesrame.openapi.diff.compare.schemadiffresult;
package com.qdesrame.openapi.diff.core.compare.schemadiffresult;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isChanged;
import static java.util.Optional.ofNullable;

import com.qdesrame.openapi.diff.compare.ListDiff;
import com.qdesrame.openapi.diff.compare.MapKeyDiff;
import com.qdesrame.openapi.diff.compare.OpenApiDiff;
import com.qdesrame.openapi.diff.model.Change;
import com.qdesrame.openapi.diff.model.ChangedSchema;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.model.schema.*;
import com.qdesrame.openapi.diff.core.compare.ListDiff;
import com.qdesrame.openapi.diff.core.compare.MapKeyDiff;
import com.qdesrame.openapi.diff.core.compare.OpenApiDiff;
import com.qdesrame.openapi.diff.core.model.Change;
import com.qdesrame.openapi.diff.core.model.ChangedSchema;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.schema.*;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.media.Schema;
import java.util.*;
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import lombok.Getter;
import lombok.Value;

@Getter
@Value
public class Change<T> {
private final T oldValue;
private final T newValue;
private final Type type;

private Change(T oldValue, T newValue, Type type) {
this.oldValue = oldValue;
this.newValue = newValue;
this.type = type;
}
T oldValue;
T newValue;
Type type;

public static <T> Change<T> changed(T oldValue, T newValue) {
return new Change<>(oldValue, newValue, Type.CHANGED);
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import java.util.Optional;

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
@@ -7,15 +7,13 @@
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 22/12/17. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedApiResponse implements ComposedChanged {

private final ApiResponses oldApiResponses;
private final ApiResponses newApiResponses;
private final DiffContext context;
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.MediaType;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 22/12/17. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedContent implements ComposedChanged {

private final Content oldContent;
private final Content newContent;
private final DiffContext context;
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.Data;

@Getter
@Setter
@Accessors
@Data
public class ChangedExtensions implements ComposedChanged {

private final Map<String, Object> oldExtensions;
private final Map<String, Object> newExtensions;
private final DiffContext context;
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.headers.Header;
import java.util.Arrays;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 28/12/17. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedHeader implements ComposedChanged {

private final Header oldHeader;
private final Header newHeader;
private final DiffContext context;
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.headers.Header;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 28/12/17. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedHeaders implements ComposedChanged {

private final Map<String, Header> oldHeaders;
private final Map<String, Header> newHeaders;
private final DiffContext context;
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

@Getter
@Setter
@Data
@Accessors(chain = true)
public abstract class ChangedList<T> implements Changed {

protected DiffContext context;
protected List<T> oldValue;
protected List<T> newValue;
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.media.Schema;
import java.util.Collections;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedMediaType implements ComposedChanged {

private final Schema oldSchema;
private final Schema newSchema;
private final DiffContext context;
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import java.util.Objects;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedMetadata implements Changed {

Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.security.OAuthFlow;
import java.util.Collections;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 12/01/18. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedOAuthFlow implements ComposedChanged {

private OAuthFlow oldOAuthFlow;
private OAuthFlow newOAuthFlow;

Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.security.OAuthFlows;
import java.util.Arrays;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 12/01/18. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedOAuthFlows implements ComposedChanged {

private final OAuthFlows oldOAuthFlows;
private final OAuthFlows newOAuthFlows;

Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.media.Schema;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 22/12/17. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedOneOfSchema implements ComposedChanged {

private final Map<String, String> oldMapping;
private final Map<String, String> newMapping;
private final DiffContext context;
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import com.qdesrame.openapi.diff.utils.EndpointUtils;
import com.qdesrame.openapi.diff.core.utils.EndpointUtils;
import io.swagger.v3.oas.models.OpenAPI;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 22/12/17. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedOpenApi implements ComposedChanged {

private OpenAPI oldSpecOpenApi;
private OpenAPI newSpecOpenApi;

@@ -23,8 +21,7 @@ public class ChangedOpenApi implements ComposedChanged {
private ChangedExtensions changedExtensions;

public List<Endpoint> getDeprecatedEndpoints() {
return changedOperations
.stream()
return changedOperations.stream()
.filter(ChangedOperation::isDeprecated)
.map(
c ->
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import static com.qdesrame.openapi.diff.model.Changed.result;
import static com.qdesrame.openapi.diff.core.model.Changed.result;

import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import java.util.Arrays;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedOperation implements ComposedChanged {

private Operation oldOperation;
private Operation newOperation;

Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.parameters.Parameter;
import java.util.Arrays;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedParameter implements ComposedChanged {

private final DiffContext context;
private Parameter oldParameter;
private Parameter newParameter;
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.parameters.Parameter;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedParameters implements ComposedChanged {
private final List<Parameter> oldParameterList;
@@ -39,7 +37,12 @@ public DiffResult isCoreChanged() {
if (increased.isEmpty() && missing.isEmpty()) {
return DiffResult.NO_CHANGES;
}
if (increased.stream().noneMatch(Parameter::getRequired) && missing.isEmpty()) {
if (increased.stream()
.noneMatch(
p -> {
return p.getRequired() != null && p.getRequired();
})
&& missing.isEmpty()) {
return DiffResult.COMPATIBLE;
}
return DiffResult.INCOMPATIBLE;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
@@ -8,14 +8,13 @@
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedPath implements ComposedChanged {

private final String pathUrl;
private final PathItem oldPath;
private final PathItem newPath;
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.PathItem;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;

@Getter
@Setter
@Data
public class ChangedPaths implements ComposedChanged {

private final Map<String, PathItem> oldPathMap;
private final Map<String, PathItem> newPathMap;

Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.parameters.RequestBody;
import java.util.Arrays;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 27/12/17. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedRequestBody implements ComposedChanged {

private final RequestBody oldRequestBody;
private final RequestBody newRequestBody;
private final DiffContext context;
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.responses.ApiResponse;
import java.util.Arrays;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedResponse implements ComposedChanged {

private final ApiResponse oldApiResponse;
private final ApiResponse newApiResponse;
private final DiffContext context;
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import com.qdesrame.openapi.diff.model.schema.*;
import com.qdesrame.openapi.diff.core.model.schema.ChangedEnum;
import com.qdesrame.openapi.diff.core.model.schema.ChangedMaxLength;
import com.qdesrame.openapi.diff.core.model.schema.ChangedReadOnly;
import com.qdesrame.openapi.diff.core.model.schema.ChangedRequired;
import com.qdesrame.openapi.diff.core.model.schema.ChangedWriteOnly;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.media.Schema;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 22/12/17. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedSchema implements ComposedChanged {

protected DiffContext context;
protected Schema oldSchema;
protected Schema newSchema;
@@ -76,15 +79,24 @@ public DiffResult isCoreChanged() {
&& !discriminatorPropertyChanged) {
return DiffResult.NO_CHANGES;
}
boolean compatibleForRequest = (oldSchema != null || newSchema == null);
boolean compatibleForResponse =
missingProperties.isEmpty() && (oldSchema == null || newSchema != null);
if ((context.isRequest() && compatibleForRequest
if ((context.isRequest() && compatibleForRequest()
|| context.isResponse() && compatibleForResponse)
&& !changedType
&& !discriminatorPropertyChanged) {
return DiffResult.COMPATIBLE;
}
return DiffResult.INCOMPATIBLE;
}

private boolean compatibleForRequest() {
if (PathItem.HttpMethod.PUT.equals(context.getMethod())) {
if (increasedProperties.size() > 0) {
return false;
}
}

return (oldSchema != null || newSchema == null);
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.security.SecurityRequirement;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 06/01/18. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedSecurityRequirement implements ComposedChanged {

private SecurityRequirement oldSecurityRequirement;
private SecurityRequirement newSecurityRequirement;

Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.security.SecurityRequirement;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.commons.collections4.CollectionUtils;

/** Created by adarsh.sharma on 06/01/18. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedSecurityRequirements implements ComposedChanged {

private List<SecurityRequirement> oldSecurityRequirements;
private List<SecurityRequirement> newSecurityRequirements;

Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.security.SecurityScheme;
import java.util.Arrays;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.experimental.Accessors;

/** Created by adarsh.sharma on 11/01/18. */
@Getter
@Setter
@Data
@Accessors(chain = true)
public class ChangedSecurityScheme implements ComposedChanged {

private SecurityScheme oldSecurityScheme;
private SecurityScheme newSecurityScheme;

Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import java.util.List;
import lombok.Getter;

@Getter
public class ChangedSecuritySchemeScopes extends ChangedList<String> {

public ChangedSecuritySchemeScopes(List<String> oldValue, List<String> newValue) {
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import java.util.List;
import java.util.Objects;
@@ -16,8 +16,7 @@ public interface ComposedChanged extends Changed {
default DiffResult isChanged() {
DiffResult elementsResult =
DiffResult.fromWeight(
getChangedElements()
.stream()
getChangedElements().stream()
.filter(Objects::nonNull)
.map(Changed::isChanged)
.mapToInt(DiffResult::getWeight)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.PathItem;
import java.util.HashMap;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import static java.lang.String.format;

Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.qdesrame.openapi.diff.model;
package com.qdesrame.openapi.diff.core.model;

import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;

@Getter
@Setter
@Data
public class Endpoint {

private String pathUrl;
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.qdesrame.openapi.diff.model.schema;
package com.qdesrame.openapi.diff.core.model.schema;

import com.qdesrame.openapi.diff.model.ChangedList;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.model.DiffResult;
import com.qdesrame.openapi.diff.core.model.ChangedList;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.DiffResult;
import java.util.List;
import lombok.Getter;

@Getter
public class ChangedEnum<T> extends ChangedList<T> {

public ChangedEnum(List<T> oldValue, List<T> newValue, DiffContext context) {
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
package com.qdesrame.openapi.diff.model.schema;
package com.qdesrame.openapi.diff.core.model.schema;

import com.qdesrame.openapi.diff.model.Changed;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.model.DiffResult;
import com.qdesrame.openapi.diff.core.model.Changed;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.DiffResult;
import java.util.Objects;
import lombok.Value;

@Value
public class ChangedMaxLength implements Changed {
private final Integer oldValue;
private final Integer newValue;
private final DiffContext context;

public ChangedMaxLength(Integer oldValue, Integer newValue, DiffContext context) {
this.oldValue = oldValue;
this.newValue = newValue;
this.context = context;
}
Integer oldValue;
Integer newValue;
DiffContext context;

@Override
public DiffResult isChanged() {
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.qdesrame.openapi.diff.model.schema;
package com.qdesrame.openapi.diff.core.model.schema;

import com.qdesrame.openapi.diff.model.Changed;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.model.DiffResult;
import com.qdesrame.openapi.diff.core.model.Changed;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.DiffResult;
import java.util.Objects;
import java.util.Optional;

Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.qdesrame.openapi.diff.model.schema;
package com.qdesrame.openapi.diff.core.model.schema;

import com.qdesrame.openapi.diff.model.ChangedList;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.model.DiffResult;
import com.qdesrame.openapi.diff.core.model.ChangedList;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.DiffResult;
import java.util.List;
import lombok.Getter;

@Getter
public class ChangedRequired extends ChangedList<String> {

public ChangedRequired(List<String> oldValue, List<String> newValue, DiffContext context) {
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.qdesrame.openapi.diff.model.schema;
package com.qdesrame.openapi.diff.core.model.schema;

import com.qdesrame.openapi.diff.model.Changed;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.model.DiffResult;
import com.qdesrame.openapi.diff.core.model.Changed;
import com.qdesrame.openapi.diff.core.model.DiffContext;
import com.qdesrame.openapi.diff.core.model.DiffResult;
import java.util.Objects;
import java.util.Optional;

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.qdesrame.openapi.diff.output;
package com.qdesrame.openapi.diff.core.output;

import static com.qdesrame.openapi.diff.model.Changed.result;
import static com.qdesrame.openapi.diff.core.model.Changed.result;

import com.qdesrame.openapi.diff.model.*;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.model.*;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
@@ -213,12 +213,19 @@ private String properties(
String propPrefix, String title, Map<String, Schema> properties, DiffContext context) {
StringBuilder sb = new StringBuilder();
if (properties != null) {
properties.forEach(
(key, value) -> sb.append(property(propPrefix + key, title, resolve(value))));
properties.forEach((key, value) -> sb.append(resolveProperty(propPrefix, value, key, title)));
}
return sb.toString();
}

private String resolveProperty(String propPrefix, Schema value, String key, String title) {
try {
return property(propPrefix + key, title, resolve(value));
} catch (Exception e) {
return property(propPrefix + key, title, type(value));
}
}

protected String property(String name, String title, Schema schema) {
return property(name, title, type(schema));
}
@@ -234,7 +241,9 @@ protected Schema resolve(Schema schema) {

protected String type(Schema schema) {
String result = "object";
if (schema instanceof ArraySchema) {
if (schema == null) {
result = "no schema";
} else if (schema instanceof ArraySchema) {
result = "array";
} else if (schema.getType() != null) {
result = schema.getType();
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.qdesrame.openapi.diff.output;
package com.qdesrame.openapi.diff.core.output;

import static com.qdesrame.openapi.diff.model.Changed.result;
import static com.qdesrame.openapi.diff.core.model.Changed.result;
import static j2html.TagCreator.*;

import com.qdesrame.openapi.diff.model.*;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.model.*;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.media.Schema;
@@ -269,7 +269,16 @@ private void properties(
Map<String, Schema> properties,
DiffContext context) {
if (properties != null) {
properties.forEach((key, value) -> property(output, propPrefix + key, title, resolve(value)));
properties.forEach((key, value) -> resolveProperty(output, propPrefix, key, value, title));
}
}

private void resolveProperty(
ContainerTag output, String propPrefix, String key, Schema value, String title) {
try {
property(output, propPrefix + key, title, resolve(value));
} catch (Exception e) {
property(output, propPrefix + key, title, type(value));
}
}

@@ -288,7 +297,9 @@ protected Schema resolve(Schema schema) {

protected String type(Schema schema) {
String result = "object";
if (schema instanceof ArraySchema) {
if (schema == null) {
result = "no schema";
} else if (schema instanceof ArraySchema) {
result = "array";
} else if (schema.getType() != null) {
result = schema.getType();
@@ -347,7 +358,10 @@ private ContainerTag li_changedParam(ChangedParameter changeParam) {
return li_deprecatedParam(changeParam);
}
boolean changeRequired = changeParam.isChangeRequired();
boolean changeDescription = changeParam.getDescription().isDifferent();
boolean changeDescription =
Optional.ofNullable(changeParam.getDescription())
.map(ChangedMetadata::isDifferent)
.orElse(false);
Parameter rightParam = changeParam.getNewParameter();
Parameter leftParam = changeParam.getNewParameter();
ContainerTag li = li().withText(changeParam.getName() + " in " + changeParam.getIn());
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.qdesrame.openapi.diff.output;
package com.qdesrame.openapi.diff.core.output;

import static com.qdesrame.openapi.diff.model.Changed.result;
import static com.qdesrame.openapi.diff.utils.ChangedUtils.isUnchanged;
import static com.qdesrame.openapi.diff.core.model.Changed.result;
import static com.qdesrame.openapi.diff.core.utils.ChangedUtils.isUnchanged;
import static java.lang.String.format;

import com.qdesrame.openapi.diff.model.*;
import com.qdesrame.openapi.diff.utils.RefPointer;
import com.qdesrame.openapi.diff.utils.RefType;
import com.qdesrame.openapi.diff.core.model.*;
import com.qdesrame.openapi.diff.core.utils.RefPointer;
import com.qdesrame.openapi.diff.core.utils.RefType;
import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
@@ -63,8 +63,7 @@ protected String sectionTitle(String title) {
protected String listEndpoints(String title, List<Endpoint> endpoints) {
if (null == endpoints || endpoints.size() == 0) return "";
StringBuilder sb = new StringBuilder(sectionTitle(title));
endpoints
.stream()
endpoints.stream()
.map(e -> itemEndpoint(e.getMethod().toString(), e.getPathUrl(), e.getSummary()))
.forEach(sb::append);
return sb.toString();
@@ -85,8 +84,7 @@ protected String titleH5(String title) {
protected String listEndpoints(List<ChangedOperation> changedOperations) {
if (null == changedOperations || changedOperations.size() == 0) return "";
StringBuilder sb = new StringBuilder(sectionTitle("What's Changed"));
changedOperations
.stream()
changedOperations.stream()
.map(
operation -> {
StringBuilder details =
@@ -122,20 +120,15 @@ protected String responses(ChangedApiResponse changedApiResponse) {
StringBuilder sb = new StringBuilder("\n");
sb.append(listResponse("New response", changedApiResponse.getIncreased()));
sb.append(listResponse("Deleted response", changedApiResponse.getMissing()));
changedApiResponse
.getChanged()
.entrySet()
.stream()
changedApiResponse.getChanged().entrySet().stream()
.map(e -> this.itemResponse(e.getKey(), e.getValue()))
.forEach(sb::append);
return sb.toString();
}

protected String listResponse(String title, Map<String, ApiResponse> responses) {
StringBuilder sb = new StringBuilder();
responses
.entrySet()
.stream()
responses.entrySet().stream()
.map(e -> this.itemResponse(title, e.getKey(), e.getValue()))
.forEach(sb::append);
return sb.toString();
@@ -177,10 +170,7 @@ protected String headers(ChangedHeaders headers) {
if (headers != null) {
sb.append(listHeader("New header", headers.getIncreased()))
.append(listHeader("Deleted header", headers.getMissing()));
headers
.getChanged()
.entrySet()
.stream()
headers.getChanged().entrySet().stream()
.map(e -> this.itemHeader(e.getKey(), e.getValue()))
.forEach(sb::append);
}
@@ -189,9 +179,7 @@ protected String headers(ChangedHeaders headers) {

protected String listHeader(String title, Map<String, Header> headers) {
StringBuilder sb = new StringBuilder();
headers
.entrySet()
.stream()
headers.entrySet().stream()
.map(e -> this.itemHeader(title, e.getKey(), e.getValue()))
.forEach(sb::append);
return sb.toString();
@@ -225,10 +213,7 @@ protected String bodyContent(String prefix, ChangedContent changedContent) {
} else {
deepness = 0;
}
changedContent
.getChanged()
.entrySet()
.stream()
changedContent.getChanged().entrySet().stream()
.map(e -> this.itemContent(deepness, e.getKey(), e.getValue()))
.forEach(e -> sb.append(prefix).append(e));
return sb.toString();
@@ -240,9 +225,7 @@ protected String bodyContent(ChangedContent changedContent) {

protected String listContent(String prefix, String title, Map<String, MediaType> mediaTypes) {
StringBuilder sb = new StringBuilder();
mediaTypes
.entrySet()
.stream()
mediaTypes.entrySet().stream()
.map(e -> this.itemContent(title, e.getKey(), e.getValue()))
.forEach(e -> sb.append(prefix).append(e));
return sb.toString();
@@ -340,18 +323,14 @@ protected String schema(int deepness, ComposedSchema schema, DiffContext context
StringBuilder sb = new StringBuilder();
if (schema.getAllOf() != null && schema.getAllOf() != null) {
LOGGER.debug("All of schema");
schema
.getAllOf()
.stream()
schema.getAllOf().stream()
.map(this::resolve)
.forEach(composedChild -> sb.append(schema(deepness, composedChild, context)));
}
if (schema.getOneOf() != null && schema.getOneOf() != null) {
LOGGER.debug("One of schema");
sb.append(format("%sOne of:\n\n", indent(deepness)));
schema
.getOneOf()
.stream()
schema.getOneOf().stream()
.map(this::resolve)
.forEach(composedChild -> sb.append(schema(deepness + 1, composedChild, context)));
}
@@ -402,7 +381,7 @@ protected String properties(
if (properties != null) {
properties.forEach(
(key, value) -> {
sb.append(property(deepness, title, key, resolve(value)));
sb.append(resolveProperty(deepness, value, key, title));
if (showContent) {
sb.append(schema(deepness + 1, resolve(value), context));
}
@@ -411,6 +390,14 @@ protected String properties(
return sb.toString();
}

private String resolveProperty(int deepness, Schema value, String key, String title) {
try {
return property(deepness, title, key, resolve(value));
} catch (Exception e) {
return property(deepness, title, key, type(value), "");
}
}

protected String property(int deepness, String name, ChangedSchema schema) {
StringBuilder sb = new StringBuilder();
String type = type(schema.getNewSchema());
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.qdesrame.openapi.diff.core.output;

import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;

public interface Render {

String render(ChangedOpenApi diff);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.qdesrame.openapi.diff.utils;
package com.qdesrame.openapi.diff.core.utils;

import com.qdesrame.openapi.diff.model.Changed;
import com.qdesrame.openapi.diff.core.model.Changed;
import java.util.Optional;

public class ChangedUtils {
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.utils;
package com.qdesrame.openapi.diff.core.utils;

import java.util.LinkedHashMap;
import java.util.Map;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.qdesrame.openapi.diff.utils;
package com.qdesrame.openapi.diff.core.utils;

import com.qdesrame.openapi.diff.model.Endpoint;
import com.qdesrame.openapi.diff.core.model.Endpoint;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import java.util.ArrayList;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.qdesrame.openapi.diff.utils;
package com.qdesrame.openapi.diff.core.utils;

import io.swagger.v3.oas.models.Components;
import java.util.Map;
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.qdesrame.openapi.diff.utils;
package com.qdesrame.openapi.diff.core.utils;

import lombok.Getter;

/** Created by adarsh.sharma on 07/01/18. */
@Getter
public enum RefType {
REQUEST_BODIES("requestBodies"),
@@ -17,5 +16,5 @@ public enum RefType {
this.name = name;
}

private String name;
private final String name;
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.qdesrame.openapi.test;

import static com.qdesrame.openapi.test.TestUtils.assertOpenApiAreEquals;
import static com.qdesrame.openapi.test.TestUtils.assertOpenApiBackwardIncompatible;

import org.junit.jupiter.api.Test;

/** Created by trohrberg on 23/03/19. */
public class AddPropPutDiffTest {
private final String OPENAPI_DOC1 = "add-prop-put-1.yaml";
private final String OPENAPI_DOC2 = "add-prop-put-2.yaml";

@Test
public void testDiffSame() {
assertOpenApiAreEquals(OPENAPI_DOC1, OPENAPI_DOC1);
}

@Test
public void testDiffDifferent() {
assertOpenApiBackwardIncompatible(OPENAPI_DOC1, OPENAPI_DOC2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.qdesrame.openapi.test;

import static org.assertj.core.api.Assertions.assertThat;

import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.output.ConsoleRender;
import org.junit.jupiter.api.Test;

public class ConsoleRenderTest {
@Test
public void renderDoesNotFailWhenPropertyHasBeenRemoved() {
ConsoleRender render = new ConsoleRender();
ChangedOpenApi diff =
OpenApiCompare.fromLocations("missing_property_1.yaml", "missing_property_2.yaml");
assertThat(render.render(diff)).isNotBlank();
}
}
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@

import static org.assertj.core.api.Assertions.assertThat;

import com.qdesrame.openapi.diff.OpenApiCompare;
import com.qdesrame.openapi.diff.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import org.junit.jupiter.api.Test;

public class ContentDiffTest {
18 changes: 18 additions & 0 deletions core/src/test/java/com/qdesrame/openapi/test/HtmlRenderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.qdesrame.openapi.test;

import static org.assertj.core.api.Assertions.assertThat;

import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.output.HtmlRender;
import org.junit.jupiter.api.Test;

public class HtmlRenderTest {
@Test
public void renderDoesNotFailWhenPropertyHasBeenRemoved() {
HtmlRender render = new HtmlRender();
ChangedOpenApi diff =
OpenApiCompare.fromLocations("missing_property_1.yaml", "missing_property_2.yaml");
assertThat(render.render(diff)).isNotBlank();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.qdesrame.openapi.test;

import static org.assertj.core.api.Assertions.assertThat;

import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.output.MarkdownRender;
import org.junit.jupiter.api.Test;

public class MarkdownRenderTest {
@Test
public void renderDoesNotFailWhenPropertyHasBeenRemoved() {
MarkdownRender render = new MarkdownRender();
ChangedOpenApi diff =
OpenApiCompare.fromLocations("missing_property_1.yaml", "missing_property_2.yaml");
assertThat(render.render(diff)).isNotBlank();
}
}
Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@ public class OneOfDiffTest {
private final String OPENAPI_DOC5 = "composed_schema_2.yaml";
private final String OPENAPI_DOC6 = "oneOf_discriminator-changed_1.yaml";
private final String OPENAPI_DOC7 = "oneOf_discriminator-changed_2.yaml";
private final String OPENAPI_DOC8 = "oneOf_discriminator-missing_1.yaml";
private final String OPENAPI_DOC9 = "oneOf_discriminator-missing_2.yaml";

@Test
public void testDiffSame() {
@@ -42,4 +44,14 @@ public void testOneOfDiscrimitatorChanged() {
// The oneOf 'discriminator' changed: 'realtype' -> 'othertype':
assertOpenApiBackwardIncompatible(OPENAPI_DOC6, OPENAPI_DOC7);
}

@Test
public void testOneOfDiscrimitatorMissingSameOrder() {
assertOpenApiAreEquals(OPENAPI_DOC8, OPENAPI_DOC8);
}

@Test
public void testOneOfDiscrimitatorMissingDifferentOrder() {
assertOpenApiAreEquals(OPENAPI_DOC8, OPENAPI_DOC9);
}
}
Original file line number Diff line number Diff line change
@@ -3,12 +3,12 @@
import static com.qdesrame.openapi.test.TestUtils.assertOpenApiAreEquals;
import static org.assertj.core.api.Assertions.assertThat;

import com.qdesrame.openapi.diff.OpenApiCompare;
import com.qdesrame.openapi.diff.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.model.ChangedOperation;
import com.qdesrame.openapi.diff.model.Endpoint;
import com.qdesrame.openapi.diff.output.HtmlRender;
import com.qdesrame.openapi.diff.output.MarkdownRender;
import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.model.ChangedOperation;
import com.qdesrame.openapi.diff.core.model.Endpoint;
import com.qdesrame.openapi.diff.core.output.HtmlRender;
import com.qdesrame.openapi.diff.core.output.MarkdownRender;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.qdesrame.openapi.test;

import static org.assertj.core.api.Assertions.assertThat;

import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.model.ChangedResponse;
import com.qdesrame.openapi.diff.core.output.ConsoleRender;
import com.qdesrame.openapi.diff.core.output.HtmlRender;
import com.qdesrame.openapi.diff.core.output.MarkdownRender;
import io.swagger.v3.oas.models.media.Content;
import java.util.Map;
import org.junit.jupiter.api.Test;

public class ResponseAddedContentSchemaTest {

private final String OPENAPI_DOC1 = "response_schema_added_1.yaml";
private final String OPENAPI_DOC2 = "response_schema_added_2.yaml";

@Test
public void testDiffDifferent() {
ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(OPENAPI_DOC1, OPENAPI_DOC2);

assertThat(changedOpenApi.getNewEndpoints()).isEmpty();
assertThat(changedOpenApi.getMissingEndpoints()).isEmpty();
assertThat(changedOpenApi.getChangedOperations()).isNotEmpty();

Map<String, ChangedResponse> changedResponses =
changedOpenApi.getChangedOperations().get(0).getApiResponses().getChanged();
assertThat(changedResponses).containsKey("200");

ChangedResponse changedResponse = changedResponses.get("200");
Content oldContent = changedResponse.getOldApiResponse().getContent();
Content newContent = changedResponse.getNewApiResponse().getContent();
assertThat(oldContent.get("application/json").getSchema()).isNull();
assertThat(newContent.get("application/json").getSchema()).isNotNull();
}

@Test
public void testDiffCanBeRendered() {
ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(OPENAPI_DOC1, OPENAPI_DOC2);

assertThat(new ConsoleRender().render(changedOpenApi)).isNotBlank();
assertThat(new HtmlRender().render(changedOpenApi)).isNotBlank();
assertThat(new MarkdownRender().render(changedOpenApi)).isNotBlank();
}
}
Original file line number Diff line number Diff line change
@@ -2,10 +2,10 @@

import static org.assertj.core.api.Assertions.assertThat;

import com.qdesrame.openapi.diff.OpenApiCompare;
import com.qdesrame.openapi.diff.model.ChangedHeaders;
import com.qdesrame.openapi.diff.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.model.ChangedResponse;
import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.ChangedHeaders;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.model.ChangedResponse;
import java.util.Map;
import org.junit.jupiter.api.Test;

Original file line number Diff line number Diff line change
@@ -3,8 +3,8 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.qdesrame.openapi.diff.OpenApiCompare;
import com.qdesrame.openapi.diff.model.*;
import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.*;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import org.junit.jupiter.api.Test;

@@ -21,9 +21,7 @@ public void testDiffDifferent() {
assertThat(changedOpenApi.getChangedOperations().size() == 3);

ChangedOperation changedOperation1 =
changedOpenApi
.getChangedOperations()
.stream()
changedOpenApi.getChangedOperations().stream()
.filter(x -> x.getPathUrl().equals("/pet/{petId}"))
.findFirst()
.get();
@@ -51,9 +49,7 @@ public void testDiffDifferent() {
.isEqualTo("read:pets"));

ChangedOperation changedOperation2 =
changedOpenApi
.getChangedOperations()
.stream()
changedOpenApi.getChangedOperations().stream()
.filter(x -> x.getPathUrl().equals("/pet3"))
.findFirst()
.get();
@@ -73,9 +69,7 @@ public void testDiffDifferent() {
assertThat(changedImplicitOAuthFlow2.isAuthorizationUrl()).isTrue();

ChangedOperation changedOperation3 =
changedOpenApi
.getChangedOperations()
.stream()
changedOpenApi.getChangedOperations().stream()
.filter(x -> x.getPathUrl().equals("/pet/findByStatus2"))
.findFirst()
.get();
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.qdesrame.openapi.test;

import static com.qdesrame.openapi.test.TestUtils.assertOpenApiAreEquals;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

@Disabled
public class Swagger2CompatibilityTest {
private final String SWAGGER_DOC1 = "petstore_swagger2.yaml";
private final String OPENAPI_DOC2 = "petstore_openapi3.yaml";

@Test
public void testEqual() {
assertOpenApiAreEquals(SWAGGER_DOC1, SWAGGER_DOC1);
}

@Test
public void testSwagger2ToOpenapi3() {
assertOpenApiAreEquals(SWAGGER_DOC1, OPENAPI_DOC2);
}
}
Original file line number Diff line number Diff line change
@@ -3,8 +3,8 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.slf4j.LoggerFactory.getLogger;

import com.qdesrame.openapi.diff.OpenApiCompare;
import com.qdesrame.openapi.diff.model.ChangedOpenApi;
import com.qdesrame.openapi.diff.core.OpenApiCompare;
import com.qdesrame.openapi.diff.core.model.ChangedOpenApi;
import org.slf4j.Logger;

public class TestUtils {
File renamed without changes.
File renamed without changes.
71 changes: 71 additions & 0 deletions core/src/test/resources/add-prop-put-1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
openapi: 3.0.0
servers:
- description: SwaggerHub API Auto Mocking
url: https://virtserver.swaggerhub.com/anshul10s/pet-store/1.0.0
info:
description: |
This is a sample Petstore server. You can find
out more about Swagger at
[http://swagger.io](http://swagger.io) or on
[irc.freenode.net, #swagger](http://swagger.io/irc/).
version: "1.0.0"
title: Swagger Petstore
termsOfService: 'http://swagger.io/terms/'
contact:
email: apiteam@swagger.io
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: pet
description: Everything about your Pets
externalDocs:
description: Find out more
url: 'http://swagger.io'
- name: store
description: Access to Petstore orders
- name: user
description: Operations about user
externalDocs:
description: Find out more about our store
url: 'http://swagger.io'
paths:
/store/inventory/{id}:
put:
tags:
- store
summary: Updates the inventory with the given id
description: Updates the inventory with the given id and returns it
operationId: putInventory
parameters:
- name: id
in: path
description: Unique Id of the inventory
required: true
example: a-b-c-d
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Inventory'
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Inventory'
externalDocs:
description: Find out more about Swagger
url: 'http://swagger.io'
components:
schemas:
Inventory:
type: object
properties:
id:
type: string
details:
type: count
73 changes: 73 additions & 0 deletions core/src/test/resources/add-prop-put-2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
openapi: 3.0.0
servers:
- description: SwaggerHub API Auto Mocking
url: https://virtserver.swaggerhub.com/anshul10s/pet-store/1.0.0
info:
description: |
This is a sample Petstore server. You can find
out more about Swagger at
[http://swagger.io](http://swagger.io) or on
[irc.freenode.net, #swagger](http://swagger.io/irc/).
version: "1.0.0"
title: Swagger Petstore
termsOfService: 'http://swagger.io/terms/'
contact:
email: apiteam@swagger.io
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: pet
description: Everything about your Pets
externalDocs:
description: Find out more
url: 'http://swagger.io'
- name: store
description: Access to Petstore orders
- name: user
description: Operations about user
externalDocs:
description: Find out more about our store
url: 'http://swagger.io'
paths:
/store/inventory/{id}:
put:
tags:
- store
summary: Updates the inventory with the given id
description: Updates the inventory with the given id and returns it
operationId: putInventory
parameters:
- name: id
in: path
description: Unique Id of the inventory
required: true
example: a-b-c-d
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Inventory'
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Inventory'
externalDocs:
description: Find out more about Swagger
url: 'http://swagger.io'
components:
schemas:
Inventory:
type: object
properties:
id:
type: string
details:
type: count
extra_info:
type: string
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -36,9 +36,6 @@ paths:
summary: Add a new pet to the store
description: ''
operationId: addPet
responses:
'405':
description: Invalid input
requestBody:
$ref: '#/components/requestBodies/Pet'
responses:
@@ -48,6 +45,8 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/MyResponseType'
'405':
description: Invalid input
/pet/findByStatus:
get:
tags:
Original file line number Diff line number Diff line change
@@ -36,9 +36,6 @@ paths:
summary: Add a new pet to the store
description: ''
operationId: addPet
responses:
'405':
description: Invalid input
requestBody:
$ref: '#/components/requestBodies/Pet'
responses:
@@ -48,6 +45,8 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/MyResponseType'
'405':
description: Invalid input
get:
tags:
- pet
Original file line number Diff line number Diff line change
@@ -36,9 +36,6 @@ paths:
summary: Add a new pet to the store
description: ''
operationId: addPet
responses:
'405':
description: Invalid input
requestBody:
$ref: '#/components/requestBodies/Pet'
responses:
@@ -48,6 +45,8 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/MyResponseType'
'405':
description: Invalid input
/pet/findByStatus:
get:
tags:
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
31 changes: 31 additions & 0 deletions core/src/test/resources/missing_property_1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
openapi: 3.0.1
info:
title: Title
version: 1.0.0
description: Description
paths:
/:
get:
summary: Simple GET
operationId: simpleGet
responses:
default:
content:
application/json:
schema:
$ref: '#/components/schemas/Wrapper'
description: Simple GET
components:
schemas:
Wrapper:
type: object
properties:
id:
type: string
childProperty:
$ref: '#/components/schemas/ChildProperty'
ChildProperty:
type: object
properties:
id:
type: string
24 changes: 24 additions & 0 deletions core/src/test/resources/missing_property_2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
openapi: 3.0.1
info:
title: Title
version: 1.0.0
description: Description
paths:
/:
get:
summary: Simple GET
operationId: simpleGet
responses:
default:
content:
application/json:
schema:
$ref: '#/components/schemas/Wrapper'
description: Simple GET
components:
schemas:
Wrapper:
type: object
properties:
id:
type: string
File renamed without changes.
File renamed without changes.
File renamed without changes.
44 changes: 44 additions & 0 deletions core/src/test/resources/oneOf_discriminator-missing_1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
openapi: 3.0.1
info:
title: oneOf test for issue 29
version: '1.0'
servers:
- url: 'http://localhost:8000/'
paths:
/state:
post:
operationId: update
requestBody:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/A'
- $ref: '#/components/schemas/B'
required: true
responses:
'201':
description: OK
components:
schemas:
A:
type: object
properties:
realtype:
type: string
othertype:
type: string
message:
type: string
B:
type: object
properties:
realtype:
type: string
othertype:
type: string
description:
type: string
code:
type: integer
format: int32
44 changes: 44 additions & 0 deletions core/src/test/resources/oneOf_discriminator-missing_2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
openapi: 3.0.1
info:
title: oneOf test for issue 29
version: '1.0'
servers:
- url: 'http://localhost:8000/'
paths:
/state:
post:
operationId: update
requestBody:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/B'
- $ref: '#/components/schemas/A'
required: true
responses:
'201':
description: OK
components:
schemas:
A:
type: object
properties:
realtype:
type: string
othertype:
type: string
message:
type: string
B:
type: object
properties:
realtype:
type: string
othertype:
type: string
description:
type: string
code:
type: integer
format: int32
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
109 changes: 109 additions & 0 deletions core/src/test/resources/petstore_openapi3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
101 changes: 101 additions & 0 deletions core/src/test/resources/petstore_swagger2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
swagger: "2.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
host: petstore.swagger.io
basePath: /v1
schemes:
- http
consumes:
- application/json
produces:
- application/json
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
type: integer
format: int32
responses:
"200":
description: A paged array of pets
headers:
x-next:
type: string
description: A link to the next page of responses
schema:
$ref: '#/definitions/Pets'
default:
description: unexpected error
schema:
$ref: '#/definitions/Error'
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
"201":
description: Null response
default:
description: unexpected error
schema:
$ref: '#/definitions/Error'
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
type: string
responses:
"200":
description: Expected response to a valid request
schema:
$ref: '#/definitions/Pets'
default:
description: unexpected error
schema:
$ref: '#/definitions/Error'
definitions:
Pet:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: '#/definitions/Pet'
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
106 changes: 106 additions & 0 deletions core/src/test/resources/response_schema_added_1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json: {}
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
Loading