From 15054e60bd4da81fde01f7224a23d00e628d5dcc Mon Sep 17 00:00:00 2001 From: Aaditya Taparia Date: Mon, 3 Dec 2018 15:45:23 +0900 Subject: [PATCH 01/41] Remove child class gotcha --- lib/rspec_api_documentation/open_api/example.rb | 7 ------- lib/rspec_api_documentation/open_api/headers.rb | 7 ------- lib/rspec_api_documentation/open_api/node.rb | 15 ++++++++++----- lib/rspec_api_documentation/open_api/paths.rb | 7 ------- .../open_api/response.rb | 4 ++-- lib/rspec_api_documentation/open_api/root.rb | 2 +- .../writers/open_api_writer.rb | 17 +++++++++-------- 7 files changed, 22 insertions(+), 37 deletions(-) delete mode 100644 lib/rspec_api_documentation/open_api/example.rb delete mode 100644 lib/rspec_api_documentation/open_api/headers.rb delete mode 100644 lib/rspec_api_documentation/open_api/paths.rb diff --git a/lib/rspec_api_documentation/open_api/example.rb b/lib/rspec_api_documentation/open_api/example.rb deleted file mode 100644 index c641b191..00000000 --- a/lib/rspec_api_documentation/open_api/example.rb +++ /dev/null @@ -1,7 +0,0 @@ -module RspecApiDocumentation - module OpenApi - class Example < Node - CHILD_CLASS = true - end - end -end diff --git a/lib/rspec_api_documentation/open_api/headers.rb b/lib/rspec_api_documentation/open_api/headers.rb deleted file mode 100644 index 6a073a14..00000000 --- a/lib/rspec_api_documentation/open_api/headers.rb +++ /dev/null @@ -1,7 +0,0 @@ -module RspecApiDocumentation - module OpenApi - class Headers < Node - CHILD_CLASS = Header - end - end -end diff --git a/lib/rspec_api_documentation/open_api/node.rb b/lib/rspec_api_documentation/open_api/node.rb index 2f102c88..c48db3b4 100644 --- a/lib/rspec_api_documentation/open_api/node.rb +++ b/lib/rspec_api_documentation/open_api/node.rb @@ -36,18 +36,21 @@ def initialize(opts = {}) opts.each do |name, value| if name.to_s == 'hide' self.hide = value - elsif self.class::CHILD_CLASS - add_setting name, :value => self.class::CHILD_CLASS === true ? value : self.class::CHILD_CLASS.new(value) elsif setting_exist?(name.to_sym) schema = setting_schema(name) converted = - case - when schema.is_a?(Array) && schema[0] <= Node then value.map { |v| v.is_a?(schema[0]) ? v : schema[0].new(v) } - when schema <= Node then value.is_a?(schema) ? value : schema.new(value) + if schema.is_a?(Hash) && schema.values[0] <= Node + Hash[value.map { |k, v| [k, v.is_a?(schema.values[0]) ? v : schema.values[0].new(v)] }] + elsif schema.is_a?(Array) && schema[0] <= Node + value.map { |v| v.is_a?(schema[0]) ? v : schema[0].new(v) } + elsif schema <= Node + value.is_a?(schema) ? value : schema.new(value) else value end assign_setting(name, converted) + elsif self.class::CHILD_CLASS + add_setting name, :value => self.class::CHILD_CLASS === true ? value : self.class::CHILD_CLASS.new(value) else public_send("#{name}=", value) if respond_to?("#{name}=") end @@ -94,6 +97,8 @@ def as_json when value.is_a?(Array) && value[0].is_a?(Node) tmp = value.select { |v| !v.hide }.map { |v| v.as_json } hash[name] = tmp unless tmp.empty? + when value.is_a?(Hash) && value.values[0].is_a?(Node) + hash[name] = Hash[value.map { |k, v| [k, v.as_json] }] else hash[name] = value end unless value.nil? diff --git a/lib/rspec_api_documentation/open_api/paths.rb b/lib/rspec_api_documentation/open_api/paths.rb deleted file mode 100644 index b3a9efb1..00000000 --- a/lib/rspec_api_documentation/open_api/paths.rb +++ /dev/null @@ -1,7 +0,0 @@ -module RspecApiDocumentation - module OpenApi - class Paths < Node - CHILD_CLASS = Path - end - end -end diff --git a/lib/rspec_api_documentation/open_api/response.rb b/lib/rspec_api_documentation/open_api/response.rb index 6584db6f..3d1fa91a 100644 --- a/lib/rspec_api_documentation/open_api/response.rb +++ b/lib/rspec_api_documentation/open_api/response.rb @@ -3,8 +3,8 @@ module OpenApi class Response < Node add_setting :description, :required => true, :default => 'Successful operation' add_setting :schema, :schema => Schema - add_setting :headers, :schema => Headers - add_setting :examples, :schema => Example + add_setting :headers, :schema => { "" => Header } + add_setting :examples end end end diff --git a/lib/rspec_api_documentation/open_api/root.rb b/lib/rspec_api_documentation/open_api/root.rb index edaeae96..4c03e5a9 100644 --- a/lib/rspec_api_documentation/open_api/root.rb +++ b/lib/rspec_api_documentation/open_api/root.rb @@ -8,7 +8,7 @@ class Root < Node add_setting :schemes, :default => %w(http https) add_setting :consumes, :default => %w(application/json application/xml) add_setting :produces, :default => %w(application/json application/xml) - add_setting :paths, :default => Paths.new, :required => true, :schema => Paths + add_setting :paths, :default => {}, :required => true, :schema => { "" => Path } add_setting :definitions add_setting :parameters add_setting :responses diff --git a/lib/rspec_api_documentation/writers/open_api_writer.rb b/lib/rspec_api_documentation/writers/open_api_writer.rb index ce45080c..e8c702e0 100644 --- a/lib/rspec_api_documentation/writers/open_api_writer.rb +++ b/lib/rspec_api_documentation/writers/open_api_writer.rb @@ -80,11 +80,12 @@ def add_tags! end def add_paths! - specs.safe_assign_setting(:paths, OpenApi::Paths.new) + specs.safe_assign_setting(:paths, {}) examples.each do |example| - specs.paths.add_setting example.route, :value => OpenApi::Path.new + route = example.route.to_s + specs.paths[route] = OpenApi::Path.new - operation = specs.paths.setting(example.route).setting(example.http_method) || OpenApi::Operation.new + operation = specs.paths[route].setting(example.http_method) || OpenApi::Operation.new operation.safe_assign_setting(:tags, [example.resource_name]) operation.safe_assign_setting(:summary, example.respond_to?(:route_summary) ? example.route_summary : '') @@ -97,7 +98,7 @@ def add_paths! process_responses(operation.responses, example) - specs.paths.setting(example.route).assign_setting(example.http_method, operation) + specs.paths[route].assign_setting(example.http_method, operation) end end @@ -110,16 +111,16 @@ def process_responses(responses, example) ) if request[:response_headers] - response.safe_assign_setting(:headers, OpenApi::Headers.new) + response.safe_assign_setting(:headers, {}) request[:response_headers].each do |header, value| - response.headers.add_setting header, :value => OpenApi::Header.new('x-example-value' => value) + response.headers[header.to_s] = OpenApi::Header.new('x-example-value' => value) end end if /\A(?[^;]+)/ =~ request[:response_content_type] - response.safe_assign_setting(:examples, OpenApi::Example.new) + response.safe_assign_setting(:examples, {}) response_body = JSON.parse(request[:response_body]) rescue nil - response.examples.add_setting response_content_type, :value => response_body + response.examples[response_content_type.to_s] = response_body end responses.add_setting "#{request[:response_status]}", :value => response end From 4baa9515d12442b47689e575d015c38062a3a2ed Mon Sep 17 00:00:00 2001 From: Aaditya Taparia Date: Mon, 3 Dec 2018 17:38:44 +0900 Subject: [PATCH 02/41] Remove child_class completely --- lib/rspec_api_documentation.rb | 4 ---- lib/rspec_api_documentation/open_api/node.rb | 10 +--------- lib/rspec_api_documentation/open_api/operation.rb | 4 ++-- lib/rspec_api_documentation/open_api/response.rb | 2 +- lib/rspec_api_documentation/open_api/responses.rb | 9 --------- lib/rspec_api_documentation/open_api/root.rb | 4 ++-- .../open_api/security_definitions.rb | 7 ------- .../writers/open_api_writer.rb | 12 ++++++------ spec/open_api/root_spec.rb | 2 -- 9 files changed, 12 insertions(+), 42 deletions(-) delete mode 100644 lib/rspec_api_documentation/open_api/responses.rb delete mode 100644 lib/rspec_api_documentation/open_api/security_definitions.rb diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb index 5986aadb..8dd61d23 100644 --- a/lib/rspec_api_documentation.rb +++ b/lib/rspec_api_documentation.rb @@ -58,18 +58,14 @@ module OpenApi autoload :Info autoload :Contact autoload :License - autoload :Paths autoload :Path autoload :Tag autoload :Operation autoload :Parameter - autoload :Responses autoload :Response autoload :Example - autoload :Headers autoload :Header autoload :Schema - autoload :SecurityDefinitions autoload :SecuritySchema end diff --git a/lib/rspec_api_documentation/open_api/node.rb b/lib/rspec_api_documentation/open_api/node.rb index c48db3b4..8830a319 100644 --- a/lib/rspec_api_documentation/open_api/node.rb +++ b/lib/rspec_api_documentation/open_api/node.rb @@ -1,12 +1,6 @@ module RspecApiDocumentation module OpenApi class Node - # this is used to define class of incoming option attribute - # If +false+ then do not create new setting - # If +true+ then create new setting with raw passed value - # If RspecApiDocumentation::OpenApi::Node then create new setting and wrap it in this class - CHILD_CLASS = false - # This attribute allow us to hide some of children through configuration file attr_accessor :hide @@ -49,8 +43,6 @@ def initialize(opts = {}) value end assign_setting(name, converted) - elsif self.class::CHILD_CLASS - add_setting name, :value => self.class::CHILD_CLASS === true ? value : self.class::CHILD_CLASS.new(value) else public_send("#{name}=", value) if respond_to?("#{name}=") end @@ -98,7 +90,7 @@ def as_json tmp = value.select { |v| !v.hide }.map { |v| v.as_json } hash[name] = tmp unless tmp.empty? when value.is_a?(Hash) && value.values[0].is_a?(Node) - hash[name] = Hash[value.map { |k, v| [k, v.as_json] }] + hash[name] = Hash[value.select { |k, v| !v.hide }.map { |k, v| [k, v.as_json] }] else hash[name] = value end unless value.nil? diff --git a/lib/rspec_api_documentation/open_api/operation.rb b/lib/rspec_api_documentation/open_api/operation.rb index 85db7c1b..5c6f6986 100644 --- a/lib/rspec_api_documentation/open_api/operation.rb +++ b/lib/rspec_api_documentation/open_api/operation.rb @@ -3,13 +3,13 @@ module OpenApi class Operation < Node add_setting :tags, :default => [] add_setting :summary - add_setting :description, :default => '' + add_setting :description add_setting :externalDocs add_setting :operationId add_setting :consumes add_setting :produces add_setting :parameters, :default => [], :schema => [Parameter] - add_setting :responses, :required => true, :schema => Responses + add_setting :responses, :required => true, :schema => { String => Response } add_setting :schemes add_setting :deprecated, :default => false add_setting :security diff --git a/lib/rspec_api_documentation/open_api/response.rb b/lib/rspec_api_documentation/open_api/response.rb index 3d1fa91a..ba379ea1 100644 --- a/lib/rspec_api_documentation/open_api/response.rb +++ b/lib/rspec_api_documentation/open_api/response.rb @@ -3,7 +3,7 @@ module OpenApi class Response < Node add_setting :description, :required => true, :default => 'Successful operation' add_setting :schema, :schema => Schema - add_setting :headers, :schema => { "" => Header } + add_setting :headers, :schema => { String => Header } add_setting :examples end end diff --git a/lib/rspec_api_documentation/open_api/responses.rb b/lib/rspec_api_documentation/open_api/responses.rb deleted file mode 100644 index 4b8c7025..00000000 --- a/lib/rspec_api_documentation/open_api/responses.rb +++ /dev/null @@ -1,9 +0,0 @@ -module RspecApiDocumentation - module OpenApi - class Responses < Node - CHILD_CLASS = Response - - add_setting :default, :default => lambda { |responses| responses.existing_settings.size > 1 ? nil : Response.new } - end - end -end diff --git a/lib/rspec_api_documentation/open_api/root.rb b/lib/rspec_api_documentation/open_api/root.rb index 4c03e5a9..420fb630 100644 --- a/lib/rspec_api_documentation/open_api/root.rb +++ b/lib/rspec_api_documentation/open_api/root.rb @@ -8,11 +8,11 @@ class Root < Node add_setting :schemes, :default => %w(http https) add_setting :consumes, :default => %w(application/json application/xml) add_setting :produces, :default => %w(application/json application/xml) - add_setting :paths, :default => {}, :required => true, :schema => { "" => Path } + add_setting :paths, :default => {}, :required => true, :schema => { String => Path } add_setting :definitions add_setting :parameters add_setting :responses - add_setting :securityDefinitions, :schema => SecurityDefinitions + add_setting :securityDefinitions, :schema => { String => SecuritySchema } add_setting :security add_setting :tags, :default => [], :schema => [Tag] add_setting :externalDocs diff --git a/lib/rspec_api_documentation/open_api/security_definitions.rb b/lib/rspec_api_documentation/open_api/security_definitions.rb deleted file mode 100644 index e1ddc136..00000000 --- a/lib/rspec_api_documentation/open_api/security_definitions.rb +++ /dev/null @@ -1,7 +0,0 @@ -module RspecApiDocumentation - module OpenApi - class SecurityDefinitions < Node - CHILD_CLASS = SecuritySchema - end - end -end diff --git a/lib/rspec_api_documentation/writers/open_api_writer.rb b/lib/rspec_api_documentation/writers/open_api_writer.rb index e8c702e0..9552dada 100644 --- a/lib/rspec_api_documentation/writers/open_api_writer.rb +++ b/lib/rspec_api_documentation/writers/open_api_writer.rb @@ -48,7 +48,7 @@ def examples end def add_security_definitions! - security_definitions = OpenApi::SecurityDefinitions.new + security_definitions = {} arr = examples.map do |example| example.respond_to?(:authentications) ? example.authentications : nil @@ -62,7 +62,7 @@ def add_security_definitions! type: opts[:type], in: opts[:in] ) - security_definitions.add_setting security, :value => schema + security_definitions[security.to_s] = schema end end specs.securityDefinitions = security_definitions unless arr.empty? @@ -83,14 +83,14 @@ def add_paths! specs.safe_assign_setting(:paths, {}) examples.each do |example| route = example.route.to_s - specs.paths[route] = OpenApi::Path.new + specs.paths[route] ||= OpenApi::Path.new operation = specs.paths[route].setting(example.http_method) || OpenApi::Operation.new operation.safe_assign_setting(:tags, [example.resource_name]) operation.safe_assign_setting(:summary, example.respond_to?(:route_summary) ? example.route_summary : '') operation.safe_assign_setting(:description, example.respond_to?(:route_description) ? example.route_description : '') - operation.safe_assign_setting(:responses, OpenApi::Responses.new) + operation.safe_assign_setting(:responses, {}) operation.safe_assign_setting(:parameters, extract_parameters(example)) operation.safe_assign_setting(:consumes, example.requests.map { |request| request[:request_content_type] }.compact.map { |q| q[/[^;]+/] }) operation.safe_assign_setting(:produces, example.requests.map { |request| request[:response_content_type] }.compact.map { |q| q[/[^;]+/] }) @@ -120,9 +120,9 @@ def process_responses(responses, example) if /\A(?[^;]+)/ =~ request[:response_content_type] response.safe_assign_setting(:examples, {}) response_body = JSON.parse(request[:response_body]) rescue nil - response.examples[response_content_type.to_s] = response_body + response.examples[response_content_type.to_s] = response_body if response_body end - responses.add_setting "#{request[:response_status]}", :value => response + responses[request[:response_status].to_s] = response end end diff --git a/spec/open_api/root_spec.rb b/spec/open_api/root_spec.rb index 52debbbf..44aafaf5 100644 --- a/spec/open_api/root_spec.rb +++ b/spec/open_api/root_spec.rb @@ -8,7 +8,6 @@ describe "default settings" do class RspecApiDocumentation::OpenApi::Info; end - class RspecApiDocumentation::OpenApi::Paths; end its(:swagger) { should == '2.0' } its(:info) { should be_a(RspecApiDocumentation::OpenApi::Info) } @@ -17,7 +16,6 @@ class RspecApiDocumentation::OpenApi::Paths; end its(:schemes) { should == %w(http https) } its(:consumes) { should == %w(application/json application/xml) } its(:produces) { should == %w(application/json application/xml) } - its(:paths) { should be_a(RspecApiDocumentation::OpenApi::Paths) } its(:definitions) { should be_nil } its(:parameters) { should be_nil } its(:responses) { should be_nil } From 03abdc6626d629858540604b9c095b3bde00c1fd Mon Sep 17 00:00:00 2001 From: Aaditya Taparia Date: Mon, 3 Dec 2018 18:58:45 +0900 Subject: [PATCH 03/41] Add path root spec --- lib/rspec_api_documentation.rb | 1 - spec/open_api/root_spec.rb | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb index 8dd61d23..ed413937 100644 --- a/lib/rspec_api_documentation.rb +++ b/lib/rspec_api_documentation.rb @@ -63,7 +63,6 @@ module OpenApi autoload :Operation autoload :Parameter autoload :Response - autoload :Example autoload :Header autoload :Schema autoload :SecuritySchema diff --git a/spec/open_api/root_spec.rb b/spec/open_api/root_spec.rb index 44aafaf5..1c2c91e0 100644 --- a/spec/open_api/root_spec.rb +++ b/spec/open_api/root_spec.rb @@ -19,6 +19,7 @@ class RspecApiDocumentation::OpenApi::Info; end its(:definitions) { should be_nil } its(:parameters) { should be_nil } its(:responses) { should be_nil } + its(:paths) { should == {} } its(:securityDefinitions) { should be_nil } its(:security) { should be_nil } its(:tags) { should == [] } From 5749585b1cc02d99042176bde6eed6318a3a408f Mon Sep 17 00:00:00 2001 From: Aaditya Taparia Date: Thu, 6 Dec 2018 19:15:05 +0900 Subject: [PATCH 04/41] Change to open api spec 3.0 --- lib/rspec_api_documentation.rb | 21 ++- .../open_api/components.rb | 13 ++ .../open_api/contact.rb | 6 +- .../open_api/external_docs.rb | 8 + lib/rspec_api_documentation/open_api/flow.rb | 10 + .../open_api/header.rb | 17 +- .../open_api/helper.rb | 2 +- lib/rspec_api_documentation/open_api/info.rb | 8 +- lib/rspec_api_documentation/open_api/media.rb | 10 + lib/rspec_api_documentation/open_api/node.rb | 8 +- .../open_api/operation.rb | 11 +- .../open_api/parameter.rb | 36 ++-- lib/rspec_api_documentation/open_api/path.rb | 1 + .../open_api/request_body.rb | 9 + .../open_api/response.rb | 6 +- lib/rspec_api_documentation/open_api/root.rb | 19 +- .../open_api/schema.rb | 27 ++- .../open_api/security_schema.rb | 14 -- .../open_api/security_scheme.rb | 14 ++ .../open_api/server.rb | 9 + lib/rspec_api_documentation/open_api/tag.rb | 4 +- .../open_api/variable.rb | 9 + .../writers/open_api_writer.rb | 175 +++++++++++------- 23 files changed, 282 insertions(+), 155 deletions(-) create mode 100644 lib/rspec_api_documentation/open_api/components.rb create mode 100644 lib/rspec_api_documentation/open_api/external_docs.rb create mode 100644 lib/rspec_api_documentation/open_api/flow.rb create mode 100644 lib/rspec_api_documentation/open_api/media.rb create mode 100644 lib/rspec_api_documentation/open_api/request_body.rb delete mode 100644 lib/rspec_api_documentation/open_api/security_schema.rb create mode 100644 lib/rspec_api_documentation/open_api/security_scheme.rb create mode 100644 lib/rspec_api_documentation/open_api/server.rb create mode 100644 lib/rspec_api_documentation/open_api/variable.rb diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb index ed413937..0db3d01c 100644 --- a/lib/rspec_api_documentation.rb +++ b/lib/rspec_api_documentation.rb @@ -52,20 +52,27 @@ module Writers module OpenApi extend ActiveSupport::Autoload + autoload :Components + autoload :Contact + autoload :ExternalDocs + autoload :Flow + autoload :Header autoload :Helper - autoload :Node - autoload :Root autoload :Info - autoload :Contact autoload :License - autoload :Path - autoload :Tag + autoload :Media + autoload :Node autoload :Operation autoload :Parameter + autoload :Path + autoload :RequestBody autoload :Response - autoload :Header + autoload :Root autoload :Schema - autoload :SecuritySchema + autoload :SecurityScheme + autoload :Server + autoload :Tag + autoload :Variable end module Views diff --git a/lib/rspec_api_documentation/open_api/components.rb b/lib/rspec_api_documentation/open_api/components.rb new file mode 100644 index 00000000..104fa52f --- /dev/null +++ b/lib/rspec_api_documentation/open_api/components.rb @@ -0,0 +1,13 @@ +module RspecApiDocumentation + module OpenApi + class Components < Node + add_setting :schemas, :schema => { '' => Schema } + add_setting :responses, :schema => { '' => Response } + add_setting :parameters, :schema => { '' => Parameter } + add_setting :headers, :schema => { '' => Header } + add_setting :securitySchemes, :schema => { '' => SecurityScheme } + add_setting :links + add_setting :callbacks + end + end +end diff --git a/lib/rspec_api_documentation/open_api/contact.rb b/lib/rspec_api_documentation/open_api/contact.rb index b6bc3c02..9bd942bb 100644 --- a/lib/rspec_api_documentation/open_api/contact.rb +++ b/lib/rspec_api_documentation/open_api/contact.rb @@ -1,9 +1,9 @@ module RspecApiDocumentation module OpenApi class Contact < Node - add_setting :name, :default => 'API Support' - add_setting :url, :default => 'http://www.open-api.io/support' - add_setting :email, :default => 'support@open-api.io' + add_setting :name + add_setting :url + add_setting :email end end end diff --git a/lib/rspec_api_documentation/open_api/external_docs.rb b/lib/rspec_api_documentation/open_api/external_docs.rb new file mode 100644 index 00000000..e13a8285 --- /dev/null +++ b/lib/rspec_api_documentation/open_api/external_docs.rb @@ -0,0 +1,8 @@ +module RspecApiDocumentation + module OpenApi + class ExternalDocs < Node + add_setting :description + add_setting :url, :required => true + end + end +end diff --git a/lib/rspec_api_documentation/open_api/flow.rb b/lib/rspec_api_documentation/open_api/flow.rb new file mode 100644 index 00000000..83c2b055 --- /dev/null +++ b/lib/rspec_api_documentation/open_api/flow.rb @@ -0,0 +1,10 @@ +module RspecApiDocumentation + module OpenApi + class Flow < Node + add_setting :authorizationUrl, :required => true + add_setting :tokenUrl, :required => true + add_setting :refreshUrl + add_setting :scopes, :required => true + end + end +end diff --git a/lib/rspec_api_documentation/open_api/header.rb b/lib/rspec_api_documentation/open_api/header.rb index 222e2694..e61cb9c4 100644 --- a/lib/rspec_api_documentation/open_api/header.rb +++ b/lib/rspec_api_documentation/open_api/header.rb @@ -1,12 +1,17 @@ module RspecApiDocumentation module OpenApi class Header < Node - add_setting :description, :default => '' - add_setting :type, :required => true, :default => lambda { |header| - Helper.extract_type(header.public_send('x-example-value')) - } - add_setting :format - add_setting 'x-example-value' + add_setting :description + add_setting :required + add_setting :deprecated + # add_setting :allowEmptyValue + # add_setting :style + # add_setting :explode + # add_setting :allowReserved + add_setting :schema, :schema => Schema + add_setting :example + # add_setting :examples, :schema => { '' => Example } + # add_setting :content, :schema => { '' => Media } end end end diff --git a/lib/rspec_api_documentation/open_api/helper.rb b/lib/rspec_api_documentation/open_api/helper.rb index 0e25ad65..83a06a90 100644 --- a/lib/rspec_api_documentation/open_api/helper.rb +++ b/lib/rspec_api_documentation/open_api/helper.rb @@ -16,7 +16,7 @@ def extract_type(value) end def extract_items(value, opts = {}) - result = {type: extract_type(value)} + result = { type: extract_type(value) } if result[:type] == :array result[:items] = extract_items(value[0], opts) else diff --git a/lib/rspec_api_documentation/open_api/info.rb b/lib/rspec_api_documentation/open_api/info.rb index ff4c934a..4c295d65 100644 --- a/lib/rspec_api_documentation/open_api/info.rb +++ b/lib/rspec_api_documentation/open_api/info.rb @@ -2,10 +2,10 @@ module RspecApiDocumentation module OpenApi class Info < Node add_setting :title, :default => 'OpenAPI Specification', :required => true - add_setting :description, :default => 'This is a sample server Petstore server.' - add_setting :termsOfService, :default => 'http://open-api.io/terms/' - add_setting :contact, :default => Contact.new, :schema => Contact - add_setting :license, :default => License.new, :schema => License + add_setting :description + add_setting :termsOfService + add_setting :contact, :schema => Contact + add_setting :license, :schema => License add_setting :version, :default => '1.0.0', :required => true end end diff --git a/lib/rspec_api_documentation/open_api/media.rb b/lib/rspec_api_documentation/open_api/media.rb new file mode 100644 index 00000000..6b7c5feb --- /dev/null +++ b/lib/rspec_api_documentation/open_api/media.rb @@ -0,0 +1,10 @@ +module RspecApiDocumentation + module OpenApi + class Media < Node + add_setting :schema, :schema => Schema + add_setting :example + # add_setting :examples, :schema => { '' => Example } + # add_setting :encoding, :schema => { '' => Encoding } + end + end +end diff --git a/lib/rspec_api_documentation/open_api/node.rb b/lib/rspec_api_documentation/open_api/node.rb index 8830a319..920b7950 100644 --- a/lib/rspec_api_documentation/open_api/node.rb +++ b/lib/rspec_api_documentation/open_api/node.rb @@ -64,7 +64,13 @@ def add_setting(name, opts = {}) settings[name] = opts[:value] if opts[:value] define_singleton_method("#{name}_schema") { opts[:schema] || NilClass } - define_singleton_method("#{name}=") { |value| settings[name] = value } + define_singleton_method("#{name}=") do |value| + if setting[name].is_a?(Hash) && value.is_a?(Hash) + value.each { |k, v| setting[name][k] = setting[name][k] ? setting[name][k].merge(v) : v } + else + settings[name] = value + end + end define_singleton_method("#{name}") do if settings.has_key?(name) settings[name] diff --git a/lib/rspec_api_documentation/open_api/operation.rb b/lib/rspec_api_documentation/open_api/operation.rb index 5c6f6986..b7713e0f 100644 --- a/lib/rspec_api_documentation/open_api/operation.rb +++ b/lib/rspec_api_documentation/open_api/operation.rb @@ -4,15 +4,14 @@ class Operation < Node add_setting :tags, :default => [] add_setting :summary add_setting :description - add_setting :externalDocs - add_setting :operationId - add_setting :consumes - add_setting :produces + add_setting :externalDocs, :schema => ExternalDocs + # add_setting :operationId add_setting :parameters, :default => [], :schema => [Parameter] - add_setting :responses, :required => true, :schema => { String => Response } - add_setting :schemes + add_setting :requestBody, :schema => RequestBody + add_setting :responses, :required => true, :schema => { '' => Response } add_setting :deprecated, :default => false add_setting :security + # add_setting :servers, :schema => [Server] end end end diff --git a/lib/rspec_api_documentation/open_api/parameter.rb b/lib/rspec_api_documentation/open_api/parameter.rb index d16c5473..e8c1c370 100644 --- a/lib/rspec_api_documentation/open_api/parameter.rb +++ b/lib/rspec_api_documentation/open_api/parameter.rb @@ -1,33 +1,19 @@ module RspecApiDocumentation module OpenApi class Parameter < Node - # Required to write example values to description of parameter when option `with_example: true` is provided - attr_accessor :value - attr_accessor :with_example - add_setting :name, :required => true add_setting :in, :required => true - add_setting :description, :default => '' - add_setting :required, :default => lambda { |parameter| parameter.in.to_s == 'path' ? true : false } - add_setting :schema - add_setting :type - add_setting :items - add_setting :default - add_setting :minimum - add_setting :maximum - add_setting :enum - - def description_with_example - str = description_without_example.dup || '' - if with_example && value - str << "\n" unless str.empty? - str << "Eg, `#{value}`" - end - str - end - - alias_method :description_without_example, :description - alias_method :description, :description_with_example + add_setting :description + add_setting :required, :default => lambda { |parameter| parameter.in.to_s == 'path' } + add_setting :deprecated + # add_setting :allowEmptyValue + # add_setting :style + # add_setting :explode + # add_setting :allowReserved + add_setting :schema, :schema => Schema + add_setting :example + # add_setting :examples, :schema => { '' => Example } + # add_setting :content, :schema => { '' => Media } end end end diff --git a/lib/rspec_api_documentation/open_api/path.rb b/lib/rspec_api_documentation/open_api/path.rb index 241bba8c..158ec616 100644 --- a/lib/rspec_api_documentation/open_api/path.rb +++ b/lib/rspec_api_documentation/open_api/path.rb @@ -8,6 +8,7 @@ class Path < Node add_setting :options, :schema => Operation add_setting :head, :schema => Operation add_setting :patch, :schema => Operation + add_setting :trace, :schema => Operation end end end diff --git a/lib/rspec_api_documentation/open_api/request_body.rb b/lib/rspec_api_documentation/open_api/request_body.rb new file mode 100644 index 00000000..00fc63c0 --- /dev/null +++ b/lib/rspec_api_documentation/open_api/request_body.rb @@ -0,0 +1,9 @@ +module RspecApiDocumentation + module OpenApi + class RequestBody < Node + add_setting :description, :default => 'body' + add_setting :content, :required => true, :schema => { '' => Media } + add_setting :required, :default => false + end + end +end diff --git a/lib/rspec_api_documentation/open_api/response.rb b/lib/rspec_api_documentation/open_api/response.rb index ba379ea1..04887a46 100644 --- a/lib/rspec_api_documentation/open_api/response.rb +++ b/lib/rspec_api_documentation/open_api/response.rb @@ -2,9 +2,9 @@ module RspecApiDocumentation module OpenApi class Response < Node add_setting :description, :required => true, :default => 'Successful operation' - add_setting :schema, :schema => Schema - add_setting :headers, :schema => { String => Header } - add_setting :examples + add_setting :headers, :schema => { '' => Header } + add_setting :content, :schema => { '' => Media } + # add_setting :links end end end diff --git a/lib/rspec_api_documentation/open_api/root.rb b/lib/rspec_api_documentation/open_api/root.rb index 420fb630..b02f61e0 100644 --- a/lib/rspec_api_documentation/open_api/root.rb +++ b/lib/rspec_api_documentation/open_api/root.rb @@ -1,21 +1,14 @@ module RspecApiDocumentation module OpenApi class Root < Node - add_setting :swagger, :default => '2.0', :required => true + add_setting :openapi, :default => '3.0.0', :required => true add_setting :info, :default => Info.new, :required => true, :schema => Info - add_setting :host, :default => 'localhost:3000' - add_setting :basePath - add_setting :schemes, :default => %w(http https) - add_setting :consumes, :default => %w(application/json application/xml) - add_setting :produces, :default => %w(application/json application/xml) - add_setting :paths, :default => {}, :required => true, :schema => { String => Path } - add_setting :definitions - add_setting :parameters - add_setting :responses - add_setting :securityDefinitions, :schema => { String => SecuritySchema } + add_setting :servers, :schema => [Server] + add_setting :paths, :default => { '/' => Path.new }, :required => true, :schema => { '' => Path } + add_setting :components, :schema => Components add_setting :security - add_setting :tags, :default => [], :schema => [Tag] - add_setting :externalDocs + add_setting :tags, :schema => [Tag] + add_setting :externalDocs, :schema => ExternalDocs end end end diff --git a/lib/rspec_api_documentation/open_api/schema.rb b/lib/rspec_api_documentation/open_api/schema.rb index c632c12f..7f3d186c 100644 --- a/lib/rspec_api_documentation/open_api/schema.rb +++ b/lib/rspec_api_documentation/open_api/schema.rb @@ -1,15 +1,36 @@ module RspecApiDocumentation module OpenApi class Schema < Node - add_setting :format add_setting :title - add_setting :description, :default => '' + add_setting :multipleOf + add_setting :maximum + add_setting :exclusiveMaximum + add_setting :minimum + add_setting :exclusiveMinimum + add_setting :maxLength + add_setting :minLength + add_setting :pattern + add_setting :maxItems + add_setting :minItems + add_setting :uniqueItems + add_setting :maxProperties + add_setting :minProperties add_setting :required add_setting :enum add_setting :type + add_setting :allOf, :schema => [Schema] + add_setting :oneOf, :schema => [Schema] + add_setting :anyOf, :schema => [Schema] + add_setting :not, :schema => [Schema] add_setting :items - add_setting :properties + add_setting :properties, :schema => { '' => Schema } + add_setting :description + add_setting :format add_setting :example + add_setting :externalDocs, :schema => ExternalDocs + add_setting :nullable + add_setting :deprecated + add_setting :discriminator end end end diff --git a/lib/rspec_api_documentation/open_api/security_schema.rb b/lib/rspec_api_documentation/open_api/security_schema.rb deleted file mode 100644 index a1ba5f05..00000000 --- a/lib/rspec_api_documentation/open_api/security_schema.rb +++ /dev/null @@ -1,14 +0,0 @@ -module RspecApiDocumentation - module OpenApi - class SecuritySchema < Node - add_setting :type, :required => true - add_setting :description, :default => '' - add_setting :name - add_setting :in - add_setting :flow - add_setting :authorizationUrl - add_setting :tokenUrl - add_setting :scopes - end - end -end diff --git a/lib/rspec_api_documentation/open_api/security_scheme.rb b/lib/rspec_api_documentation/open_api/security_scheme.rb new file mode 100644 index 00000000..aae46019 --- /dev/null +++ b/lib/rspec_api_documentation/open_api/security_scheme.rb @@ -0,0 +1,14 @@ +module RspecApiDocumentation + module OpenApi + class SecurityScheme < Node + add_setting :type, :required => true + add_setting :description + add_setting :name + add_setting :in + add_setting :scheme + add_setting :bearerFormat + add_setting :flows, :schema => { '' => Flow } + add_setting :openIdConnectUrl + end + end +end diff --git a/lib/rspec_api_documentation/open_api/server.rb b/lib/rspec_api_documentation/open_api/server.rb new file mode 100644 index 00000000..11ffe8a7 --- /dev/null +++ b/lib/rspec_api_documentation/open_api/server.rb @@ -0,0 +1,9 @@ +module RspecApiDocumentation + module OpenApi + class Server < Node + add_setting :url, :required => true + add_setting :description + add_setting :variables, :schema => { '' => Variable } + end + end +end diff --git a/lib/rspec_api_documentation/open_api/tag.rb b/lib/rspec_api_documentation/open_api/tag.rb index 6c8a82d8..5a1e8422 100644 --- a/lib/rspec_api_documentation/open_api/tag.rb +++ b/lib/rspec_api_documentation/open_api/tag.rb @@ -2,8 +2,8 @@ module RspecApiDocumentation module OpenApi class Tag < Node add_setting :name, :required => true - add_setting :description, :default => '' - add_setting :externalDocs + add_setting :description + # add_setting :externalDocs, :schema => ExternalDocs end end end diff --git a/lib/rspec_api_documentation/open_api/variable.rb b/lib/rspec_api_documentation/open_api/variable.rb new file mode 100644 index 00000000..7f7947bf --- /dev/null +++ b/lib/rspec_api_documentation/open_api/variable.rb @@ -0,0 +1,9 @@ +module RspecApiDocumentation + module OpenApi + class Variable < Node + add_setting :enum + add_setting :default, :required => true + add_setting :description + end + end +end diff --git a/lib/rspec_api_documentation/writers/open_api_writer.rb b/lib/rspec_api_documentation/writers/open_api_writer.rb index 9552dada..ddae4ad5 100644 --- a/lib/rspec_api_documentation/writers/open_api_writer.rb +++ b/lib/rspec_api_documentation/writers/open_api_writer.rb @@ -33,9 +33,10 @@ def initialize(index, configuration, init_config) def as_json @specs = OpenApi::Root.new(init_config) + add_components! add_tags! add_paths! - add_security_definitions! + add_security_schemes! specs.as_json end @@ -47,8 +48,12 @@ def examples index.examples.map { |example| OpenApiExample.new(example) } end - def add_security_definitions! - security_definitions = {} + def add_components! + specs.safe_assign_setting(:components, OpenApi::Components.new) + end + + def add_security_schemes! + security_schemes = {} arr = examples.map do |example| example.respond_to?(:authentications) ? example.authentications : nil @@ -56,16 +61,16 @@ def add_security_definitions! arr.each do |securities| securities.each do |security, opts| - schema = OpenApi::SecuritySchema.new( + schema = OpenApi::SecurityScheme.new( name: opts[:name], description: opts[:description], type: opts[:type], in: opts[:in] ) - security_definitions[security.to_s] = schema + security_schemes[security.to_s] = schema end end - specs.securityDefinitions = security_definitions unless arr.empty? + specs.components.safe_assign_setting(:securitySchemes, security_schemes) unless arr.empty? end def add_tags! @@ -88,12 +93,13 @@ def add_paths! operation = specs.paths[route].setting(example.http_method) || OpenApi::Operation.new operation.safe_assign_setting(:tags, [example.resource_name]) - operation.safe_assign_setting(:summary, example.respond_to?(:route_summary) ? example.route_summary : '') - operation.safe_assign_setting(:description, example.respond_to?(:route_description) ? example.route_description : '') + operation.safe_assign_setting(:summary, example.route_summary) if example.respond_to?(:route_summary) + operation.safe_assign_setting(:description, example.route_description) if example.respond_to?(:route_description) + operation.safe_assign_setting(:externalDocs, OpenApi::ExternalDocs.new(url: example.external_docs)) if example.respond_to?(:external_docs) operation.safe_assign_setting(:responses, {}) + operation.safe_assign_setting(:deprecated, example.deprecated) if example.respond_to?(:deprecated) operation.safe_assign_setting(:parameters, extract_parameters(example)) - operation.safe_assign_setting(:consumes, example.requests.map { |request| request[:request_content_type] }.compact.map { |q| q[/[^;]+/] }) - operation.safe_assign_setting(:produces, example.requests.map { |request| request[:response_content_type] }.compact.map { |q| q[/[^;]+/] }) + operation.safe_assign_setting(:requestBody, extract_request_body(example)) operation.safe_assign_setting(:security, example.respond_to?(:authentications) ? example.authentications.map { |(k, _)| {k => []} } : []) process_responses(operation.responses, example) @@ -103,62 +109,111 @@ def add_paths! end def process_responses(responses, example) - schema = extract_schema(example.respond_to?(:response_fields) ? example.response_fields : []) + schema = extract_schema(example.respond_to?(:response_fields) ? example.response_fields : nil) example.requests.each do |request| response = OpenApi::Response.new( - description: example.description, - schema: schema + description: example.description ) if request[:response_headers] response.safe_assign_setting(:headers, {}) request[:response_headers].each do |header, value| - response.headers[header.to_s] = OpenApi::Header.new('x-example-value' => value) + response.headers[header.to_s] = OpenApi::Header.new(schema: OpenApi::Schema.new(type: 'string'), example: value) end end + response_body = JSON.parse(request[:response_body]) rescue nil if /\A(?[^;]+)/ =~ request[:response_content_type] - response.safe_assign_setting(:examples, {}) - response_body = JSON.parse(request[:response_body]) rescue nil - response.examples[response_content_type.to_s] = response_body if response_body + content_type = response_content_type.to_s + else + content_type = 'application/json' + end + + if response_body + response.safe_assign_setting(:content, { + content_type => OpenApi::Media.new(schema: schema || get_schema(response_body), example: response_body) + }) end + responses[request[:response_status].to_s] = response end end def extract_schema(fields) - schema = {type: 'object', properties: {}} + return nil if fields.nil? + + schema = { type: 'object', properties: {} } fields.each do |field| current = schema if field[:scope] [*field[:scope]].each do |scope| - current[:properties][scope] ||= {type: 'object', properties: {}} + current[:properties][scope] ||= { type: 'object', properties: {} } current = current[:properties][scope] end end - current[:properties][field[:name]] = {type: field[:type] || OpenApi::Helper.extract_type(field[:value])} + current[:properties][field[:name]] = { type: field[:type] || OpenApi::Helper.extract_type(field[:value]) } current[:properties][field[:name]][:example] = field[:value] if field[:value] && field[:with_example] - current[:properties][field[:name]][:default] = field[:default] if field[:default] - current[:properties][field[:name]][:description] = field[:description] if field[:description] - opts = {enum: field[:enum], minimum: field[:minimum], maximum: field[:maximum]} + opts = { + description: field[:description], + default: field[:default], + enum: field[:enum], + minimum: field[:minimum], + maximum: field[:maximum], + required: field[:required], + nullable: field[:nullable] || field[:value].nil? || nil + } if current[:properties][field[:name]][:type] == :array current[:properties][field[:name]][:items] = field[:items] || OpenApi::Helper.extract_items(field[:value][0], opts) else opts.each { |k, v| current[:properties][field[:name]][k] = v if v } end - - current[:required] ||= [] << field[:name] if field[:required] end OpenApi::Schema.new(schema) end + def get_schema(field) + type = OpenApi::Helper.extract_type(field).to_s + case type + when 'object' + OpenApi::Schema.new(type: type, properties: Hash[field.map { |k, v| [k, get_schema(v)] }]) + when 'array' + OpenApi::Schema.new(type: type, items: get_schema(field[0])) + else + OpenApi::Schema.new(type: type, example: field, nullable: field.nil? || nil) + end + end + def extract_parameters(example) - extract_known_parameters(example.extended_parameters.select { |p| !p[:in].nil? }) + - extract_unknown_parameters(example, example.extended_parameters.select { |p| p[:in].nil? }) + known_parameters = extract_known_parameters(example.extended_parameters.reject { |p| p[:in].nil? }) + known_param_names = known_parameters.map { |p| p.name } + unknown_parameters = extract_unknown_parameters(example).reject { |p| known_param_names.include?(p.name) } + known_parameters + unknown_parameters + end + + def extract_request_body(example) + if example.respond_to?(:request_body) + OpenApi::RequestBody.new( + content: { + example.request_body[:type] || 'application/json' => OpenApi::Media.new( + schema: OpenApi::Schema.new(example.request_body[:schema]), + example: example.request_body[:example] + ) + } + ) + else + body = example.requests.map { |req| JSON.parse(req[:request_body]) rescue nil }.compact.reduce({}, :merge) + return nil if body.empty? + + OpenApi::RequestBody.new( + content: { + 'application/json' => OpenApi::Media.new(schema: get_schema(body), example: body) + } + ) + end end def extract_parameter(opts) @@ -167,52 +222,38 @@ def extract_parameter(opts) in: opts[:in], description: opts[:description], required: opts[:required], - type: opts[:type] || OpenApi::Helper.extract_type(opts[:value]), - value: opts[:value], - with_example: opts[:with_example], - default: opts[:default], - ).tap do |elem| - if elem.type == :array - elem.items = opts[:items] || OpenApi::Helper.extract_items(opts[:value][0], { minimum: opts[:minimum], maximum: opts[:maximum], enum: opts[:enum] }) - else - elem.minimum = opts[:minimum] - elem.maximum = opts[:maximum] - elem.enum = opts[:enum] - end - end + deprecated: opts[:deprecated], + schema: opts[:schema] || get_schema(opts[:value]), + example: opts[:value] + ) end - def extract_unknown_parameters(example, parameters) - if example.http_method == :get - parameters.map { |parameter| extract_parameter(parameter.merge(in: :query)) } - elsif parameters.any? { |parameter| !parameter[:scope].nil? } - [OpenApi::Parameter.new( - name: :body, - in: :body, - description: '', - schema: extract_schema(parameters) - )] - else - parameters.map { |parameter| extract_parameter(parameter.merge(in: :formData)) } + def extract_unknown_parameters(example) + parameters = [] + example.requests.each do |req| + req[:request_query_parameters].each do |name, value| + parameters.push(OpenApi::Parameter.new( + name: name, + in: :query, + schema: get_schema(value), + example: value + )) + end + req[:request_headers].each do |name, value| + parameters.push(OpenApi::Parameter.new( + name: name, + in: :header, + schema: get_schema(value), + example: value + )) + end end + parameters end def extract_known_parameters(parameters) - result = parameters.select { |parameter| %w(query path header formData).include?(parameter[:in].to_s) } - .map { |parameter| extract_parameter(parameter) } - - body = parameters.select { |parameter| %w(body).include?(parameter[:in].to_s) } - - result.unshift( - OpenApi::Parameter.new( - name: :body, - in: :body, - description: '', - schema: extract_schema(body) - ) - ) unless body.empty? - - result + parameters.select { |parameter| %w(query path header cookie).include?(parameter[:in].to_s) } + .map { |parameter| extract_parameter(parameter) } end end From ce261dd2e6976ef133164ec586f00ae867a54eed Mon Sep 17 00:00:00 2001 From: Jake Howerton Date: Fri, 3 May 2019 20:23:51 -0500 Subject: [PATCH 05/41] add warning for `config.docs_dir` --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index df541bd5..5a1113f3 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,7 @@ RspecApiDocumentation.configure do |config| config.configurations_dir = Rails.root.join("doc", "configurations", "api") # Output folder + # **WARNING*** All contents of the configured directory will be cleared, use a dedicated directory. config.docs_dir = Rails.root.join("doc", "api") # An array of output format(s). @@ -238,6 +239,7 @@ RspecApiDocumentation.configure do |config| config.define_group :public do |config| # By default the group's doc_dir is a subfolder under the parent group, based # on the group's name. + # **WARNING*** All contents of the configured directory will be cleared, use a dedicated directory. config.docs_dir = Rails.root.join("doc", "api", "public") # Change the filter to only include :public examples From ca1ded5e42ff707dfc4512a66f13f973333e3c9d Mon Sep 17 00:00:00 2001 From: David Stosik Date: Thu, 6 Feb 2020 17:14:41 +0900 Subject: [PATCH 06/41] Clean up Gemfile stuff - Untrack Gemfile.lock - Move `inch` gem from Gemfile to development dependency in gemspec Details: https://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ --- .gitignore | 1 + Gemfile | 2 - Gemfile.lock | 160 -------------------------------- rspec_api_documentation.gemspec | 1 + 4 files changed, 2 insertions(+), 162 deletions(-) delete mode 100644 Gemfile.lock diff --git a/.gitignore b/.gitignore index 1063635d..e4bf1377 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ example/public/docs *.swp /html/ /.idea +Gemfile.lock diff --git a/Gemfile b/Gemfile index 04bc0b1a..d65e2a66 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,3 @@ source 'http://rubygems.org' gemspec - -gem 'inch' diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 6e8db2a9..00000000 --- a/Gemfile.lock +++ /dev/null @@ -1,160 +0,0 @@ -PATH - remote: . - specs: - rspec_api_documentation (6.1.0) - activesupport (>= 3.0.0) - mustache (~> 1.0, >= 0.99.4) - rspec (~> 3.0) - -GEM - remote: http://rubygems.org/ - specs: - activesupport (4.2.5.1) - i18n (~> 0.7) - json (~> 1.7, >= 1.7.7) - minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) - tzinfo (~> 1.1) - addressable (2.4.0) - aruba (0.13.0) - childprocess (~> 0.5.6) - contracts (~> 0.9) - cucumber (>= 1.3.19) - ffi (~> 1.9.10) - rspec-expectations (>= 2.99) - thor (~> 0.19) - attr_required (1.0.1) - builder (3.2.2) - capybara (2.6.2) - addressable - mime-types (>= 1.16) - nokogiri (>= 1.3.3) - rack (>= 1.0.0) - rack-test (>= 0.5.4) - xpath (~> 2.0) - childprocess (0.5.9) - ffi (~> 1.0, >= 1.0.11) - coderay (1.1.2) - contracts (0.13.0) - crack (0.4.3) - safe_yaml (~> 1.0.0) - cucumber (2.3.2) - builder (>= 2.1.2) - cucumber-core (~> 1.4.0) - cucumber-wire (~> 0.0.1) - diff-lcs (>= 1.1.3) - gherkin (~> 3.2.0) - multi_json (>= 1.7.5, < 2.0) - multi_test (>= 0.1.2) - cucumber-core (1.4.0) - gherkin (~> 3.2.0) - cucumber-wire (0.0.1) - daemons (1.2.3) - diff-lcs (1.2.5) - eventmachine (1.0.9.1) - fakefs (0.6.0) - faraday (0.9.2) - multipart-post (>= 1.2, < 3) - ffi (1.9.10) - gherkin (3.2.0) - hashdiff (0.2.3) - httpclient (2.7.1) - i18n (0.7.0) - inch (0.8.0) - pry - sparkr (>= 0.2.0) - term-ansicolor - yard (~> 0.9.12) - json (1.8.6) - method_source (0.9.0) - mime-types (3.0) - mime-types-data (~> 3.2015) - mime-types-data (3.2015.1120) - mini_portile2 (2.3.0) - minitest (5.8.4) - multi_json (1.11.2) - multi_test (0.1.2) - multipart-post (2.0.0) - mustache (1.0.5) - nokogiri (1.8.4) - mini_portile2 (~> 2.3.0) - pry (0.11.3) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - rack (1.6.4) - rack-oauth2 (1.2.2) - activesupport (>= 2.3) - attr_required (>= 0.0.5) - httpclient (>= 2.4) - multi_json (>= 1.3.6) - rack (>= 1.1) - rack-protection (1.5.3) - rack - rack-test (0.6.3) - rack (>= 1.0) - rake (10.5.0) - rspec (3.4.0) - rspec-core (~> 3.4.0) - rspec-expectations (~> 3.4.0) - rspec-mocks (~> 3.4.0) - rspec-core (3.4.2) - rspec-support (~> 3.4.0) - rspec-expectations (3.4.0) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) - rspec-its (1.2.0) - rspec-core (>= 3.0.0) - rspec-expectations (>= 3.0.0) - rspec-mocks (3.4.1) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) - rspec-support (3.4.1) - safe_yaml (1.0.4) - sinatra (1.4.7) - rack (~> 1.5) - rack-protection (~> 1.4) - tilt (>= 1.3, < 3) - sparkr (0.4.1) - term-ansicolor (1.6.0) - tins (~> 1.0) - thin (1.6.4) - daemons (~> 1.0, >= 1.0.9) - eventmachine (~> 1.0, >= 1.0.4) - rack (~> 1.0) - thor (0.19.1) - thread_safe (0.3.5) - tilt (2.0.2) - tins (1.16.3) - tzinfo (1.2.2) - thread_safe (~> 0.1) - webmock (1.22.6) - addressable (>= 2.3.6) - crack (>= 0.3.2) - hashdiff - xpath (2.0.0) - nokogiri (~> 1.3) - yard (0.9.15) - -PLATFORMS - ruby - -DEPENDENCIES - aruba (~> 0.5) - bundler (~> 1.0) - capybara (~> 2.2) - fakefs (~> 0.4) - faraday (~> 0.9, >= 0.9.0) - inch - nokogiri (~> 1.8, >= 1.8.2) - rack-oauth2 (~> 1.2.2, >= 1.0.7) - rack-test (~> 0.6.2) - rake (~> 10.1) - rspec-its (~> 1.0) - rspec_api_documentation! - sinatra (~> 1.4, >= 1.4.4) - thin (~> 1.6, >= 1.6.3) - webmock (~> 1.7) - yard (>= 0.9.11) - -BUNDLED WITH - 1.16.4 diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 9590586a..e03d9204 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -32,6 +32,7 @@ Gem::Specification.new do |s| s.add_development_dependency "thin", "~> 1.6", ">= 1.6.3" s.add_development_dependency "nokogiri", "~> 1.8", ">= 1.8.2" s.add_development_dependency "yard", ">= 0.9.11" + s.add_development_dependency "inch", "~> 0.8.0" s.files = Dir.glob("lib/**/*") + Dir.glob("templates/**/*") s.require_path = "lib" From 2c5d811b828def0f4793c796370cf0569d711d0b Mon Sep 17 00:00:00 2001 From: David Stosik Date: Thu, 6 Feb 2020 17:21:42 +0900 Subject: [PATCH 07/41] Relax Bundler dependency --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index e03d9204..8ea93e0e 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency "activesupport", ">= 3.0.0" s.add_runtime_dependency "mustache", "~> 1.0", ">= 0.99.4" - s.add_development_dependency "bundler", "~> 1.0" + s.add_development_dependency "bundler", ">= 1.16" s.add_development_dependency "fakefs", "~> 0.4" s.add_development_dependency "sinatra", "~> 1.4", ">= 1.4.4" s.add_development_dependency "aruba", "~> 0.5" From 65ee9735a50b159d2b8137160201a11d61719e40 Mon Sep 17 00:00:00 2001 From: David Stosik Date: Thu, 6 Feb 2020 17:29:14 +0900 Subject: [PATCH 08/41] Freeze development dependencies while we figure out what breaks --- rspec_api_documentation.gemspec | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 8ea93e0e..674bd21c 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -19,19 +19,19 @@ Gem::Specification.new do |s| s.add_runtime_dependency "mustache", "~> 1.0", ">= 0.99.4" s.add_development_dependency "bundler", ">= 1.16" - s.add_development_dependency "fakefs", "~> 0.4" - s.add_development_dependency "sinatra", "~> 1.4", ">= 1.4.4" - s.add_development_dependency "aruba", "~> 0.5" - s.add_development_dependency "capybara", "~> 2.2" - s.add_development_dependency "rake", "~> 10.1" - s.add_development_dependency "rack-test", "~> 0.6.2" - s.add_development_dependency "rack-oauth2", "~> 1.2.2", ">= 1.0.7" - s.add_development_dependency "webmock", "~> 1.7" - s.add_development_dependency "rspec-its", "~> 1.0" - s.add_development_dependency "faraday", "~> 0.9", ">= 0.9.0" - s.add_development_dependency "thin", "~> 1.6", ">= 1.6.3" - s.add_development_dependency "nokogiri", "~> 1.8", ">= 1.8.2" - s.add_development_dependency "yard", ">= 0.9.11" + s.add_development_dependency "fakefs", "~> 0.6.0" + s.add_development_dependency "sinatra", "~> 1.4.7" + s.add_development_dependency "aruba", "~> 0.13.0" + s.add_development_dependency "capybara", "~> 2.6.2" + s.add_development_dependency "rake", "~> 10.5.0" + s.add_development_dependency "rack-test", "~> 0.6.3" + s.add_development_dependency "rack-oauth2", "~> 1.2.2" + s.add_development_dependency "webmock", "~> 1.22.6" + s.add_development_dependency "rspec-its", "~> 1.2.0" + s.add_development_dependency "faraday", "~> 0.9.2" + s.add_development_dependency "thin", "~> 1.6.4" + s.add_development_dependency "nokogiri", "~> 1.8.4" + s.add_development_dependency "yard", "~> 0.9.15" s.add_development_dependency "inch", "~> 0.8.0" s.files = Dir.glob("lib/**/*") + Dir.glob("templates/**/*") From 2770148d69a5363f71f4c0aadc430d0d11c828f7 Mon Sep 17 00:00:00 2001 From: David Stosik Date: Thu, 6 Feb 2020 17:39:27 +0900 Subject: [PATCH 09/41] Freeze more development dependencies to get a green CI --- rspec_api_documentation.gemspec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 674bd21c..f1a67b33 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -33,6 +33,11 @@ Gem::Specification.new do |s| s.add_development_dependency "nokogiri", "~> 1.8.4" s.add_development_dependency "yard", "~> 0.9.15" s.add_development_dependency "inch", "~> 0.8.0" + s.add_development_dependency "minitest", "~> 5.8.4" + s.add_development_dependency "contracts", "~> 0.13.0" + s.add_development_dependency "gherkin", "~> 3.2.0" + s.add_development_dependency "multi_json", "~> 1.11.2" + s.add_development_dependency "rspec", "~> 3.4.0" s.files = Dir.glob("lib/**/*") + Dir.glob("templates/**/*") s.require_path = "lib" From b0e58898c7868e716c87a404dac3b2e44f1e7ee6 Mon Sep 17 00:00:00 2001 From: David Stosik Date: Fri, 2 Oct 2020 11:47:31 +0900 Subject: [PATCH 10/41] Allow response_body_formatter config to format "binary" responses (#458) * Allow response_body_formatter config to format "binary" responses Following this issue on Rack's repository: [Fix incorrect MockResponse#body String encoding](https://github.com/rack/rack/pull/1486), it looks like we can expect, from now on, that Rack's `response_body` encoding will be `Encoding::ASCII_8BIT`: > I think the response body should probably always be ASCII-8BIT. Rack can't really know anything about the encoding of the bytes that users want to send. At the end of the day, it's just bytes written to the socket, and I don't think Rack should have any opinion about the encoding the user sends. Therefore, `rspec_api_documentation` cannot rely on `response_body.encoding` to determine whether the response is binary data or not. This line becomes incorrect: https://github.com/zipmark/rspec_api_documentation/blob/81e5c563ce6787f143cf775c64e2bd08c35d3585/lib/rspec_api_documentation/client_base.rb#L90-L91 The real fix would be to figure out a better way to define whether a string is binary or not, but I believe this is a bit outside the scope of my knowledge. In this PR, I'm focusing on giving any application using the `rspec_api_documentation` the choice on how to process the response_body, and particularly on how to detect binary data, while not altering `rspec_api_documentation`'s default behaviour. As an additional benefit, this change would allow an application to display friendlier responses in the documentation for some binary types. For example, PNG data: ```rb Proc.new do |content_type, response_body| # http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature if response_body[0,8] == "\x89PNG\r\n\u001A\n" "" elsif content_type =~ /application\/.*json/ JSON.pretty_generate(JSON.parse(response_body)) else response_body end end ``` * Update README.md Co-Authored-By: Benjamin Fleischer --- README.md | 3 ++- lib/rspec_api_documentation/client_base.rb | 9 +++------ lib/rspec_api_documentation/configuration.rb | 4 +++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d96d961f..bedc7ac7 100644 --- a/README.md +++ b/README.md @@ -252,7 +252,8 @@ RspecApiDocumentation.configure do |config| # Change how the response body is formatted by default # Is proc that will be called with the response_content_type & response_body - # by default response_content_type of `application/json` are pretty formated. + # by default, a response body that is likely to be binary is replaced with the string + # "[binary data]" regardless of the media type. Otherwise, a response_content_type of `application/json` is pretty formatted. config.response_body_formatter = Proc.new { |response_content_type, response_body| response_body } # Change the embedded style for HTML output. This file will not be processed by diff --git a/lib/rspec_api_documentation/client_base.rb b/lib/rspec_api_documentation/client_base.rb index d234391b..db0560a3 100644 --- a/lib/rspec_api_documentation/client_base.rb +++ b/lib/rspec_api_documentation/client_base.rb @@ -87,12 +87,9 @@ def headers(method, path, params, request_headers) def record_response_body(response_content_type, response_body) return nil if response_body.empty? - if response_body.encoding == Encoding::ASCII_8BIT - "[binary data]" - else - formatter = RspecApiDocumentation.configuration.response_body_formatter - return formatter.call(response_content_type, response_body) - end + + formatter = RspecApiDocumentation.configuration.response_body_formatter + formatter.call(response_content_type, response_body) end def clean_out_uploaded_data(params, request_body) diff --git a/lib/rspec_api_documentation/configuration.rb b/lib/rspec_api_documentation/configuration.rb index 55054cb6..cd50524f 100644 --- a/lib/rspec_api_documentation/configuration.rb +++ b/lib/rspec_api_documentation/configuration.rb @@ -118,7 +118,9 @@ def self.add_setting(name, opts = {}) # See RspecApiDocumentation::DSL::Endpoint#do_request add_setting :response_body_formatter, default: Proc.new { |_, _| Proc.new do |content_type, response_body| - if content_type =~ /application\/.*json/ + if response_body.encoding == Encoding::ASCII_8BIT + "[binary data]" + elsif content_type =~ /application\/.*json/ JSON.pretty_generate(JSON.parse(response_body)) else response_body From 2e469c48b6004c4a035f0e1ee5c51de981150433 Mon Sep 17 00:00:00 2001 From: David Stosik Date: Fri, 2 Oct 2020 15:50:54 +0900 Subject: [PATCH 11/41] Remove dev dependency to Thin (#479) This change is part of preliminary efforts at attempting to refresh the Continuous Integration setup, by supporting recent Ruby version and updating dependencies. To be honest, I don't know what benefits the Thin server brings to the table. I tried digging in the code, but the commit that introduced it does not tell me much: cdeea8b. What I know however is that I have troubles running the specs locally, getting a timeout on this line: https://github.com/zipmark/rspec_api_documentation/blob/560c3bdc7bd5581e7c223334390221ecfc910be8/spec/http_test_client_spec.rb#L16 However, letting Capybara handle its server details, as shown in this PR, does not seem to have any negative impact (spec is still green, and fairly fast). --- rspec_api_documentation.gemspec | 1 - spec/http_test_client_spec.rb | 7 ------- 2 files changed, 8 deletions(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index f1a67b33..59bb5128 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -29,7 +29,6 @@ Gem::Specification.new do |s| s.add_development_dependency "webmock", "~> 1.22.6" s.add_development_dependency "rspec-its", "~> 1.2.0" s.add_development_dependency "faraday", "~> 0.9.2" - s.add_development_dependency "thin", "~> 1.6.4" s.add_development_dependency "nokogiri", "~> 1.8.4" s.add_development_dependency "yard", "~> 0.9.15" s.add_development_dependency "inch", "~> 0.8.0" diff --git a/spec/http_test_client_spec.rb b/spec/http_test_client_spec.rb index e2282371..f93b549e 100644 --- a/spec/http_test_client_spec.rb +++ b/spec/http_test_client_spec.rb @@ -9,13 +9,6 @@ describe RspecApiDocumentation::HttpTestClient do before(:all) do WebMock.allow_net_connect! - - Capybara.server do |app, port| - require 'rack/handler/thin' - Thin::Logging.silent = true - Rack::Handler::Thin.run(app, :Port => port) - end - server = Capybara::Server.new(StubApp.new, 8888) server.boot end From 66a253a450efba8ac785193454d3213aa2de7352 Mon Sep 17 00:00:00 2001 From: David Stosik Date: Sat, 3 Oct 2020 02:25:55 +0900 Subject: [PATCH 12/41] Remove deprecated key in .travis.yml (#482) > `root`: deprecated key `sudo` (The key \`sudo\` has no effect anymore.) --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 65742749..60ca1ab1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: ruby -sudo: false rvm: - 2.1.8 - 2.2.4 From 1a164bcae63c57e694f355c5aa8806ed896f69eb Mon Sep 17 00:00:00 2001 From: David Stosik Date: Sat, 3 Oct 2020 02:29:36 +0900 Subject: [PATCH 13/41] Test more recent versions of Ruby on Travis (#480) * Test more recent versions of Ruby on Travis Added: - 2.4.9 (reached end-of-life but may temporarily help in incremental debugging) - 2.5.8 - 2.6.6 Did not add 2.7.x yet because it introduces *a lot* of warnings. Did not remove any past version yet because until decided otherwise, they should be supported by the gem. (I would recommend a major version bump when those versions get dropped.) The idea is that developments from now on should be future-proof, and changes should be tested on current versions of Ruby. * Update WebMock to latest 2.x version Updating to WebMock 2.x means that: > require 'webmock' does not enable WebMock anymore. gem 'webmock' can now be safely added to a Gemfile and no http client libs will be modified when it's loaded. Call WebMock.enable! to enable WebMock. > > Please note that require 'webmock/rspec', require 'webmock/test_unit', require 'webmock/minitest' and require 'webmock/cucumber' still do enable WebMock. Source: [WebMock's CHANGELOG.md](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md#200). As rspec_api_documentation is very much tied to RSpec, I saw no problem with replacing all instances of `require 'webmock'` with `require 'webmock/rspec'`. * Update WebMock dependency to 3.2.0 3.2.0 introduced another breaking change that had to be addressed: [Automatically disable WebMock after rspec suite](https://github.com/bblimke/webmock/pull/731) As the example app_spec.rb in features/oauth2_mac_client.feature is supposed to be a stand-alone spec file, it made sense, to me, to `require "webmock/rspec"`. Does that make any sense? * Bump WebMock dev dependency to 3.5.0 This introduces Ruby 2.6 support and should get the test suite to run on that version of Ruby. * Try using WebMock 3.8.3 Let's see how this goes on Travis. --- .travis.yml | 3 +++ features/oauth2_mac_client.feature | 1 + lib/rspec_api_documentation/dsl/resource.rb | 2 +- lib/rspec_api_documentation/oauth2_mac_client.rb | 2 +- rspec_api_documentation.gemspec | 2 +- spec/http_test_client_spec.rb | 2 +- 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 60ca1ab1..f219b701 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,9 @@ rvm: - 2.1.8 - 2.2.4 - 2.3.0 + - 2.4.9 + - 2.5.8 + - 2.6.6 gemfile: - Gemfile script: diff --git a/features/oauth2_mac_client.feature b/features/oauth2_mac_client.feature index 133cf603..dd9cd026 100644 --- a/features/oauth2_mac_client.feature +++ b/features/oauth2_mac_client.feature @@ -2,6 +2,7 @@ Feature: Use OAuth2 MAC client as a test client Background: Given a file named "app_spec.rb" with: """ + require "webmock/rspec" require "rspec_api_documentation" require "rspec_api_documentation/dsl" require "rack/builder" diff --git a/lib/rspec_api_documentation/dsl/resource.rb b/lib/rspec_api_documentation/dsl/resource.rb index f03a610b..150895d3 100644 --- a/lib/rspec_api_documentation/dsl/resource.rb +++ b/lib/rspec_api_documentation/dsl/resource.rb @@ -30,7 +30,7 @@ def self.define_action(method) def callback(*args, &block) begin - require 'webmock' + require 'webmock/rspec' rescue LoadError raise "Callbacks require webmock to be installed" end diff --git a/lib/rspec_api_documentation/oauth2_mac_client.rb b/lib/rspec_api_documentation/oauth2_mac_client.rb index e5ebcb26..596171a9 100644 --- a/lib/rspec_api_documentation/oauth2_mac_client.rb +++ b/lib/rspec_api_documentation/oauth2_mac_client.rb @@ -4,7 +4,7 @@ # ActiveSupport::SecureRandom not provided in activesupport >= 3.2 end begin - require "webmock" + require "webmock/rspec" rescue LoadError raise "Webmock needs to be installed before using the OAuth2MACClient" end diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 59bb5128..20e1258d 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -26,7 +26,7 @@ Gem::Specification.new do |s| s.add_development_dependency "rake", "~> 10.5.0" s.add_development_dependency "rack-test", "~> 0.6.3" s.add_development_dependency "rack-oauth2", "~> 1.2.2" - s.add_development_dependency "webmock", "~> 1.22.6" + s.add_development_dependency "webmock", "~> 3.8.3" s.add_development_dependency "rspec-its", "~> 1.2.0" s.add_development_dependency "faraday", "~> 0.9.2" s.add_development_dependency "nokogiri", "~> 1.8.4" diff --git a/spec/http_test_client_spec.rb b/spec/http_test_client_spec.rb index f93b549e..fd77dc0f 100644 --- a/spec/http_test_client_spec.rb +++ b/spec/http_test_client_spec.rb @@ -3,7 +3,7 @@ require 'capybara' require 'capybara/server' require 'sinatra/base' -require 'webmock' +require 'webmock/rspec' require 'support/stub_app' describe RspecApiDocumentation::HttpTestClient do From d3892cc7388460a98476734963face5a7a2ac158 Mon Sep 17 00:00:00 2001 From: David Stosik Date: Sat, 3 Oct 2020 02:34:21 +0900 Subject: [PATCH 14/41] Remove Gemnasium links (#481) > ### Why is Gemnasium.com closed? > Gemnasium was acquired by GitLab in January 2018. Since May 15, 2018, the services provided by Gemnasium are no longer available. [Source.](https://docs.gitlab.com/ee/user/project/import/gemnasium.html#why-is-gemnasiumcom-closed) --- README.md | 1 - features/readme.md | 1 - 2 files changed, 2 deletions(-) diff --git a/README.md b/README.md index bedc7ac7..3a02de80 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ [![Build Status](https://travis-ci.org/zipmark/rspec_api_documentation.svg?branch=master)](https://travis-ci.org/zipmark/rspec_api_documentation) -[![Dependency Status](https://gemnasium.com/badges/github.com/zipmark/rspec_api_documentation.svg)](https://gemnasium.com/github.com/zipmark/rspec_api_documentation) [![Code Climate](https://codeclimate.com/github/zipmark/rspec_api_documentation/badges/gpa.svg)](https://codeclimate.com/github/zipmark/rspec_api_documentation) [![Inline docs](https://inch-ci.org/github/zipmark/rspec_api_documentation.svg?branch=master)](https://inch-ci.org/github/zipmark/rspec_api_documentation) [![Gem Version](https://badge.fury.io/rb/rspec_api_documentation.svg)](https://badge.fury.io/rb/rspec_api_documentation) diff --git a/features/readme.md b/features/readme.md index 5e8f4c05..8b424a20 100644 --- a/features/readme.md +++ b/features/readme.md @@ -1,5 +1,4 @@ [![Travis status](https://secure.travis-ci.org/zipmark/rspec_api_documentation.png)](https://secure.travis-ci.org/zipmark/rspec_api_documentation) -[![Gemnasium status](https://gemnasium.com/zipmark/rspec_api_documentation.png)](https://gemnasium.com/zipmark/rspec_api_documentation) http://github.com/zipmark/rspec_api_documentation From a0d07455eaf3057ed8de5fec2bfd7c109a05f74c Mon Sep 17 00:00:00 2001 From: Marek L Date: Fri, 10 Jun 2022 14:56:56 +0100 Subject: [PATCH 15/41] Require explicitly ActiveSupport Array#extract_options! Why: Trying run the specs on vanilla machine produces error: ``` resource.rb:10:in `block in define_action: undefined method extract_options! for ["/path"]:Array (NoMethodError) ``` --- lib/rspec_api_documentation.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb index 5986aadb..f37d74a5 100644 --- a/lib/rspec_api_documentation.rb +++ b/lib/rspec_api_documentation.rb @@ -1,5 +1,6 @@ require 'active_support' require 'active_support/inflector' +require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/hash/conversions' require 'active_support/core_ext/hash/deep_merge' require 'cgi' From 40c1dfc3a9e10ce8b905ca3609b72c458ca9f11a Mon Sep 17 00:00:00 2001 From: Marek L Date: Fri, 10 Jun 2022 15:11:23 +0100 Subject: [PATCH 16/41] Bump dev dependency on Faraday gem to ~> 1.0.0 Why: Trying to run specs with the old version using `bundle exec rspec` leads to an error: ``` tried to create Proc object without a block faraday-0.9.2/lib/faraday/options.rb:153:in new: tried to create Proc object without a block (ArgumentError) ... ../http_test_client.rb:2:in require ``` --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 20e1258d..e4406c8e 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -28,7 +28,7 @@ Gem::Specification.new do |s| s.add_development_dependency "rack-oauth2", "~> 1.2.2" s.add_development_dependency "webmock", "~> 3.8.3" s.add_development_dependency "rspec-its", "~> 1.2.0" - s.add_development_dependency "faraday", "~> 0.9.2" + s.add_development_dependency "faraday", "~> 1.0.0" s.add_development_dependency "nokogiri", "~> 1.8.4" s.add_development_dependency "yard", "~> 0.9.15" s.add_development_dependency "inch", "~> 0.8.0" From 758c879893a21233c0eb977e79ef026f263fc37e Mon Sep 17 00:00:00 2001 From: Marek L Date: Fri, 10 Jun 2022 15:24:26 +0100 Subject: [PATCH 17/41] Require explicitly ActiveSupport Hash::Keys Why: Fixes error when running specs `bundle exec (/home/m/.rbenv/versions/3.1.0/bin/rspec) bundle exec rspec spec/dsl_spec.rb` ``` NoMethodError: undefined method `stringify_keys for {:name=>"Friday Order"}:Hash ... dsl/endpoint.rb:171:in `block in extra_params ``` --- lib/rspec_api_documentation.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb index f37d74a5..a15e6018 100644 --- a/lib/rspec_api_documentation.rb +++ b/lib/rspec_api_documentation.rb @@ -3,6 +3,7 @@ require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/hash/conversions' require 'active_support/core_ext/hash/deep_merge' +require 'active_support/core_ext/hash/keys' require 'cgi' require 'json' From 26af788cb15ab8f3576cc25d0eaf83127970a2d8 Mon Sep 17 00:00:00 2001 From: Marek L Date: Fri, 10 Jun 2022 15:29:49 +0100 Subject: [PATCH 18/41] Update Api Blueprint spec assertions to reflect implementation Why: Given specs fails on expecting `description` field being empty while in current version it contains capitalised version of `name` attribute. ``` expected: [{:required=>false, :name=>"description", :description=>nil, :properties_description=>"optional"}] got: [{:required=>false, :name=>"description", :description=>"Description", :properties_description=>"optional"}] ``` --- spec/views/api_blueprint_index_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/views/api_blueprint_index_spec.rb b/spec/views/api_blueprint_index_spec.rb index 1d526597..e923abf2 100644 --- a/spec/views/api_blueprint_index_spec.rb +++ b/spec/views/api_blueprint_index_spec.rb @@ -142,7 +142,7 @@ properties_description: "required, string" }, { name: "option", - description: nil, + description: 'Option', properties_description: 'optional' }] expect(post_route_with_optionals[:has_attributes?]).to eq false @@ -158,7 +158,7 @@ expect(posts_route[:attributes]).to eq [{ required: false, name: "description", - description: nil, + description: 'Description', properties_description: "optional" }] end From 8530790d1d899588024588f63173a3d6dc319b25 Mon Sep 17 00:00:00 2001 From: nicolaa Date: Fri, 13 Jan 2023 09:46:58 -0500 Subject: [PATCH 19/41] testing --- .travis.yml | 1 + lib/rspec_api_documentation/writers/writer.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f219b701..3cceeaed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ rvm: - 2.4.9 - 2.5.8 - 2.6.6 + - 3.2.0 gemfile: - Gemfile script: diff --git a/lib/rspec_api_documentation/writers/writer.rb b/lib/rspec_api_documentation/writers/writer.rb index d70b1f2a..a00c1715 100644 --- a/lib/rspec_api_documentation/writers/writer.rb +++ b/lib/rspec_api_documentation/writers/writer.rb @@ -14,7 +14,7 @@ def self.write(index, configuration) end def self.clear_docs(docs_dir) - if File.exists?(docs_dir) + if File.exist?(docs_dir) FileUtils.rm_rf(docs_dir, :secure => true) end FileUtils.mkdir_p(docs_dir) From f9e78b5a63650544d95b211ba9706038682b8227 Mon Sep 17 00:00:00 2001 From: nicolaa Date: Fri, 13 Jan 2023 09:54:19 -0500 Subject: [PATCH 20/41] support ruby32 syntax --- lib/rspec_api_documentation/writers/append_json_writer.rb | 2 +- spec/api_documentation_spec.rb | 2 +- spec/writers/html_writer_spec.rb | 2 +- spec/writers/json_iodocs_writer_spec.rb | 2 +- spec/writers/json_writer_spec.rb | 2 +- spec/writers/markdown_writer_spec.rb | 2 +- spec/writers/slate_writer_spec.rb | 2 +- spec/writers/textile_writer_spec.rb | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/rspec_api_documentation/writers/append_json_writer.rb b/lib/rspec_api_documentation/writers/append_json_writer.rb index 5eae1f7b..69f943e7 100644 --- a/lib/rspec_api_documentation/writers/append_json_writer.rb +++ b/lib/rspec_api_documentation/writers/append_json_writer.rb @@ -5,7 +5,7 @@ module Writers class AppendJsonWriter < JsonWriter def write index_file = docs_dir.join("index.json") - if File.exists?(index_file) && (output = File.read(index_file)).length >= 2 + if File.exist?(index_file) && (output = File.read(index_file)).length >= 2 existing_index_hash = JSON.parse(output) end File.open(index_file, "w+") do |f| diff --git a/spec/api_documentation_spec.rb b/spec/api_documentation_spec.rb index 39930cc4..dc295567 100644 --- a/spec/api_documentation_spec.rb +++ b/spec/api_documentation_spec.rb @@ -19,7 +19,7 @@ subject.clear_docs expect(File.directory?(configuration.docs_dir)).to be_truthy - expect(File.exists?(test_file)).to be_falsey + expect(File.exist?(test_file)).to be_falsey end end diff --git a/spec/writers/html_writer_spec.rb b/spec/writers/html_writer_spec.rb index 72dc5615..76db414e 100644 --- a/spec/writers/html_writer_spec.rb +++ b/spec/writers/html_writer_spec.rb @@ -27,7 +27,7 @@ writer.write index_file = File.join(configuration.docs_dir, "index.html") - expect(File.exists?(index_file)).to be_truthy + expect(File.exist?(index_file)).to be_truthy end end end diff --git a/spec/writers/json_iodocs_writer_spec.rb b/spec/writers/json_iodocs_writer_spec.rb index bfee639c..116ccab1 100644 --- a/spec/writers/json_iodocs_writer_spec.rb +++ b/spec/writers/json_iodocs_writer_spec.rb @@ -25,7 +25,7 @@ it "should write the index" do writer.write index_file = File.join(configuration.docs_dir, "apiconfig.json") - expect(File.exists?(index_file)).to be_truthy + expect(File.exist?(index_file)).to be_truthy end end end diff --git a/spec/writers/json_writer_spec.rb b/spec/writers/json_writer_spec.rb index 9e5e6b8d..973b52b1 100644 --- a/spec/writers/json_writer_spec.rb +++ b/spec/writers/json_writer_spec.rb @@ -24,7 +24,7 @@ it "should write the index" do writer.write index_file = File.join(configuration.docs_dir, "index.json") - expect(File.exists?(index_file)).to be_truthy + expect(File.exist?(index_file)).to be_truthy end end end diff --git a/spec/writers/markdown_writer_spec.rb b/spec/writers/markdown_writer_spec.rb index 799336ee..313a51d9 100644 --- a/spec/writers/markdown_writer_spec.rb +++ b/spec/writers/markdown_writer_spec.rb @@ -27,7 +27,7 @@ writer.write index_file = File.join(configuration.docs_dir, "index.md") - expect(File.exists?(index_file)).to be_truthy + expect(File.exist?(index_file)).to be_truthy end end end diff --git a/spec/writers/slate_writer_spec.rb b/spec/writers/slate_writer_spec.rb index 9c1398da..acd91047 100644 --- a/spec/writers/slate_writer_spec.rb +++ b/spec/writers/slate_writer_spec.rb @@ -27,7 +27,7 @@ writer.write index_file = File.join(configuration.docs_dir, "index.html.md") - expect(File.exists?(index_file)).to be_truthy + expect(File.exist?(index_file)).to be_truthy end end end diff --git a/spec/writers/textile_writer_spec.rb b/spec/writers/textile_writer_spec.rb index 1531f7ad..2e10cb7d 100644 --- a/spec/writers/textile_writer_spec.rb +++ b/spec/writers/textile_writer_spec.rb @@ -27,7 +27,7 @@ writer.write index_file = File.join(configuration.docs_dir, "index.textile") - expect(File.exists?(index_file)).to be_truthy + expect(File.exist?(index_file)).to be_truthy end end end From 277b4c81b7311eeb97deb989ea65bcd38ad44e37 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Thu, 25 Apr 2024 12:04:07 -0500 Subject: [PATCH 21/41] ci: remove TravisCI --- .travis.yml | 15 --------------- README.md | 1 - features/readme.md | 2 -- 3 files changed, 18 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f219b701..00000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: ruby -rvm: - - 2.1.8 - - 2.2.4 - - 2.3.0 - - 2.4.9 - - 2.5.8 - - 2.6.6 -gemfile: - - Gemfile -script: - - bundle exec rake -branches: - only: - - master diff --git a/README.md b/README.md index 3a02de80..3c413732 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -[![Build Status](https://travis-ci.org/zipmark/rspec_api_documentation.svg?branch=master)](https://travis-ci.org/zipmark/rspec_api_documentation) [![Code Climate](https://codeclimate.com/github/zipmark/rspec_api_documentation/badges/gpa.svg)](https://codeclimate.com/github/zipmark/rspec_api_documentation) [![Inline docs](https://inch-ci.org/github/zipmark/rspec_api_documentation.svg?branch=master)](https://inch-ci.org/github/zipmark/rspec_api_documentation) [![Gem Version](https://badge.fury.io/rb/rspec_api_documentation.svg)](https://badge.fury.io/rb/rspec_api_documentation) diff --git a/features/readme.md b/features/readme.md index 8b424a20..365510ec 100644 --- a/features/readme.md +++ b/features/readme.md @@ -1,5 +1,3 @@ -[![Travis status](https://secure.travis-ci.org/zipmark/rspec_api_documentation.png)](https://secure.travis-ci.org/zipmark/rspec_api_documentation) - http://github.com/zipmark/rspec_api_documentation # RSpec API Doc Generator From 7c25673d3e31fa04fed21154dcf3144eee7266c8 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Thu, 25 Apr 2024 12:10:59 -0500 Subject: [PATCH 22/41] ci: add github actions ci workflow --- .github/workflows/ci.yml | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..f74c1b8a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,65 @@ +--- + +name: CI + +on: [push, pull_request] + +jobs: + test: + name: "Testing" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + # Recent Rubies and Rails + - ruby-version: '3.2' + - ruby-version: '3.1' + - ruby-version: '3.0' + - ruby-version: '2.7' + - ruby-version: '2.6' + - ruby-version: '2.6' + - ruby-version: '2.7' + - ruby-version: '2.6' + # Old Rubies and Rails + - ruby-version: '2.5' + bundler: '1' + - ruby-version: '2.4' + bundler: '1' + - ruby-version: '2.4' + bundler: '1' + # Failing with a stack trace in active support + # - ruby-version: '2.4' + # rails-version: '4.1' + # bundler: '1' + + continue-on-error: "${{ endsWith(matrix.ruby-version, 'head') }}" + + env: + CI: "1" + + steps: + - name: "Checkout Code" + uses: "actions/checkout@v2" + timeout-minutes: 5 + with: + fetch-depth: 0 + + # - name: Install required libs + # run: | + # sudo apt-get -yqq install libsqlite3-dev + + - name: "Build Ruby" + uses: ruby/setup-ruby@v1 + with: + ruby-version: "${{ matrix.ruby-version }}" + bundler: "${{ matrix.bundler || 2 }}" + bundler-cache: true + # env: + # RAILS_VERSION: ${{ matrix.rails-version }} + + - name: "Run tests" + run: | + bundle exec rake + # env: + # RAILS_VERSION: ${{ matrix.rails-version }} From 876cf4a620813c58b753ba073f6e18d7f7aafcc9 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Thu, 25 Apr 2024 12:11:16 -0500 Subject: [PATCH 23/41] deps(dependabot): add dependabot config --- .github/dependabot.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..3e16eafe --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: +- package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "daily" +- package-ecosystem: bundler + directory: "/" + schedule: + interval: daily + time: "11:00" + open-pull-requests-limit: 10 From 115605a60f81160fe31142795cc40f8ef4a71efc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:38:58 +0000 Subject: [PATCH 24/41] Bump actions/checkout from 2 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f74c1b8a..93077e3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: steps: - name: "Checkout Code" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" timeout-minutes: 5 with: fetch-depth: 0 From be311da2e594a15b907d384188b7ffd772baf8f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:39:07 +0000 Subject: [PATCH 25/41] Update rack-oauth2 requirement from ~> 1.2.2 to ~> 1.12.0 Updates the requirements on [rack-oauth2](https://github.com/nov/rack-oauth2) to permit the latest version. - [Release notes](https://github.com/nov/rack-oauth2/releases) - [Changelog](https://github.com/nov/rack-oauth2/blob/main/CHANGELOG.md) - [Commits](https://github.com/nov/rack-oauth2/compare/v1.2.2...v1.12.0) --- updated-dependencies: - dependency-name: rack-oauth2 dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 20e1258d..5984f74e 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -25,7 +25,7 @@ Gem::Specification.new do |s| s.add_development_dependency "capybara", "~> 2.6.2" s.add_development_dependency "rake", "~> 10.5.0" s.add_development_dependency "rack-test", "~> 0.6.3" - s.add_development_dependency "rack-oauth2", "~> 1.2.2" + s.add_development_dependency "rack-oauth2", "~> 1.12.0" s.add_development_dependency "webmock", "~> 3.8.3" s.add_development_dependency "rspec-its", "~> 1.2.0" s.add_development_dependency "faraday", "~> 0.9.2" From 5c71ceedbfa91d7b1bd756d78c32c3b62461a914 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:39:09 +0000 Subject: [PATCH 26/41] Update rspec requirement from ~> 3.4.0 to ~> 3.13.0 Updates the requirements on [rspec](https://github.com/rspec/rspec-metagem) to permit the latest version. - [Commits](https://github.com/rspec/rspec-metagem/compare/v3.4.0...v3.13.0) --- updated-dependencies: - dependency-name: rspec dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 20e1258d..b7bb2baa 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -36,7 +36,7 @@ Gem::Specification.new do |s| s.add_development_dependency "contracts", "~> 0.13.0" s.add_development_dependency "gherkin", "~> 3.2.0" s.add_development_dependency "multi_json", "~> 1.11.2" - s.add_development_dependency "rspec", "~> 3.4.0" + s.add_development_dependency "rspec", "~> 3.0" s.files = Dir.glob("lib/**/*") + Dir.glob("templates/**/*") s.require_path = "lib" From e74afb826f7823ce91e5891921d47e0b093921da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:39:20 +0000 Subject: [PATCH 27/41] Update aruba requirement from ~> 0.13.0 to ~> 0.14.14 Updates the requirements on [aruba](https://github.com/cucumber/aruba) to permit the latest version. - [Changelog](https://github.com/cucumber/aruba/blob/main/CHANGELOG.md) - [Commits](https://github.com/cucumber/aruba/compare/v0.13.0...v0.14.14) --- updated-dependencies: - dependency-name: aruba dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 20e1258d..1eb768b0 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.add_development_dependency "bundler", ">= 1.16" s.add_development_dependency "fakefs", "~> 0.6.0" s.add_development_dependency "sinatra", "~> 1.4.7" - s.add_development_dependency "aruba", "~> 0.13.0" + s.add_development_dependency "aruba", "~> 0.14.14" s.add_development_dependency "capybara", "~> 2.6.2" s.add_development_dependency "rake", "~> 10.5.0" s.add_development_dependency "rack-test", "~> 0.6.3" From 09f69e3d4e8952a1671c97ff11462a81e06ede7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:46:21 +0000 Subject: [PATCH 28/41] Update contracts requirement from ~> 0.13.0 to ~> 0.17 Updates the requirements on [contracts](https://github.com/egonSchiele/contracts.ruby) to permit the latest version. - [Changelog](https://github.com/egonSchiele/contracts.ruby/blob/master/CHANGELOG.markdown) - [Commits](https://github.com/egonSchiele/contracts.ruby/compare/v0.13.0...v0.17) --- updated-dependencies: - dependency-name: contracts dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 1d4bd3da..6899fb48 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -33,7 +33,7 @@ Gem::Specification.new do |s| s.add_development_dependency "yard", "~> 0.9.15" s.add_development_dependency "inch", "~> 0.8.0" s.add_development_dependency "minitest", "~> 5.8.4" - s.add_development_dependency "contracts", "~> 0.13.0" + s.add_development_dependency "contracts", "~> 0.17" s.add_development_dependency "gherkin", "~> 3.2.0" s.add_development_dependency "multi_json", "~> 1.11.2" s.add_development_dependency "rspec", "~> 3.0" From afc5c4716c04fc6bfcf49d6ec13f1890d5eaa907 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:46:48 +0000 Subject: [PATCH 29/41] Update multi_json requirement from ~> 1.11.2 to ~> 1.15.0 Updates the requirements on [multi_json](https://github.com/intridea/multi_json) to permit the latest version. - [Changelog](https://github.com/intridea/multi_json/blob/master/CHANGELOG.md) - [Commits](https://github.com/intridea/multi_json/compare/v1.11.2...v1.15.0) --- updated-dependencies: - dependency-name: multi_json dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 40646226..0ac56f32 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -35,7 +35,7 @@ Gem::Specification.new do |s| s.add_development_dependency "minitest", "~> 5.8.4" s.add_development_dependency "contracts", "~> 0.17" s.add_development_dependency "gherkin", "~> 3.2.0" - s.add_development_dependency "multi_json", "~> 1.11.2" + s.add_development_dependency "multi_json", "~> 1.15.0" s.add_development_dependency "rspec", "~> 3.0" s.files = Dir.glob("lib/**/*") + Dir.glob("templates/**/*") From 3cfa9c0c1884df647a4319489758143bb0bdfd2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:46:52 +0000 Subject: [PATCH 30/41] Update rspec-its requirement from ~> 1.2.0 to ~> 1.3.0 Updates the requirements on [rspec-its](https://github.com/rspec/rspec-its) to permit the latest version. - [Changelog](https://github.com/rspec/rspec-its/blob/main/Changelog.md) - [Commits](https://github.com/rspec/rspec-its/compare/v1.2.0...v1.3.0) --- updated-dependencies: - dependency-name: rspec-its dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 40646226..217af1fb 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -27,7 +27,7 @@ Gem::Specification.new do |s| s.add_development_dependency "rack-test", "~> 0.6.3" s.add_development_dependency "rack-oauth2", "~> 1.12.0" s.add_development_dependency "webmock", "~> 3.8.3" - s.add_development_dependency "rspec-its", "~> 1.2.0" + s.add_development_dependency "rspec-its", "~> 1.3.0" s.add_development_dependency "faraday", "~> 0.9.2" s.add_development_dependency "nokogiri", "~> 1.8.4" s.add_development_dependency "yard", "~> 0.9.15" From 3d5521b28d0bb312e185564ff7f69be73376db18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:46:56 +0000 Subject: [PATCH 31/41] Update capybara requirement from ~> 2.6.2 to ~> 3.39.2 Updates the requirements on [capybara](https://github.com/teamcapybara/capybara) to permit the latest version. - [Changelog](https://github.com/teamcapybara/capybara/blob/master/History.md) - [Commits](https://github.com/teamcapybara/capybara/compare/2.6.2...3.39.2) --- updated-dependencies: - dependency-name: capybara dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index 40646226..94435140 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |s| s.add_development_dependency "fakefs", "~> 0.6.0" s.add_development_dependency "sinatra", "~> 1.4.7" s.add_development_dependency "aruba", "~> 0.14.14" - s.add_development_dependency "capybara", "~> 2.6.2" + s.add_development_dependency "capybara", "~> 3.39.2" s.add_development_dependency "rake", "~> 10.5.0" s.add_development_dependency "rack-test", "~> 0.6.3" s.add_development_dependency "rack-oauth2", "~> 1.12.0" From 58d5bd11dca1e68e3863b9926998aaf324931133 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:47:40 +0000 Subject: [PATCH 32/41] Update rake requirement from ~> 10.5.0 to ~> 13.2.1 Updates the requirements on [rake](https://github.com/ruby/rake) to permit the latest version. - [Release notes](https://github.com/ruby/rake/releases) - [Changelog](https://github.com/ruby/rake/blob/master/History.rdoc) - [Commits](https://github.com/ruby/rake/compare/v10.5.0...v13.2.1) --- updated-dependencies: - dependency-name: rake dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index cdd9b06b..12ff7eb8 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -23,7 +23,7 @@ Gem::Specification.new do |s| s.add_development_dependency "sinatra", "~> 1.4.7" s.add_development_dependency "aruba", "~> 0.14.14" s.add_development_dependency "capybara", "~> 3.39.2" - s.add_development_dependency "rake", "~> 10.5.0" + s.add_development_dependency "rake", "~> 13.2.1" s.add_development_dependency "rack-test", "~> 0.6.3" s.add_development_dependency "rack-oauth2", "~> 1.12.0" s.add_development_dependency "webmock", "~> 3.8.3" From ab4c568be341114d6e074612f76530e03051bb53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:47:41 +0000 Subject: [PATCH 33/41] Update sinatra requirement from ~> 1.4.7 to ~> 2.0.8 Updates the requirements on [sinatra](https://github.com/sinatra/sinatra) to permit the latest version. - [Changelog](https://github.com/sinatra/sinatra/blob/main/CHANGELOG.md) - [Commits](https://github.com/sinatra/sinatra/compare/v1.4.7...v2.0.8.1) --- updated-dependencies: - dependency-name: sinatra dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index cdd9b06b..bda0e41c 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |s| s.add_development_dependency "bundler", ">= 1.16" s.add_development_dependency "fakefs", "~> 0.6.0" - s.add_development_dependency "sinatra", "~> 1.4.7" + s.add_development_dependency "sinatra", "~> 2.0.8" s.add_development_dependency "aruba", "~> 0.14.14" s.add_development_dependency "capybara", "~> 3.39.2" s.add_development_dependency "rake", "~> 10.5.0" From fe505fff24d43f03d5f19f3d94c7c24f57f7395d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:47:56 +0000 Subject: [PATCH 34/41] Update gherkin requirement from ~> 3.2.0 to ~> 9.0.0 Updates the requirements on [gherkin](https://github.com/cucumber/cucumber) to permit the latest version. - [Release notes](https://github.com/cucumber/cucumber/releases) - [Commits](https://github.com/cucumber/cucumber/compare/react/v3.2.0...gherkin/v9.0.0) --- updated-dependencies: - dependency-name: gherkin dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index cdd9b06b..b9ec109b 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -34,7 +34,7 @@ Gem::Specification.new do |s| s.add_development_dependency "inch", "~> 0.8.0" s.add_development_dependency "minitest", "~> 5.8.4" s.add_development_dependency "contracts", "~> 0.17" - s.add_development_dependency "gherkin", "~> 3.2.0" + s.add_development_dependency "gherkin", "~> 9.0.0" s.add_development_dependency "multi_json", "~> 1.15.0" s.add_development_dependency "rspec", "~> 3.0" From 6251232b7053d5cb992ae229f67493b419870935 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:48:15 +0000 Subject: [PATCH 35/41] Update webmock requirement from ~> 3.8.3 to ~> 3.23.0 Updates the requirements on [webmock](https://github.com/bblimke/webmock) to permit the latest version. - [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md) - [Commits](https://github.com/bblimke/webmock/compare/v3.8.3...v3.23.0) --- updated-dependencies: - dependency-name: webmock dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- rspec_api_documentation.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rspec_api_documentation.gemspec b/rspec_api_documentation.gemspec index bda0e41c..feabfe57 100644 --- a/rspec_api_documentation.gemspec +++ b/rspec_api_documentation.gemspec @@ -26,7 +26,7 @@ Gem::Specification.new do |s| s.add_development_dependency "rake", "~> 10.5.0" s.add_development_dependency "rack-test", "~> 0.6.3" s.add_development_dependency "rack-oauth2", "~> 1.12.0" - s.add_development_dependency "webmock", "~> 3.8.3" + s.add_development_dependency "webmock", "~> 3.23.0" s.add_development_dependency "rspec-its", "~> 1.3.0" s.add_development_dependency "faraday", "~> 0.9.2" s.add_development_dependency "nokogiri", "~> 1.8.4" From 1b4f2113ab8b06830deba3cbbc19252b45cefd4b Mon Sep 17 00:00:00 2001 From: Dmitry Krasnoukhov Date: Mon, 19 May 2025 19:05:29 +0300 Subject: [PATCH 36/41] OAS3 requestBody to include all defined parameters --- .../writers/open_api_writer.rb | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/rspec_api_documentation/writers/open_api_writer.rb b/lib/rspec_api_documentation/writers/open_api_writer.rb index ddae4ad5..7d4a026c 100644 --- a/lib/rspec_api_documentation/writers/open_api_writer.rb +++ b/lib/rspec_api_documentation/writers/open_api_writer.rb @@ -208,9 +208,14 @@ def extract_request_body(example) body = example.requests.map { |req| JSON.parse(req[:request_body]) rescue nil }.compact.reduce({}, :merge) return nil if body.empty? + schema = get_schema(body) + example.extended_parameters.select { |p| p[:in].nil? }.each do |parameter| + inject_body_parameter(schema, parameter) + end + OpenApi::RequestBody.new( content: { - 'application/json' => OpenApi::Media.new(schema: get_schema(body), example: body) + 'application/json' => OpenApi::Media.new(schema: schema, example: body) } ) end @@ -255,6 +260,20 @@ def extract_known_parameters(parameters) parameters.select { |parameter| %w(query path header cookie).include?(parameter[:in].to_s) } .map { |parameter| extract_parameter(parameter) } end + + def inject_body_parameter(schema, parameter) + scope = schema + parameter[:scope] && Array(parameter[:scope]).each do |curr| + scope.properties[curr.to_s] ||= OpenApi::Schema.new(type: 'object', properties: {}) + scope = scope.properties[curr.to_s] + end + + scope.required ||= [] + scope.required << parameter[:name].to_s if parameter[:required] + + scope.properties[parameter[:name].to_s] ||= get_schema(parameter[:value]) + scope.properties[parameter[:name].to_s].description = parameter[:description] if parameter[:description] + end end class OpenApiExample From 7396c013ce89fc6a4a309c97bed233d354babb0e Mon Sep 17 00:00:00 2001 From: Dmitry Krasnoukhov Date: Mon, 19 May 2025 19:06:16 +0300 Subject: [PATCH 37/41] correct header/query formatting for slate --- lib/rspec_api_documentation/views/markup_example.rb | 4 +++- templates/rspec_api_documentation/slate_example.mustache | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/rspec_api_documentation/views/markup_example.rb b/lib/rspec_api_documentation/views/markup_example.rb index 682075bf..181ab028 100644 --- a/lib/rspec_api_documentation/views/markup_example.rb +++ b/lib/rspec_api_documentation/views/markup_example.rb @@ -49,7 +49,9 @@ def response_fields def requests super.map do |hash| hash[:request_headers_text] = format_hash(hash[:request_headers]) - hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters]) + hash[:request_query_parameters_text] = if hash[:request_query_parameters].present? + CGI.unescape(hash[:request_query_parameters].to_query) + end hash[:response_headers_text] = format_hash(hash[:response_headers]) if @host if hash[:curl].is_a? RspecApiDocumentation::Curl diff --git a/templates/rspec_api_documentation/slate_example.mustache b/templates/rspec_api_documentation/slate_example.mustache index f07233a4..f6d9aff6 100644 --- a/templates/rspec_api_documentation/slate_example.mustache +++ b/templates/rspec_api_documentation/slate_example.mustache @@ -20,8 +20,8 @@ {{# requests }} ```plaintext -{{ request_method }} {{ request_path }} -{{ request_headers_text }} +{{ request_method }} {{{ request_path }}} +{{{ request_headers_text }}} ``` {{/ requests }} @@ -29,8 +29,8 @@ {{# requests }} {{# request_query_parameters_text }} -```json -{{ request_query_parameters_text }} +```plaintext +{{{ request_query_parameters_text }}} ``` {{/ request_query_parameters_text }} From 3896fb00f6ef724b3e5dc575ad7950d82175561d Mon Sep 17 00:00:00 2001 From: Dmitry Krasnoukhov Date: Tue, 20 May 2025 17:08:44 +0300 Subject: [PATCH 38/41] handle case with no properties for scope --- lib/rspec_api_documentation/writers/open_api_writer.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/rspec_api_documentation/writers/open_api_writer.rb b/lib/rspec_api_documentation/writers/open_api_writer.rb index 7d4a026c..cd9cd7af 100644 --- a/lib/rspec_api_documentation/writers/open_api_writer.rb +++ b/lib/rspec_api_documentation/writers/open_api_writer.rb @@ -268,6 +268,8 @@ def inject_body_parameter(schema, parameter) scope = scope.properties[curr.to_s] end + return unless scope.properties + scope.required ||= [] scope.required << parameter[:name].to_s if parameter[:required] From 02c00ec1e1122ce43c284744e24eae552d8b3b53 Mon Sep 17 00:00:00 2001 From: Dmitry Krasnoukhov Date: Wed, 21 May 2025 18:03:07 +0300 Subject: [PATCH 39/41] prevent empty required --- lib/rspec_api_documentation/writers/open_api_writer.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/rspec_api_documentation/writers/open_api_writer.rb b/lib/rspec_api_documentation/writers/open_api_writer.rb index cd9cd7af..9c2ade77 100644 --- a/lib/rspec_api_documentation/writers/open_api_writer.rb +++ b/lib/rspec_api_documentation/writers/open_api_writer.rb @@ -270,8 +270,10 @@ def inject_body_parameter(schema, parameter) return unless scope.properties - scope.required ||= [] - scope.required << parameter[:name].to_s if parameter[:required] + if parameter[:required] + scope.required ||= [] + scope.required << parameter[:name].to_s + end scope.properties[parameter[:name].to_s] ||= get_schema(parameter[:value]) scope.properties[parameter[:name].to_s].description = parameter[:description] if parameter[:description] From 02244891e2e5852070d9da4c396a600453db9657 Mon Sep 17 00:00:00 2001 From: Dmitry Krasnoukhov Date: Mon, 26 May 2025 13:27:59 +0300 Subject: [PATCH 40/41] fix route with param name generation --- lib/rspec_api_documentation/writers/open_api_writer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rspec_api_documentation/writers/open_api_writer.rb b/lib/rspec_api_documentation/writers/open_api_writer.rb index 9c2ade77..e59dd1ed 100644 --- a/lib/rspec_api_documentation/writers/open_api_writer.rb +++ b/lib/rspec_api_documentation/writers/open_api_writer.rb @@ -302,7 +302,7 @@ def requests end def route - super.gsub(/:(?[^\/]+)/, '{\k}') + super.gsub(/:(\w+)/, '{\1}') end end end From 527c18e133ee6773ac0aec31c4e9014a54e60cf3 Mon Sep 17 00:00:00 2001 From: Dmitry Krasnoukhov Date: Wed, 4 Jun 2025 18:58:29 +0300 Subject: [PATCH 41/41] set type if present --- lib/rspec_api_documentation/writers/open_api_writer.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/rspec_api_documentation/writers/open_api_writer.rb b/lib/rspec_api_documentation/writers/open_api_writer.rb index e59dd1ed..51d16663 100644 --- a/lib/rspec_api_documentation/writers/open_api_writer.rb +++ b/lib/rspec_api_documentation/writers/open_api_writer.rb @@ -276,6 +276,7 @@ def inject_body_parameter(schema, parameter) end scope.properties[parameter[:name].to_s] ||= get_schema(parameter[:value]) + scope.properties[parameter[:name].to_s].type = parameter[:type] if parameter[:type] scope.properties[parameter[:name].to_s].description = parameter[:description] if parameter[:description] end end