Skip to content

Commit

Permalink
Merge pull request #55 from exoego/smart-merger
Browse files Browse the repository at this point in the history
Implement smarter merge
  • Loading branch information
k0kubun authored May 19, 2022
2 parents 6107936 + 7bf6054 commit 7c03c0f
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 13 deletions.
11 changes: 6 additions & 5 deletions lib/rspec/openapi/schema_merger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,23 @@ def normalize_keys(spec)
# Also this needs to be aware of OpenAPI details unlike an ordinary deep_reverse_merge
# because a Hash-like structure may be an array whose Hash elements have a key name.
#
# TODO: Perform more intelligent merges like rerouting edits / merging types
# TODO: Should we probably force-merge `summary` regardless of manual modifications?
def deep_reverse_merge!(base, spec)
spec.each do |key, value|
if base[key].is_a?(Hash) && value.is_a?(Hash)
deep_reverse_merge!(base[key], value)
elsif !base.key?(key)
base[key] = value
if !base[key].key?("$ref")
deep_reverse_merge!(base[key], value)
end
elsif base[key].is_a?(Array) && value.is_a?(Array)
# parameters need to be merged as if `name` and `in` were the Hash keys.
if key == 'parameters'
base[key] |= value
base[key].uniq! { |param| param.slice('name', 'in') }
else
base[key] = value
end
else
# no-op
base[key] = value
end
end
base
Expand Down
4 changes: 2 additions & 2 deletions spec/rails/doc/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
}
},
"200": {
"description": "with flat query parameters",
"description": "with different deep query parameters",
"content": {
"application/json": {
"schema": {
Expand Down Expand Up @@ -406,7 +406,7 @@
},
"example": {
"nested": {
"image": "#<ActionDispatch::Http::UploadedFile:0x00007fa723dec4a8>",
"image": "test.png",
"caption": "Some caption"
}
}
Expand Down
12 changes: 6 additions & 6 deletions spec/rails/doc/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ paths:
example: token
responses:
'200':
description: returns a list of tables
description: with different deep query parameters
content:
application/json:
schema:
Expand Down Expand Up @@ -93,7 +93,7 @@ paths:
database:
id: 2
name: production
null_sample:
null_sample:
storage_size: 12.3
created_at: '2020-07-17T00:00:00+00:00'
updated_at: '2020-07-17T00:00:00+00:00'
Expand Down Expand Up @@ -165,7 +165,7 @@ paths:
database:
id: 2
name: production
null_sample:
null_sample:
storage_size: 12.3
created_at: '2020-07-17T00:00:00+00:00'
updated_at: '2020-07-17T00:00:00+00:00'
Expand Down Expand Up @@ -218,7 +218,7 @@ paths:
database:
id: 2
name: production
null_sample:
null_sample:
storage_size: 12.3
created_at: '2020-07-17T00:00:00+00:00'
updated_at: '2020-07-17T00:00:00+00:00'
Expand Down Expand Up @@ -310,7 +310,7 @@ paths:
database:
id: 2
name: production
null_sample:
null_sample:
storage_size: 12.3
created_at: '2020-07-17T00:00:00+00:00'
updated_at: '2020-07-17T00:00:00+00:00'
Expand Down Expand Up @@ -362,7 +362,7 @@ paths:
database:
id: 2
name: production
null_sample:
null_sample:
storage_size: 12.3
created_at: '2020-07-17T00:00:00+00:00'
updated_at: '2020-07-17T00:00:00+00:00'
Expand Down
64 changes: 64 additions & 0 deletions spec/rspec/schema_merger/base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"openapi": "3.0.3",
"info": {
"title": "My API",
"version": "1.0.0"
},
"servers": [],
"paths": {
"/tables": {
"get": {
"summary": "index",
"tags": [
"Table"
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
},
"example": 1
}
],
"responses": {
"200": {
"description": "foo",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Table"
},
"example": [
{
"id": 1,
"name": "THIS SHOULD BE UPDATED"
}
]
}
}
}
},
"parameters": []
}
}
},
"components": {
"schemas": {
"Table": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
}
}
}
}
63 changes: 63 additions & 0 deletions spec/rspec/schema_merger/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"openapi": "3.0.3",
"info": {
"title": "My API",
"version": "1.0.0"
},
"servers": [],
"paths": {
"/tables": {
"get": {
"summary": "index",
"tags": [
"Table"
],
"parameters": [
{
"name": "foo_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
},
"example": 9999
}
],
"responses": {
"200": {
"description": "foo",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Table"
},
"example": [
{
"id": 9999,
"name": "UPDATED"
}
]
}
}
}
}
}
}
},
"components": {
"schemas": {
"Table": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
}
}
}
}
49 changes: 49 additions & 0 deletions spec/rspec/schema_merger/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"paths": {
"/tables": {
"get": {
"summary": "index",
"tags": [
"Table"
],
"parameters": [
{
"name": "foo_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
},
"example": 9999
}
],
"responses": {
"200": {
"description": "foo",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"example": [
{
"id": 9999,
"name": "UPDATED"
}
]
}
}
}
}
}
}
}
}
27 changes: 27 additions & 0 deletions spec/rspec/schema_merger/schema_merger_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'spec_helper'
require 'json'
require "rspec/openapi/schema_merger"

RSpec.describe "SchemaMerger" do
include SpecHelper

let(:base_path) do
File.expand_path('spec/rspec/schema_merger/base.json', repo_root)
end

let(:input_path) do
File.expand_path('spec/rspec/schema_merger/input.json', repo_root)
end

let(:expected_path) do
File.expand_path('spec/rspec/schema_merger/expected.json', repo_root)
end

it "overwrite the supported key, but leaves the unsupported keys" do
base_json = JSON.load(File.read(base_path))
input_json = JSON.load(File.read(input_path))
res = RSpec::OpenAPI::SchemaMerger.reverse_merge!(base_json, input_json)
expected_json = JSON.load(File.read(expected_path))
expect(res).to eq(expected_json)
end
end

0 comments on commit 7c03c0f

Please sign in to comment.