grape-swagger 0.31.1 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e20b96cce4f137604bc4133b23249fde90b242160469cd6ed347d2840bd5b74
4
- data.tar.gz: 5e6d17f9875b63983b186d920dc28cdc4a957f13bc9f511a61991dbc7196ce50
3
+ metadata.gz: ea7cb947847696a10190ade08cfbe8bf19364a4b5855d932abda009c672122c4
4
+ data.tar.gz: 8a9c2f4a2bff62b247b795b6082d825d9403382ef56626f93ed697b4b654dc54
5
5
  SHA512:
6
- metadata.gz: f2596bf6f153d0447fec637fc4c035fa2bc1d3806feebf2f71a9e6fcd9c950a40d7bbd02fa703ad11994a0b4969fb014a0342a4dc01a7c3224c6670d126ffb73
7
- data.tar.gz: 39e5bfb7503ae7ea188231768db59fd89b8ef41494edb18ec8bf3e1cc458fda5fcf6db381663e06681e2b4b476e454147a4494232c316901a88caf2955ea7e92
6
+ metadata.gz: 45dfe914ee2225ab36174fd182563a56aaf8cfb78f9aaccdc8a4070e47acb41e0010f31c283d6bef76819a296539457da5095191e17e181d0acf4271f743bcf0
7
+ data.tar.gz: 0ab65509589c8537b7f77810dd76be2fb50e092796570a333704a9b06893e8a5756988465214752df3b0a2093a731e33e10b229b7c879568e28d2f247a79dd68
data/.rubocop_todo.yml CHANGED
@@ -1,11 +1,18 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2018-09-28 22:03:50 -0400 using RuboCop version 0.59.2.
3
+ # on 2018-11-04 01:12:26 +0100 using RuboCop version 0.60.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
+ # Offense count: 1
10
+ # Configuration parameters: Include.
11
+ # Include: **/*.gemfile, **/Gemfile, **/gems.rb
12
+ Bundler/DuplicatedGem:
13
+ Exclude:
14
+ - 'Gemfile'
15
+
9
16
  # Offense count: 1
10
17
  # Configuration parameters: Include.
11
18
  # Include: **/*.gemspec
@@ -35,6 +42,6 @@ Style/ClassVars:
35
42
  Exclude:
36
43
  - 'lib/grape-swagger/doc_methods.rb'
37
44
 
38
- # Offense count: 21
45
+ # Offense count: 22
39
46
  Style/Documentation:
40
47
  Enabled: false
data/.travis.yml CHANGED
@@ -11,22 +11,22 @@ after_success:
11
11
  - bundle exec danger
12
12
 
13
13
  rvm:
14
- - 2.5.1
15
- - 2.4.4
14
+ - 2.4.5
15
+ - 2.5.3
16
+ - 2.6.0-preview2
16
17
  env:
17
18
  - MODEL_PARSER=grape-swagger-entity
18
19
  - MODEL_PARSER=grape-swagger-representable
19
- - GRAPE_VERSION=0.17.0
20
- - GRAPE_VERSION=0.18.0
21
20
  - GRAPE_VERSION=0.19.2
22
21
  - GRAPE_VERSION=1.0.3
22
+ - GRAPE_VERSION=1.2.0
23
23
  - GRAPE_VERSION=HEAD
24
24
 
25
25
  matrix:
26
26
  fast_finish: true
27
27
 
28
28
  include:
29
- - rvm: 2.3.7
29
+ - rvm: 2.3.8
30
30
  env:
31
31
  - rvm: ruby-head
32
32
  env:
@@ -34,6 +34,6 @@ matrix:
34
34
  env:
35
35
 
36
36
  allow_failures:
37
- - rvm: 2.3.7
37
+ - rvm: 2.3.8
38
38
  - rvm: ruby-head
39
39
  - rvm: jruby-head
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ### Next
2
+
3
+ #### Features
4
+
5
+ * Your contribution here.
6
+
7
+ #### Fixes
8
+
9
+ * Your contribution here.
10
+
11
+ ### 0.32.0 (November 26, 2018)
12
+
13
+ #### Features
14
+
15
+ * [#717](https://github.com/ruby-grape/grape-swagger/pull/717): Adds support for grape >= 1.2 - [@myxoh](https://github.com/myxoh).
16
+
17
+ #### Fixes
18
+
19
+ * [#720](https://github.com/ruby-grape/grape-swagger/pull/720): Fix: corrected `termsOfService` field name in additional info - [@dblock](https://github.com/dblock).
20
+
1
21
  ### 0.31.1 (October 23, 2018)
2
22
 
3
23
  #### Features
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ ruby RUBY_VERSION
6
6
 
7
7
  gemspec
8
8
 
9
- gem 'grape', case version = ENV['GRAPE_VERSION'] || '~> 1.0'
9
+ gem 'grape', case version = ENV['GRAPE_VERSION'] || '~> 1.2'
10
10
  when 'HEAD'
11
11
  { git: 'https://github.com/ruby-grape/grape' }
12
12
  else
@@ -26,7 +26,12 @@ group :development, :test do
26
26
  gem 'rake'
27
27
  gem 'rdoc'
28
28
  gem 'rspec', '~> 3.0'
29
- gem 'rubocop', '~> 0.59', require: false
29
+ # TODO: change back after 2.6.0 release and updated rubocop version
30
+ if RUBY_VERSION == '2.6.0'
31
+ gem 'rubocop', git: 'https://github.com/rubocop-hq/rubocop.git', require: false
32
+ else
33
+ gem 'rubocop', '~> 0.60', require: false
34
+ end
30
35
  end
31
36
 
32
37
  group :test do
data/README.md CHANGED
@@ -48,8 +48,9 @@ grape-swagger | swagger spec | grape | grape-entity | represen
48
48
  0.10.5 | 1.2 | >= 0.10.0 ... <= 0.14.0 | < 0.5.0 | n/a |
49
49
  0.11.0 | 1.2 | >= 0.16.2 | < 0.5.0 | n/a |
50
50
  0.25.2 | 2.0 | >= 0.14.0 ... <= 0.18.0 | <= 0.6.0 | >= 2.4.1 |
51
- 0.26.0 | 2.0 | >= 0.16.2 | <= 0.6.1 | >= 2.4.1 |
52
- 0.27.0 | 2.0 | >= 0.16.2 | >= 0.5.0 | >= 2.4.1 |
51
+ 0.26.0 | 2.0 | >= 0.16.2 <= 1.1.0 | <= 0.6.1 | >= 2.4.1 |
52
+ 0.27.0 | 2.0 | >= 0.16.2 ... <= 1.1.0 | >= 0.5.0 | >= 2.4.1 |
53
+ 0.32.0 | 2.0 | >= 0.16.2 | >= 0.5.0 | >= 2.4.1 |
53
54
 
54
55
 
55
56
  ## Swagger-Spec <a name="swagger-spec"></a>
data/lib/grape-swagger.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'grape'
4
4
 
5
+ require 'grape-swagger/instance'
6
+
5
7
  require 'grape-swagger/version'
6
8
  require 'grape-swagger/endpoint'
7
9
  require 'grape-swagger/errors'
@@ -18,148 +20,152 @@ module GrapeSwagger
18
20
  autoload :Rake, 'grape-swagger/rake/oapi_tasks'
19
21
  end
20
22
 
21
- module Grape
22
- class API
23
- class << self
24
- attr_accessor :combined_routes, :combined_namespaces, :combined_namespace_routes, :combined_namespace_identifiers
25
-
26
- def add_swagger_documentation(options = {})
27
- documentation_class = create_documentation_class
23
+ module SwaggerRouting
24
+ private
28
25
 
29
- version_for(options)
30
- options = { target_class: self }.merge(options)
31
- @target_class = options[:target_class]
32
- auth_wrapper = options[:endpoint_auth_wrapper] || Class.new
26
+ def combine_routes(app, doc_klass)
27
+ app.routes.each do |route|
28
+ route_path = route.path
29
+ route_match = route_path.split(/^.*?#{route.prefix.to_s}/).last
30
+ next unless route_match
33
31
 
34
- use auth_wrapper if auth_wrapper.method_defined?(:before) && !middleware.flatten.include?(auth_wrapper)
32
+ route_match = route_match.match('\/([\w|-]*?)[\.\/\(]') || route_match.match('\/([\w|-]*)$')
33
+ next unless route_match
35
34
 
36
- documentation_class.setup(options)
37
- mount(documentation_class)
35
+ resource = route_match.captures.first
36
+ resource = '/' if resource.empty?
37
+ @target_class.combined_routes[resource] ||= []
38
+ next if doc_klass.hide_documentation_path && route.path.match(/#{doc_klass.mount_path}($|\/|\(\.)/)
38
39
 
39
- @target_class.combined_routes = {}
40
- combine_routes(@target_class, documentation_class)
40
+ @target_class.combined_routes[resource].unshift route
41
+ end
42
+ end
41
43
 
42
- @target_class.combined_namespaces = {}
43
- combine_namespaces(@target_class)
44
+ def determine_namespaced_routes(name, parent_route)
45
+ if parent_route.nil?
46
+ @target_class.combined_routes.values.flatten
47
+ else
48
+ parent_route.reject do |route|
49
+ !route_path_start_with?(route, name) || !route_instance_variable_equals?(route, name)
50
+ end
51
+ end
52
+ end
44
53
 
45
- @target_class.combined_namespace_routes = {}
46
- @target_class.combined_namespace_identifiers = {}
47
- combine_namespace_routes(@target_class.combined_namespaces)
54
+ def combine_namespace_routes(namespaces)
55
+ # iterate over each single namespace
56
+ namespaces.each_key do |name, _|
57
+ # get the parent route for the namespace
58
+ parent_route_name = extract_parent_route(name)
59
+ parent_route = @target_class.combined_routes[parent_route_name]
60
+ # fetch all routes that are within the current namespace
61
+ namespace_routes = determine_namespaced_routes(name, parent_route)
62
+
63
+ # default case when not explicitly specified or nested == true
64
+ standalone_namespaces = namespaces.reject do |_, ns|
65
+ !ns.options.key?(:swagger) ||
66
+ !ns.options[:swagger].key?(:nested) ||
67
+ ns.options[:swagger][:nested] != false
68
+ end
48
69
 
49
- exclusive_route_keys = @target_class.combined_routes.keys - @target_class.combined_namespaces.keys
50
- exclusive_route_keys.each do |key|
51
- @target_class.combined_namespace_routes[key] = @target_class.combined_routes[key]
52
- end
53
- documentation_class
70
+ parent_standalone_namespaces = standalone_namespaces.select { |ns_name, _| name.start_with?(ns_name) }
71
+ # add only to the main route
72
+ # if the namespace is not within any other namespace appearing as standalone resource
73
+ # rubocop:disable Style/Next
74
+ if parent_standalone_namespaces.empty?
75
+ # default option, append namespace methods to parent route
76
+ parent_route = @target_class.combined_namespace_routes.key?(parent_route_name)
77
+ @target_class.combined_namespace_routes[parent_route_name] = [] unless parent_route
78
+ @target_class.combined_namespace_routes[parent_route_name].push(*namespace_routes)
54
79
  end
80
+ # rubocop:enable Style/Next
81
+ end
82
+ end
55
83
 
56
- private
84
+ def extract_parent_route(name)
85
+ route_name = name.match(%r{^/?([^/]*).*$})[1]
86
+ return route_name unless route_name.include? ':'
57
87
 
58
- def version_for(options)
59
- options[:version] = version if version
60
- end
88
+ matches = name.match(/\/[a-z]+/)
89
+ matches.nil? ? route_name : matches[0].delete('/')
90
+ end
61
91
 
62
- def combine_routes(app, doc_klass)
63
- app.routes.each do |route|
64
- route_path = route.path
65
- route_match = route_path.split(/^.*?#{route.prefix.to_s}/).last
66
- next unless route_match
92
+ def route_instance_variable(route)
93
+ route.instance_variable_get(:@options)[:namespace]
94
+ end
67
95
 
68
- route_match = route_match.match('\/([\w|-]*?)[\.\/\(]') || route_match.match('\/([\w|-]*)$')
69
- next unless route_match
96
+ def route_instance_variable_equals?(route, name)
97
+ route_instance_variable(route) == "/#{name}" ||
98
+ route_instance_variable(route) == "/:version/#{name}"
99
+ end
70
100
 
71
- resource = route_match.captures.first
72
- resource = '/' if resource.empty?
73
- @target_class.combined_routes[resource] ||= []
74
- next if doc_klass.hide_documentation_path && route.path.match(/#{doc_klass.mount_path}($|\/|\(\.)/)
101
+ def route_path_start_with?(route, name)
102
+ route_prefix = route.prefix ? "/#{route.prefix}/#{name}" : "/#{name}"
103
+ route_versioned_prefix = route.prefix ? "/#{route.prefix}/:version/#{name}" : "/:version/#{name}"
75
104
 
76
- @target_class.combined_routes[resource].unshift route
77
- end
78
- end
105
+ route.path.start_with?(route_prefix, route_versioned_prefix)
106
+ end
107
+ end
79
108
 
80
- def combine_namespaces(app)
81
- app.endpoints.each do |endpoint|
82
- ns = endpoint.namespace_stackable(:namespace).last
109
+ module SwaggerDocumentationAdder
110
+ attr_accessor :combined_namespaces, :combined_namespace_identifiers
111
+ attr_accessor :combined_routes, :combined_namespace_routes
112
+ include SwaggerRouting
83
113
 
84
- # use the full namespace here (not the latest level only)
85
- # and strip leading slash
86
- mount_path = (endpoint.namespace_stackable(:mount_path) || []).join('/')
87
- full_namespace = (mount_path + endpoint.namespace).sub(/\/{2,}/, '/').sub(/^\//, '')
88
- @target_class.combined_namespaces[full_namespace] = ns if ns
114
+ def add_swagger_documentation(options = {})
115
+ documentation_class = create_documentation_class
89
116
 
90
- combine_namespaces(endpoint.options[:app]) if endpoint.options[:app]
91
- end
92
- end
117
+ version_for(options)
118
+ options = { target_class: self }.merge(options)
119
+ @target_class = options[:target_class]
120
+ auth_wrapper = options[:endpoint_auth_wrapper] || Class.new
93
121
 
94
- def determine_namespaced_routes(name, parent_route)
95
- if parent_route.nil?
96
- @target_class.combined_routes.values.flatten
97
- else
98
- parent_route.reject do |route|
99
- !route_path_start_with?(route, name) || !route_instance_variable_equals?(route, name)
100
- end
101
- end
102
- end
122
+ use auth_wrapper if auth_wrapper.method_defined?(:before) && !middleware.flatten.include?(auth_wrapper)
103
123
 
104
- def combine_namespace_routes(namespaces)
105
- # iterate over each single namespace
106
- namespaces.each_key do |name, _|
107
- # get the parent route for the namespace
108
- parent_route_name = extract_parent_route(name)
109
- parent_route = @target_class.combined_routes[parent_route_name]
110
- # fetch all routes that are within the current namespace
111
- namespace_routes = determine_namespaced_routes(name, parent_route)
112
-
113
- # default case when not explicitly specified or nested == true
114
- standalone_namespaces = namespaces.reject do |_, ns|
115
- !ns.options.key?(:swagger) ||
116
- !ns.options[:swagger].key?(:nested) ||
117
- ns.options[:swagger][:nested] != false
118
- end
119
-
120
- parent_standalone_namespaces = standalone_namespaces.select { |ns_name, _| name.start_with?(ns_name) }
121
- # add only to the main route
122
- # if the namespace is not within any other namespace appearing as standalone resource
123
- # rubocop:disable Style/Next
124
- if parent_standalone_namespaces.empty?
125
- # default option, append namespace methods to parent route
126
- parent_route = @target_class.combined_namespace_routes.key?(parent_route_name)
127
- @target_class.combined_namespace_routes[parent_route_name] = [] unless parent_route
128
- @target_class.combined_namespace_routes[parent_route_name].push(*namespace_routes)
129
- end
130
- # rubocop:enable Style/Next
131
- end
132
- end
124
+ documentation_class.setup(options)
125
+ mount(documentation_class)
133
126
 
134
- def extract_parent_route(name)
135
- route_name = name.match(%r{^/?([^/]*).*$})[1]
136
- return route_name unless route_name.include? ':'
127
+ @target_class.combined_routes = {}
128
+ combine_routes(@target_class, documentation_class)
137
129
 
138
- matches = name.match(/\/[a-z]+/)
139
- matches.nil? ? route_name : matches[0].delete('/')
140
- end
130
+ @target_class.combined_namespaces = {}
131
+ combine_namespaces(@target_class)
141
132
 
142
- def route_instance_variable(route)
143
- route.instance_variable_get(:@options)[:namespace]
144
- end
133
+ @target_class.combined_namespace_routes = {}
134
+ @target_class.combined_namespace_identifiers = {}
135
+ combine_namespace_routes(@target_class.combined_namespaces)
145
136
 
146
- def route_instance_variable_equals?(route, name)
147
- route_instance_variable(route) == "/#{name}" ||
148
- route_instance_variable(route) == "/:version/#{name}"
149
- end
137
+ exclusive_route_keys = @target_class.combined_routes.keys - @target_class.combined_namespaces.keys
138
+ exclusive_route_keys.each do |key|
139
+ @target_class.combined_namespace_routes[key] = @target_class.combined_routes[key]
140
+ end
141
+ documentation_class
142
+ end
150
143
 
151
- def route_path_start_with?(route, name)
152
- route_prefix = route.prefix ? "/#{route.prefix}/#{name}" : "/#{name}"
153
- route_versioned_prefix = route.prefix ? "/#{route.prefix}/:version/#{name}" : "/:version/#{name}"
144
+ private
154
145
 
155
- route.path.start_with?(route_prefix, route_versioned_prefix)
156
- end
146
+ def version_for(options)
147
+ options[:version] = version if version
148
+ end
157
149
 
158
- def create_documentation_class
159
- Class.new(Grape::API) do
160
- extend GrapeSwagger::DocMethods
161
- end
162
- end
150
+ def combine_namespaces(app)
151
+ app.endpoints.each do |endpoint|
152
+ ns = endpoint.namespace_stackable(:namespace).last
153
+
154
+ # use the full namespace here (not the latest level only)
155
+ # and strip leading slash
156
+ mount_path = (endpoint.namespace_stackable(:mount_path) || []).join('/')
157
+ full_namespace = (mount_path + endpoint.namespace).sub(/\/{2,}/, '/').sub(/^\//, '')
158
+ @target_class.combined_namespaces[full_namespace] = ns if ns
159
+
160
+ combine_namespaces(endpoint.options[:app]) if endpoint.options[:app]
161
+ end
162
+ end
163
+
164
+ def create_documentation_class
165
+ Class.new(GrapeInstance) do
166
+ extend GrapeSwagger::DocMethods
163
167
  end
164
168
  end
165
169
  end
170
+
171
+ GrapeInstance.extend(SwaggerDocumentationAdder)
@@ -14,7 +14,7 @@ module GrapeSwagger
14
14
 
15
15
  # required properties
16
16
  @parsed_param = {
17
- in: param_type(value_type),
17
+ in: param_type(value_type),
18
18
  name: settings[:full_name] || param
19
19
  }
20
20
 
@@ -25,15 +25,15 @@ module Grape
25
25
  # required keys for SwaggerObject
26
26
  def swagger_object(target_class, request, options)
27
27
  object = {
28
- info: info_object(options[:info].merge(version: options[:doc_version])),
29
- swagger: '2.0',
30
- produces: content_types_for(target_class),
31
- authorizations: options[:authorizations],
28
+ info: info_object(options[:info].merge(version: options[:doc_version])),
29
+ swagger: '2.0',
30
+ produces: content_types_for(target_class),
31
+ authorizations: options[:authorizations],
32
32
  securityDefinitions: options[:security_definitions],
33
- security: options[:security],
34
- host: GrapeSwagger::DocMethods::OptionalObject.build(:host, options, request),
35
- basePath: GrapeSwagger::DocMethods::OptionalObject.build(:base_path, options, request),
36
- schemes: options[:schemes].is_a?(String) ? [options[:schemes]] : options[:schemes]
33
+ security: options[:security],
34
+ host: GrapeSwagger::DocMethods::OptionalObject.build(:host, options, request),
35
+ basePath: GrapeSwagger::DocMethods::OptionalObject.build(:base_path, options, request),
36
+ schemes: options[:schemes].is_a?(String) ? [options[:schemes]] : options[:schemes]
37
37
  }
38
38
 
39
39
  GrapeSwagger::DocMethods::Extensions.add_extensions_to_root(options, object)
@@ -43,12 +43,12 @@ module Grape
43
43
  # building info object
44
44
  def info_object(infos)
45
45
  result = {
46
- title: infos[:title] || 'API title',
47
- description: infos[:description],
48
- termsOfServiceUrl: infos[:terms_of_service_url],
49
- contact: contact_object(infos),
50
- license: license_object(infos),
51
- version: infos[:version]
46
+ title: infos[:title] || 'API title',
47
+ description: infos[:description],
48
+ termsOfService: infos[:terms_of_service_url],
49
+ contact: contact_object(infos),
50
+ license: license_object(infos),
51
+ version: infos[:version]
52
52
  }
53
53
 
54
54
  GrapeSwagger::DocMethods::Extensions.add_extensions_to_info(infos, result)
@@ -61,7 +61,7 @@ module Grape
61
61
  def license_object(infos)
62
62
  {
63
63
  name: infos.delete(:license),
64
- url: infos.delete(:license_url)
64
+ url: infos.delete(:license_url)
65
65
  }.delete_if { |_, value| value.blank? }
66
66
  end
67
67
 
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ GrapeInstance = if defined? Grape::API::Instance
4
+ Grape::API::Instance
5
+ else
6
+ Grape::API
7
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrapeSwagger
4
- VERSION = '0.31.1'
4
+ VERSION = '0.32.0'
5
5
  end
@@ -3,15 +3,6 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe GrapeSwagger::DocMethods::DataType do
6
- before do
7
- stub_const 'MyEntity', Class.new
8
- MyEntity.class_eval do
9
- def self.entity_name
10
- 'MyInteger'
11
- end
12
- end
13
- end
14
-
15
6
  subject { described_class.call(value) }
16
7
 
17
8
  describe 'standards' do
@@ -26,78 +17,83 @@ describe GrapeSwagger::DocMethods::DataType do
26
17
  describe 'Hash' do
27
18
  let(:value) { { type: Hash } }
28
19
 
29
- it { expect(subject).to eql 'object' }
20
+ it { is_expected.to eq 'object' }
30
21
  end
31
22
 
32
23
  describe 'Multi types in a string' do
33
24
  let(:value) { { type: '[String, Integer]' } }
34
25
 
35
- it { expect(subject).to eql 'string' }
26
+ it { is_expected.to eq 'string' }
36
27
  end
37
28
 
38
29
  describe 'Multi types in a string stating with A' do
39
30
  let(:value) { { type: '[Apple, Orange]' } }
40
31
 
41
- it { expect(subject).to eql 'Apple' }
32
+ it { is_expected.to eq 'Apple' }
42
33
  end
43
34
 
44
35
  describe 'Multi types in array' do
45
36
  let(:value) { { type: [String, Integer] } }
46
37
 
47
- it { expect(subject).to eql 'string' }
38
+ it { is_expected.to eq 'string' }
48
39
  end
49
40
 
50
41
  describe 'Types in array with entity_name' do
42
+ before do
43
+ stub_const 'MyEntity', Class.new
44
+ allow(MyEntity).to receive(:entity_name).and_return 'MyInteger'
45
+ end
46
+
51
47
  let(:value) { { type: '[MyEntity]' } }
52
48
 
53
- it { expect(subject).to eql 'MyInteger' }
49
+ it { is_expected.to eq 'MyInteger' }
54
50
  end
55
51
 
56
52
  describe 'Rack::Multipart::UploadedFile' do
57
53
  let(:value) { { type: Rack::Multipart::UploadedFile } }
58
54
 
59
- it { expect(subject).to eql 'file' }
55
+ it { is_expected.to eq 'file' }
60
56
  end
61
57
 
62
58
  describe 'Virtus::Attribute::Boolean' do
63
59
  let(:value) { { type: Virtus::Attribute::Boolean } }
64
60
 
65
- it { expect(subject).to eql 'boolean' }
61
+ it { is_expected.to eq 'boolean' }
66
62
  end
67
63
 
68
64
  describe 'BigDecimal' do
69
65
  let(:value) { { type: BigDecimal } }
70
66
 
71
- it { expect(subject).to eql 'double' }
67
+ it { is_expected.to eq 'double' }
72
68
  end
73
69
 
74
70
  describe 'DateTime' do
75
71
  let(:value) { { type: DateTime } }
76
72
 
77
- it { expect(subject).to eql 'dateTime' }
73
+ it { is_expected.to eq 'dateTime' }
78
74
  end
79
75
 
80
76
  describe 'Numeric' do
81
77
  let(:value) { { type: Numeric } }
82
78
 
83
- it { expect(subject).to eql 'long' }
79
+ it { is_expected.to eq 'long' }
84
80
  end
85
81
 
86
82
  describe 'Symbol' do
87
83
  let(:value) { { type: Symbol } }
88
84
 
89
- it { expect(subject).to eql 'string' }
85
+ it { is_expected.to eq 'string' }
90
86
  end
91
87
 
92
88
  describe '[String]' do
93
89
  let(:value) { { type: '[String]' } }
94
90
 
95
- it { expect(subject).to eq('string') }
91
+ it { is_expected.to eq('string') }
96
92
  end
97
93
 
98
94
  describe '[Integer]' do
99
95
  let(:value) { { type: '[Integer]' } }
100
96
 
101
- it { expect(subject).to eq('integer') }
97
+ it { is_expected.to eq('integer') }
102
98
  end
103
99
  end
@@ -9,18 +9,20 @@ describe GrapeSwagger::Endpoint::ParamsParser do
9
9
  let(:parser) { described_class.new(params, settings) }
10
10
 
11
11
  describe '#parse_request_params' do
12
+ subject(:parse_request_params) { parser.parse_request_params }
13
+
12
14
  context 'when param is of array type' do
13
15
  let(:params) { [['param_1', { type: 'Array[String]' }]] }
14
16
 
15
17
  it 'adds is_array option' do
16
- expect(parser.parse_request_params).to eq('param_1' => { type: 'Array[String]', is_array: true })
18
+ expect(parse_request_params['param_1']).to eq(type: 'Array[String]', is_array: true)
17
19
  end
18
20
 
19
21
  context 'and array_use_braces setting set to true' do
20
22
  let(:settings) { { array_use_braces: true } }
21
23
 
22
24
  it 'adds braces to the param key' do
23
- expect(parser.parse_request_params.keys.first).to eq 'param_1[]'
25
+ expect(parse_request_params.keys.first).to eq 'param_1[]'
24
26
  end
25
27
  end
26
28
  end
@@ -29,7 +31,7 @@ describe GrapeSwagger::Endpoint::ParamsParser do
29
31
  let(:params) { [['param_1', { type: 'String' }]] }
30
32
 
31
33
  it 'does not change options' do
32
- expect(parser.parse_request_params).to eq('param_1' => { type: 'String' })
34
+ expect(parse_request_params['param_1']).to eq(type: 'String')
33
35
  end
34
36
 
35
37
  context 'and array_use_braces setting set to true' do
@@ -45,18 +47,18 @@ describe GrapeSwagger::Endpoint::ParamsParser do
45
47
  let(:params) { [['param_1', { type: 'Array' }], ['param_1[param_2]', { type: 'String' }]] }
46
48
 
47
49
  it 'skips root parameter' do
48
- expect(parser.parse_request_params).not_to have_key 'param_1'
50
+ is_expected.not_to have_key 'param_1'
49
51
  end
50
52
 
51
53
  it 'adds is_array option to the nested param' do
52
- expect(parser.parse_request_params).to eq('param_1[param_2]' => { type: 'String', is_array: true })
54
+ expect(parse_request_params['param_1[param_2]']).to eq(type: 'String', is_array: true)
53
55
  end
54
56
 
55
57
  context 'and array_use_braces setting set to true' do
56
58
  let(:settings) { { array_use_braces: true } }
57
59
 
58
60
  it 'adds braces to the param key' do
59
- expect(parser.parse_request_params.keys.first).to eq 'param_1[][param_2]'
61
+ expect(parse_request_params.keys.first).to eq 'param_1[][param_2]'
60
62
  end
61
63
  end
62
64
  end
@@ -65,18 +67,18 @@ describe GrapeSwagger::Endpoint::ParamsParser do
65
67
  let(:params) { [['param_1', { type: 'Hash' }], ['param_1[param_2]', { type: 'String' }]] }
66
68
 
67
69
  it 'skips root parameter' do
68
- expect(parser.parse_request_params).not_to have_key 'param_1'
70
+ is_expected.not_to have_key 'param_1'
69
71
  end
70
72
 
71
73
  it 'does not change options to the nested param' do
72
- expect(parser.parse_request_params).to eq('param_1[param_2]' => { type: 'String' })
74
+ expect(parse_request_params['param_1[param_2]']).to eq(type: 'String')
73
75
  end
74
76
 
75
77
  context 'and array_use_braces setting set to true' do
76
78
  let(:settings) { { array_use_braces: true } }
77
79
 
78
80
  it 'does not add braces to the param key' do
79
- expect(parser.parse_request_params.keys.first).to eq 'param_1[param_2]'
81
+ expect(parse_request_params.keys.first).to eq 'param_1[param_2]'
80
82
  end
81
83
  end
82
84
  end
@@ -597,7 +597,7 @@ describe GrapeSwagger::DocMethods::MoveParams do
597
597
  let(:definition) do
598
598
  {
599
599
  type: 'array',
600
- items: {
600
+ items: {
601
601
  type: 'object',
602
602
  properties: {
603
603
  description: 'Test description'
@@ -189,7 +189,7 @@ RSpec.shared_context 'entity swagger example' do
189
189
  'info' => {
190
190
  'title' => 'The API title to be displayed on the API homepage.',
191
191
  'description' => 'A description of the API.',
192
- 'termsOfServiceUrl' => 'www.The-URL-of-the-terms-and-service.com',
192
+ 'termsOfService' => 'www.The-URL-of-the-terms-and-service.com',
193
193
  'contact' => { 'name' => 'Contact name', 'email' => 'Contact@email.com', 'url' => 'Contact URL' },
194
194
  'license' => { 'name' => 'The name of the license.', 'url' => 'www.The-URL-of-the-license.org' },
195
195
  'version' => '0.0.1'
@@ -181,7 +181,7 @@ RSpec.shared_context 'mock swagger example' do
181
181
  'info' => {
182
182
  'title' => 'The API title to be displayed on the API homepage.',
183
183
  'description' => 'A description of the API.',
184
- 'termsOfServiceUrl' => 'www.The-URL-of-the-terms-and-service.com',
184
+ 'termsOfService' => 'www.The-URL-of-the-terms-and-service.com',
185
185
  'contact' => { 'name' => 'Contact name', 'email' => 'Contact@email.com', 'url' => 'Contact URL' },
186
186
  'license' => { 'name' => 'The name of the license.', 'url' => 'www.The-URL-of-the-license.org' },
187
187
  'version' => '0.0.1'
@@ -261,7 +261,7 @@ RSpec.shared_context 'representable swagger example' do
261
261
  'info' => {
262
262
  'title' => 'The API title to be displayed on the API homepage.',
263
263
  'description' => 'A description of the API.',
264
- 'termsOfServiceUrl' => 'www.The-URL-of-the-terms-and-service.com',
264
+ 'termsOfService' => 'www.The-URL-of-the-terms-and-service.com',
265
265
  'contact' => { 'name' => 'Contact name', 'email' => 'Contact@email.com', 'url' => 'Contact URL' },
266
266
  'license' => { 'name' => 'The name of the license.', 'url' => 'www.The-URL-of-the-license.org' },
267
267
  'version' => '0.0.1'
@@ -12,7 +12,7 @@ describe 'headers' do
12
12
 
13
13
  desc 'This returns something',
14
14
  failure: [{ code: 400, model: Entities::ApiError }],
15
- headers: {
15
+ headers: {
16
16
  'X-Rate-Limit-Limit' => {
17
17
  'description' => 'The number of allowed requests in the current period',
18
18
  'type' => 'integer'
@@ -128,7 +128,7 @@ describe 'Default API' do
128
128
  end
129
129
 
130
130
  it 'documents the terms of service url' do
131
- expect(subject['termsOfServiceUrl']).to eql('http://terms.com')
131
+ expect(subject['termsOfService']).to eql('http://terms.com')
132
132
  end
133
133
 
134
134
  it 'documents the contact email' do
@@ -3,52 +3,95 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'Grape::Endpoint#path_and_definitions' do
6
- let(:item) do
7
- Class.new(Grape::API) do
8
- version 'v1', using: :path
6
+ context 'when mounting an API once' do
7
+ let(:item) do
8
+ Class.new(Grape::API) do
9
+ version 'v1', using: :path
9
10
 
10
- resource :item do
11
- get '/'
11
+ resource :item do
12
+ get '/'
13
+ end
12
14
  end
13
15
  end
14
- end
15
16
 
16
- let(:api) do
17
- item_api = item
17
+ let(:api) do
18
+ item_api = item
18
19
 
19
- Class.new(Grape::API) do
20
- mount item_api
21
- add_swagger_documentation add_version: true
20
+ Class.new(Grape::API) do
21
+ mount item_api
22
+ add_swagger_documentation add_version: true
23
+ end
22
24
  end
23
- end
24
25
 
25
- let(:options) { { add_version: true } }
26
- let(:target_routes) { api.combined_namespace_routes }
26
+ let(:options) { { add_version: true } }
27
+ let(:target_routes) { api.combined_namespace_routes }
27
28
 
28
- subject { api.endpoints[0].path_and_definition_objects(target_routes, options) }
29
+ subject { api.endpoints[0].path_and_definition_objects(target_routes, options) }
29
30
 
30
- it 'is returning a versioned path' do
31
- expect(subject[0].keys[0]).to eq '/v1/item'
32
- end
31
+ it 'is returning a versioned path' do
32
+ expect(subject[0].keys[0]).to eq '/v1/item'
33
+ end
34
+
35
+ it 'tags the endpoint with the resource name' do
36
+ expect(subject.first['/v1/item'][:get][:tags]).to eq ['item']
37
+ end
38
+
39
+ context 'when custom tags are specified' do
40
+ let(:item) do
41
+ Class.new(Grape::API) do
42
+ version 'v1', using: :path
43
+
44
+ resource :item do
45
+ desc 'Item description', tags: ['special-item']
46
+ get '/'
47
+ end
48
+ end
49
+ end
33
50
 
34
- it 'tags the endpoint with the resource name' do
35
- expect(subject.first['/v1/item'][:get][:tags]).to eq ['item']
51
+ it 'tags the endpoint with the custom tags' do
52
+ expect(subject.first['/v1/item'][:get][:tags]).to eq ['special-item']
53
+ end
54
+ end
36
55
  end
37
56
 
38
- context 'when custom tags are specified' do
57
+ context 'when mounting an API more than once', if: GrapeVersion.satisfy?('>= 1.2.0') do
39
58
  let(:item) do
40
59
  Class.new(Grape::API) do
41
- version 'v1', using: :path
42
-
43
60
  resource :item do
44
- desc 'Item description', tags: ['special-item']
61
+ desc 'Item description', tags: [configuration[:tag] || 'item']
45
62
  get '/'
46
63
  end
47
64
  end
48
65
  end
49
66
 
50
- it 'tags the endpoint with the custom tags' do
51
- expect(subject.first['/v1/item'][:get][:tags]).to eq ['special-item']
67
+ let(:api) do
68
+ item_api = item
69
+ Class.new(Grape::API) do
70
+ version 'v1', using: :path do
71
+ mount item_api
72
+ end
73
+
74
+ version 'v2', using: :path do
75
+ mount item_api, with: { tag: 'special-item' }
76
+ end
77
+
78
+ add_swagger_documentation add_version: true
79
+ end
80
+ end
81
+
82
+ let(:options) { { add_version: true } }
83
+ let(:target_routes) { api.combined_namespace_routes }
84
+
85
+ subject { api.endpoints[0].path_and_definition_objects(target_routes, options) }
86
+
87
+ it 'retrieves both apis respecting their configured tags' do
88
+ expect(subject.first['/v1/item'][:get][:tags]).to eq ['item']
89
+ expect(subject.first['/v2/item'][:get][:tags]).to eq ['special-item']
90
+ end
91
+
92
+ it 'retrieves both apis with descriptions' do
93
+ expect(subject.first['/v1/item'][:get][:description]).to eq 'Item description'
94
+ expect(subject.first['/v2/item'][:get][:description]).to eq 'Item description'
52
95
  end
53
96
  end
54
97
  end
@@ -2,16 +2,16 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Grape::API do
5
+ describe GrapeInstance do
6
6
  it 'added combined-routes' do
7
- expect(Grape::API).to respond_to :combined_routes
7
+ expect(described_class).to respond_to :combined_routes
8
8
  end
9
9
 
10
10
  it 'added add_swagger_documentation' do
11
- expect(Grape::API).to respond_to :add_swagger_documentation
11
+ expect(described_class).to respond_to :add_swagger_documentation
12
12
  end
13
13
 
14
14
  it 'added combined-namespaces' do
15
- expect(Grape::API).to respond_to :combined_namespaces
15
+ expect(described_class).to respond_to :combined_namespaces
16
16
  end
17
17
  end
@@ -41,7 +41,7 @@ module Extension
41
41
  description[:auth] = { scopes: scopes }
42
42
  end
43
43
 
44
- Grape::API.extend self
44
+ GrapeInstance.extend self
45
45
  end
46
46
 
47
47
  describe 'a guarded api endpoint' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-swagger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.31.1
4
+ version: 0.32.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Vandecasteele
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-23 00:00:00.000000000 Z
11
+ date: 2018-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grape
@@ -72,6 +72,7 @@ files:
72
72
  - lib/grape-swagger/endpoint.rb
73
73
  - lib/grape-swagger/endpoint/params_parser.rb
74
74
  - lib/grape-swagger/errors.rb
75
+ - lib/grape-swagger/instance.rb
75
76
  - lib/grape-swagger/model_parsers.rb
76
77
  - lib/grape-swagger/rake/oapi_tasks.rb
77
78
  - lib/grape-swagger/version.rb
@@ -189,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
190
  version: '0'
190
191
  requirements: []
191
192
  rubyforge_project:
192
- rubygems_version: 2.7.6
193
+ rubygems_version: 2.7.8
193
194
  signing_key:
194
195
  specification_version: 4
195
196
  summary: Add auto generated documentation to your Grape API that can be displayed