grape-swagger 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: beb6baac3bba57a4fd27f01c8129fbd128c0c88426f1408784f1e77ef870c65a
4
- data.tar.gz: 88234909ace085c8b63f0534630ae8856eb15d383bee856c9fcc57079d0060a1
3
+ metadata.gz: eae164875a188218b1eb4e0e3a53039f8e661f3dd115b4cc9a6f415b3a92e64b
4
+ data.tar.gz: 6962782ea370ff7b4f84c62ed77f2fe1e7232332f3a238bce4c5af5b62eb1534
5
5
  SHA512:
6
- metadata.gz: 3b50e2b60fb3d4a1876bac4587f740c27a624c02726153746dc79e76fb1a233d04a3b1b15844bf65a337484d551ac6ea84b04c85c1537138dfc4327149cbb654
7
- data.tar.gz: 32a0e9014bf782a0f5a5417a307bf9325986d7d9df662e73174525792e9103d2a3ec3c4f8b3d7fbdc72829d7514ba299dd62adb361085020f37b104f9a29ee25
6
+ metadata.gz: 8b56b026ba97a2308579737c43daf0e9f619df0c91c511e424b533f99105faec83f9ddbcb3dd2f3d98866bffdbdecb13e652f302424f54ec4095c4605405319c
7
+ data.tar.gz: 2e88c630ade44d4c9395a18e690cad717f5a6ba6e6daae81624d0b7e6347f06c9d7d07ce85f16b5eb99ea25c1a716127cd8aac17c1367823ded3bd84151dbc47
@@ -11,6 +11,9 @@ AllCops:
11
11
  Layout/EmptyLinesAroundArguments:
12
12
  Enabled: false
13
13
 
14
+ Layout/EmptyLinesAroundAttributeAccessor:
15
+ Enabled: true
16
+
14
17
  Layout/FirstHashElementIndentation:
15
18
  EnforcedStyle: consistent
16
19
 
@@ -24,6 +27,12 @@ Layout/SpaceAroundMethodCallOperator:
24
27
 
25
28
  # Lint stuff
26
29
  #
30
+ Lint/DeprecatedOpenSSLConstant:
31
+ Enabled: true
32
+
33
+ Lint/MixedRegexpCaptureTypes:
34
+ Enabled: true
35
+
27
36
  Lint/RaiseException:
28
37
  Enabled: true
29
38
 
@@ -39,6 +48,9 @@ Metrics/BlockLength:
39
48
  Metrics/ClassLength:
40
49
  Max: 300
41
50
 
51
+ Metrics/CyclomaticComplexity:
52
+ Max: 17
53
+
42
54
  Metrics/MethodLength:
43
55
  Exclude:
44
56
  - spec/**/*
@@ -64,3 +76,15 @@ Style/HashTransformValues:
64
76
 
65
77
  Style/RegexpLiteral:
66
78
  Enabled: false
79
+
80
+ Style/RedundantFetchBlock:
81
+ Enabled: true
82
+
83
+ Style/RedundantRegexpCharacterClass:
84
+ Enabled: true
85
+
86
+ Style/RedundantRegexpEscape:
87
+ Enabled: true
88
+
89
+ Style/SlicingWithRange:
90
+ Enabled: false
@@ -33,3 +33,5 @@ jobs:
33
33
  - rvm: 2.4.10
34
34
  - rvm: ruby-head
35
35
  - rvm: jruby-head
36
+
37
+ - env: GRAPE_VERSION=HEAD
@@ -9,6 +9,19 @@
9
9
  * Your contribution here.
10
10
 
11
11
 
12
+ ### 1.2.0 (July 1, 2020)
13
+
14
+ #### Features
15
+
16
+ * [#794](https://github.com/ruby-grape/grape-swagger/pull/794): Allow `entity_name` to be inherited, fixes issue #659 - [@urkle](https://github.com/urkle).
17
+ * [#793](https://github.com/ruby-grape/grape-swagger/pull/793): Features/inheritance and discriminator - [@MaximeRDY](https://github.com/MaximeRDY).
18
+
19
+ #### Fixes
20
+
21
+ * [#798](https://github.com/ruby-grape/grape-swagger/pull/798): Modify full entity name separator - [@GarrettB71](https://github.com/GarrettB71).
22
+ * [#796](https://github.com/ruby-grape/grape-swagger/pull/796): Support grape 1.4.0 - [@thedanielhanke](https://github.com/thedanielhanke).
23
+
24
+
12
25
  ### 1.1.0 (April 20, 2020)
13
26
 
14
27
  #### Features
data/Gemfile CHANGED
@@ -14,6 +14,7 @@ gem 'grape', case version = ENV['GRAPE_VERSION'] || '>= 1.3.0'
14
14
  end
15
15
 
16
16
  gem ENV['MODEL_PARSER'] if ENV.key?('MODEL_PARSER')
17
+
17
18
  group :development, :test do
18
19
  gem 'bundler'
19
20
  gem 'grape-entity'
@@ -26,12 +27,16 @@ group :development, :test do
26
27
  gem 'rake'
27
28
  gem 'rdoc'
28
29
  gem 'rspec', '~> 3.9'
29
- gem 'rubocop', '~> 0.82', require: false
30
+ gem 'rubocop', '~> 0.85', require: false
30
31
  end
31
32
 
32
33
  group :test do
33
34
  gem 'coveralls_reborn', require: false
34
- gem 'grape-swagger-entity'
35
+
35
36
  gem 'ruby-grape-danger', '~> 0.1.1', require: false
36
37
  gem 'simplecov', require: false
38
+
39
+ unless ENV['MODEL_PARSER'] == 'grape-swagger-entity'
40
+ gem 'grape-swagger-entity', git: 'https://github.com/ruby-grape/grape-swagger-entity'
41
+ end
37
42
  end
data/README.md CHANGED
@@ -43,16 +43,16 @@ This screenshot is based on the [Hussars](https://github.com/LeFnord/hussars) sa
43
43
 
44
44
  The following versions of grape, grape-entity and grape-swagger can currently be used together.
45
45
 
46
- grape-swagger | swagger spec | grape | grape-entity | representable |
47
- --------------|--------------|-------------------------|--------------|---------------|
48
- 0.10.5 | 1.2 | >= 0.10.0 ... <= 0.14.0 | < 0.5.0 | n/a |
49
- 0.11.0 | 1.2 | >= 0.16.2 | < 0.5.0 | n/a |
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 ... <= 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 |
54
- 0.34.0 | 2.0 | >= 0.16.2 ... < 1.3.0 | >= 0.5.0 | >= 2.4.1 |
55
- >= 1.0.0 | 2.0 | >= 1.3.0 | >= 0.5.0 | >= 2.4.1 |
46
+ | grape-swagger | swagger spec | grape | grape-entity | representable |
47
+ | ------------- | ------------ | ----------------------- | ------------ | ------------- |
48
+ | 0.10.5 | 1.2 | >= 0.10.0 ... <= 0.14.0 | < 0.5.0 | n/a |
49
+ | 0.11.0 | 1.2 | >= 0.16.2 | < 0.5.0 | n/a |
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 ... <= 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 |
54
+ | 0.34.0 | 2.0 | >= 0.16.2 ... < 1.3.0 | >= 0.5.0 | >= 2.4.1 |
55
+ | >= 1.0.0 | 2.0 | >= 1.3.0 | >= 0.5.0 | >= 2.4.1 |
56
56
 
57
57
 
58
58
  ## Swagger-Spec <a name="swagger-spec"></a>
@@ -1381,6 +1381,94 @@ module API
1381
1381
  end
1382
1382
  ```
1383
1383
 
1384
+ #### Inheritance with allOf and discriminator
1385
+ ```ruby
1386
+ module Entities
1387
+ class Pet < Grape::Entity
1388
+ expose :type, documentation: {
1389
+ type: 'string',
1390
+ is_discriminator: true,
1391
+ required: true
1392
+ }
1393
+ expose :name, documentation: {
1394
+ type: 'string',
1395
+ required: true
1396
+ }
1397
+ end
1398
+
1399
+ class Cat < Pet
1400
+ expose :huntingSkill, documentation: {
1401
+ type: 'string',
1402
+ description: 'The measured skill for hunting',
1403
+ default: 'lazy',
1404
+ values: %w[
1405
+ clueless
1406
+ lazy
1407
+ adventurous
1408
+ aggressive
1409
+ ]
1410
+ }
1411
+ end
1412
+ end
1413
+ ```
1414
+
1415
+ Should generate this definitions:
1416
+ ```JSON
1417
+ {
1418
+ "definitions": {
1419
+ "Pet": {
1420
+ "type": "object",
1421
+ "discriminator": "petType",
1422
+ "properties": {
1423
+ "name": {
1424
+ "type": "string"
1425
+ },
1426
+ "petType": {
1427
+ "type": "string"
1428
+ }
1429
+ },
1430
+ "required": [
1431
+ "name",
1432
+ "petType"
1433
+ ]
1434
+ },
1435
+ "Cat": {
1436
+ "description": "A representation of a cat",
1437
+ "allOf": [
1438
+ {
1439
+ "$ref": "#/definitions/Pet"
1440
+ },
1441
+ {
1442
+ "type": "object",
1443
+ "properties": {
1444
+ "huntingSkill": {
1445
+ "type": "string",
1446
+ "description": "The measured skill for hunting",
1447
+ "default": "lazy",
1448
+ "enum": [
1449
+ "clueless",
1450
+ "lazy",
1451
+ "adventurous",
1452
+ "aggressive"
1453
+ ]
1454
+ },
1455
+ "petType": {
1456
+ "type": "string",
1457
+ "enum": ["Cat"]
1458
+ }
1459
+ },
1460
+ "required": [
1461
+ "huntingSkill",
1462
+ "petType"
1463
+ ]
1464
+ }
1465
+ ]
1466
+ }
1467
+ }
1468
+ }
1469
+ ```
1470
+
1471
+
1384
1472
 
1385
1473
 
1386
1474
  ## Securing the Swagger UI <a name="oauth"></a>
@@ -1,5 +1,31 @@
1
1
  ## Upgrading Grape-swagger
2
2
 
3
+ ### Upgrading to >= 1.2.0
4
+
5
+ - The entity_name class method is now called on parent classes for inherited entities. Now you can do this
6
+
7
+ ```ruby
8
+ module Some::Long::Module
9
+ class Base < Grape::Entity
10
+ # ... other shared logic
11
+ def self.entity_name
12
+ "V2::#{self.to_s.demodulize}"
13
+ end
14
+ end
15
+
16
+ def MyEntity < Base
17
+ # ....
18
+ end
19
+
20
+ def OtherEntity < Base
21
+ # revert back to the default behavior by hiding the method
22
+ private_class_method :entity_name
23
+ end
24
+ end
25
+ ```
26
+
27
+ - Full class name is modified to use `_` separator (e.g. `A_B_C` instead of `A::B::C`).
28
+
3
29
  ### Upgrading to >= 1.1.0
4
30
 
5
31
  Full class name is used for referencing entity by default (e.g. `A::B::C` instead of just `C`). `Entity` and `Entities` suffixes and prefixes are omitted (e.g. if entity name is `Entities::SomeScope::MyFavourite::Entity` only `SomeScope::MyFavourite` will be used).
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.license = 'MIT'
15
15
 
16
16
  s.required_ruby_version = '>= 2.4'
17
- s.add_runtime_dependency 'grape', '~> 1.3.0'
17
+ s.add_runtime_dependency 'grape', '~> 1.3'
18
18
 
19
19
  s.files = `git ls-files`.split("\n")
20
20
  s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
@@ -109,6 +109,7 @@ end
109
109
  module SwaggerDocumentationAdder
110
110
  attr_accessor :combined_namespaces, :combined_namespace_identifiers
111
111
  attr_accessor :combined_routes, :combined_namespace_routes
112
+
112
113
  include SwaggerRouting
113
114
 
114
115
  def add_swagger_documentation(options = {})
@@ -4,8 +4,8 @@ module GrapeSwagger
4
4
  module DocMethods
5
5
  class BuildModelDefinition
6
6
  class << self
7
- def build(model, properties, required)
8
- definition = { type: 'object', properties: properties }
7
+ def build(model, properties, required, other_def_properties = {})
8
+ definition = { type: 'object', properties: properties }.merge(other_def_properties)
9
9
 
10
10
  if required.nil?
11
11
  required_attrs = required_attributes(model)
@@ -17,6 +17,57 @@ module GrapeSwagger
17
17
  definition
18
18
  end
19
19
 
20
+ def parse_params_from_model(parsed_response, model, model_name)
21
+ if parsed_response.is_a?(Hash) && parsed_response.keys.first == :allOf
22
+ refs_or_models = parsed_response[:allOf]
23
+ parsed = parse_refs_and_models(refs_or_models, model)
24
+
25
+ {
26
+ allOf: parsed
27
+ }
28
+ else
29
+ properties, required = parsed_response
30
+ unless properties&.any?
31
+ raise GrapeSwagger::Errors::SwaggerSpec,
32
+ "Empty model #{model_name}, swagger 2.0 doesn't support empty definitions."
33
+ end
34
+ properties, other_def_properties = parse_properties(properties)
35
+
36
+ build(
37
+ model, properties, required, other_def_properties
38
+ )
39
+ end
40
+ end
41
+
42
+ def parse_properties(properties)
43
+ other_properties = {}
44
+
45
+ discriminator_key, discriminator_value =
46
+ properties.find do |_key, value|
47
+ value[:documentation].try(:[], :is_discriminator)
48
+ end
49
+
50
+ if discriminator_key
51
+ discriminator_value.delete(:documentation)
52
+ properties[discriminator_key] = discriminator_value
53
+
54
+ other_properties[:discriminator] = discriminator_key
55
+ end
56
+
57
+ [properties, other_properties]
58
+ end
59
+
60
+ def parse_refs_and_models(refs_or_models, model)
61
+ refs_or_models.map do |ref_or_models|
62
+ if ref_or_models.is_a?(Hash) && ref_or_models.keys.first == '$ref'
63
+ ref_or_models
64
+ else
65
+ properties, required = ref_or_models
66
+ GrapeSwagger::DocMethods::BuildModelDefinition.build(model, properties, required)
67
+ end
68
+ end
69
+ end
70
+
20
71
  private
21
72
 
22
73
  def required_attributes(model)
@@ -48,14 +48,14 @@ module GrapeSwagger
48
48
  end
49
49
 
50
50
  def parse_entity_name(model)
51
- if model.methods(false).include?(:entity_name)
51
+ if model.respond_to?(:entity_name)
52
52
  model.entity_name
53
53
  elsif model.to_s.end_with?('::Entity', '::Entities')
54
- model.to_s.split('::')[0..-2].join('::')
54
+ model.to_s.split('::')[0..-2].join('_')
55
55
  elsif model.to_s.start_with?('Entity::', 'Entities::', 'Representable::')
56
- model.to_s.split('::')[1..-1].join('::')
56
+ model.to_s.split('::')[1..-1].join('_')
57
57
  else
58
- model.to_s
58
+ model.to_s.split('::').join('_')
59
59
  end
60
60
  end
61
61
 
@@ -16,8 +16,8 @@ module GrapeSwagger
16
16
 
17
17
  def manipulate(path)
18
18
  operation = path.split('/').map(&:capitalize).join
19
- operation.gsub!(/\-(\w)/, &:upcase).delete!('-') if operation[/\-(\w)/]
20
- operation.gsub!(/\_(\w)/, &:upcase).delete!('_') if operation.include?('_')
19
+ operation.gsub!(/-(\w)/, &:upcase).delete!('-') if operation[/-(\w)/]
20
+ operation.gsub!(/_(\w)/, &:upcase).delete!('_') if operation.include?('_')
21
21
  operation.gsub!(/\.(\w)/, &:upcase).delete!('.') if operation[/\.(\w)/]
22
22
  if path.include?('{')
23
23
  operation.gsub!(/\{(\w)/, &:upcase)
@@ -77,6 +77,19 @@ module GrapeSwagger
77
77
 
78
78
  param_type ||= value_type[:param_type]
79
79
 
80
+ array_items = parse_array_item(
81
+ definitions,
82
+ type,
83
+ value_type
84
+ )
85
+
86
+ @parsed_param[:in] = param_type || 'formData'
87
+ @parsed_param[:items] = array_items
88
+ @parsed_param[:type] = 'array'
89
+ @parsed_param[:collectionFormat] = collection_format if DataType.collections.include?(collection_format)
90
+ end
91
+
92
+ def parse_array_item(definitions, type, value_type)
80
93
  array_items = {}
81
94
  if definitions[value_type[:data_type]]
82
95
  array_items['$ref'] = "#/definitions/#{@parsed_param[:type]}"
@@ -91,10 +104,7 @@ module GrapeSwagger
91
104
 
92
105
  array_items[:default] = value_type[:default] if value_type[:default].present?
93
106
 
94
- @parsed_param[:in] = param_type || 'formData'
95
- @parsed_param[:items] = array_items
96
- @parsed_param[:type] = 'array'
97
- @parsed_param[:collectionFormat] = collection_format if DataType.collections.include?(collection_format)
107
+ array_items
98
108
  end
99
109
 
100
110
  def document_additional_properties(settings)
@@ -196,10 +196,7 @@ module Grape
196
196
  end
197
197
 
198
198
  def response_object(route, options)
199
- codes = http_codes_from_route(route)
200
- codes.map! { |x| x.is_a?(Array) ? { code: x[0], message: x[1], model: x[2], examples: x[3], headers: x[4] } : x }
201
-
202
- codes.each_with_object({}) do |value, memo|
199
+ codes(route).each_with_object({}) do |value, memo|
203
200
  value[:message] ||= ''
204
201
  memo[value[:code]] = { description: value[:message] }
205
202
 
@@ -225,6 +222,12 @@ module Grape
225
222
  end
226
223
  end
227
224
 
225
+ def codes(route)
226
+ http_codes_from_route(route).map do |x|
227
+ x.is_a?(Array) ? { code: x[0], message: x[1], model: x[2], examples: x[3], headers: x[4] } : x
228
+ end
229
+ end
230
+
228
231
  def success_code?(code)
229
232
  status = code.is_a?(Array) ? code.first : code[:code]
230
233
  status.between?(200, 299)
@@ -340,12 +343,10 @@ module Grape
340
343
  parser = GrapeSwagger.model_parsers.find(model)
341
344
  raise GrapeSwagger::Errors::UnregisteredParser, "No parser registered for #{model_name}." unless parser
342
345
 
343
- properties, required = parser.new(model, self).call
344
- unless properties&.any?
345
- raise GrapeSwagger::Errors::SwaggerSpec,
346
- "Empty model #{model_name}, swagger 2.0 doesn't support empty definitions."
347
- end
348
- @definitions[model_name] = GrapeSwagger::DocMethods::BuildModelDefinition.build(model, properties, required)
346
+ parsed_response = parser.new(model, self).call
347
+
348
+ @definitions[model_name] =
349
+ GrapeSwagger::DocMethods::BuildModelDefinition.parse_params_from_model(parsed_response, model, model_name)
349
350
 
350
351
  model_name
351
352
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrapeSwagger
4
- VERSION = '1.1.0'
4
+ VERSION = '1.2.0'
5
5
  end
@@ -35,5 +35,5 @@ describe '#427 nested entity given as string' do
35
35
  JSON.parse(last_response.body)['definitions']
36
36
  end
37
37
 
38
- specify { expect(subject.keys).to include 'RoleEntity', 'Permission::WithoutRole' }
38
+ specify { expect(subject.keys).to include 'RoleEntity', 'Permission_WithoutRole' }
39
39
  end
@@ -55,6 +55,8 @@ describe 'definition names' do
55
55
  class Class7
56
56
  class SeventhEntity < Class6::SixthEntity
57
57
  expose :seventh_thing
58
+
59
+ private_class_method :entity_name
58
60
  end
59
61
  end
60
62
  end
@@ -82,11 +84,11 @@ describe 'definition names' do
82
84
  JSON.parse(last_response.body)['definitions']
83
85
  end
84
86
 
85
- specify { expect(subject).to include 'TestDefinition::DummyEntities::WithVeryLongName::AnotherGroupingModule::Class1' }
86
- specify { expect(subject).to include 'TestDefinition::DummyEntities::WithVeryLongName::AnotherGroupingModule::Class2' }
87
+ specify { expect(subject).to include 'TestDefinition_DummyEntities_WithVeryLongName_AnotherGroupingModule_Class1' }
88
+ specify { expect(subject).to include 'TestDefinition_DummyEntities_WithVeryLongName_AnotherGroupingModule_Class2' }
87
89
  specify { expect(subject).to include 'FooKlass' }
88
- specify { expect(subject).to include 'TestDefinition::DummyEntities::WithVeryLongName::AnotherGroupingModule::Class4::FourthEntity' }
89
- specify { expect(subject).to include 'TestDefinition::DummyEntities::WithVeryLongName::AnotherGroupingModule::Class5::FithEntity' }
90
+ specify { expect(subject).to include 'TestDefinition_DummyEntities_WithVeryLongName_AnotherGroupingModule_Class4_FourthEntity' }
91
+ specify { expect(subject).to include 'TestDefinition_DummyEntities_WithVeryLongName_AnotherGroupingModule_Class5_FithEntity' }
90
92
  specify { expect(subject).to include 'BarKlass' }
91
- specify { expect(subject).to include 'TestDefinition::DummyEntities::WithVeryLongName::AnotherGroupingModule::Class7::SeventhEntity' }
93
+ specify { expect(subject).to include 'TestDefinition_DummyEntities_WithVeryLongName_AnotherGroupingModule_Class7_SeventhEntity' }
92
94
  end
@@ -49,6 +49,18 @@ describe GrapeSwagger::DocMethods::DataType do
49
49
  it { is_expected.to eq 'MyInteger' }
50
50
  end
51
51
 
52
+ describe 'Types in array with inherited entity_name' do
53
+ before do
54
+ stub_const 'EntityBase', Class.new
55
+ allow(EntityBase).to receive(:entity_name).and_return 'MyInteger'
56
+ stub_const 'MyEntity', Class.new(EntityBase)
57
+ end
58
+
59
+ let(:value) { { type: '[MyEntity]' } }
60
+
61
+ it { is_expected.to eq 'MyInteger' }
62
+ end
63
+
52
64
  describe 'Rack::Multipart::UploadedFile' do
53
65
  let(:value) { { type: Rack::Multipart::UploadedFile } }
54
66
 
@@ -189,7 +189,7 @@ describe 'setting of param type, such as `query`, `path`, `formData`, `body`, `h
189
189
  'type' => 'object',
190
190
  'properties' => {
191
191
  'data' => {
192
- '$ref' => '#/definitions/NestedModule::ApiResponse',
192
+ '$ref' => '#/definitions/NestedModule_ApiResponse',
193
193
  'description' => 'request data'
194
194
  }
195
195
  },
@@ -207,7 +207,7 @@ describe 'setting of param type, such as `query`, `path`, `formData`, `body`, `h
207
207
  end
208
208
 
209
209
  specify do
210
- expect(subject['definitions']['NestedModule::ApiResponse']).not_to be_nil
210
+ expect(subject['definitions']['NestedModule_ApiResponse']).not_to be_nil
211
211
  end
212
212
 
213
213
  specify do
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Inheritance and Discriminator' do
6
+ before :all do
7
+ module InheritanceTest
8
+ module Entities
9
+ # example from https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#models-with-polymorphism-supports
10
+ class Pet < Grape::Entity
11
+ expose :type, documentation: {
12
+ type: 'string',
13
+ is_discriminator: true,
14
+ required: true
15
+ }
16
+ expose :name, documentation: {
17
+ type: 'string',
18
+ required: true
19
+ }
20
+ end
21
+
22
+ class Cat < Pet
23
+ expose :huntingSkill, documentation: {
24
+ type: 'string',
25
+ description: 'The measured skill for hunting',
26
+ default: 'lazy',
27
+ values: %w[
28
+ clueless
29
+ lazy
30
+ adventurous
31
+ aggressive
32
+ ]
33
+ }
34
+ end
35
+ end
36
+ class NameApi < Grape::API
37
+ add_swagger_documentation models: [Entities::Pet, Entities::Cat]
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'Parent model' do
43
+ let(:app) { InheritanceTest::NameApi }
44
+
45
+ subject do
46
+ get '/swagger_doc'
47
+ JSON.parse(last_response.body)['definitions']
48
+ end
49
+
50
+ specify do
51
+ subject['InheritanceTest_Entities_Pet'].key?('discriminator')
52
+ subject['InheritanceTest_Entities_Pet']['discriminator'] = 'type'
53
+ subject['InheritanceTest_Entities_Cat'].key?('allOf')
54
+ end
55
+ end
56
+ end
@@ -22,6 +22,20 @@ describe 'referenceEntity' do
22
22
  expose :title, documentation: { type: 'string', desc: 'Title of the kind.' }
23
23
  expose :something, documentation: { type: Something, desc: 'Something interesting.' }
24
24
  end
25
+
26
+ class Base < Grape::Entity
27
+ def self.entity_name
28
+ parts = to_s.split('::')
29
+
30
+ "MyAPI::#{parts.last}"
31
+ end
32
+
33
+ expose :title, documentation: { type: 'string', desc: 'Title of the parent.' }
34
+ end
35
+
36
+ class Child < Base
37
+ expose :child, documentation: { type: 'string', desc: 'Child property.' }
38
+ end
25
39
  end
26
40
 
27
41
  class ResponseModelApi < Grape::API
@@ -40,6 +54,16 @@ describe 'referenceEntity' do
40
54
  present kind, with: Entities::Kind
41
55
  end
42
56
 
57
+ desc 'This returns a child entity',
58
+ entity: Entities::Child,
59
+ http_codes: [
60
+ { code: 200, message: 'OK', model: Entities::Child }
61
+ ]
62
+ get '/child' do
63
+ child = OpenStruct.new text: 'child'
64
+ present child, with: Entities::Child
65
+ end
66
+
43
67
  add_swagger_documentation # models: [MyAPI::Entities::Something, MyAPI::Entities::Kind]
44
68
  end
45
69
  end
@@ -49,36 +73,57 @@ describe 'referenceEntity' do
49
73
  MyAPI::ResponseModelApi
50
74
  end
51
75
 
52
- subject do
53
- get '/swagger_doc/kind'
54
- JSON.parse(last_response.body)
76
+ describe 'kind' do
77
+ subject do
78
+ get '/swagger_doc/kind'
79
+ JSON.parse(last_response.body)
80
+ end
81
+
82
+ it 'should document specified models' do
83
+ expect(subject['paths']['/kind']['get']['parameters']).to eq [{
84
+ 'in' => 'query',
85
+ 'name' => 'something',
86
+ 'description' => 'Something interesting.',
87
+ 'type' => 'SomethingCustom',
88
+ 'required' => false
89
+ }]
90
+
91
+ expect(subject['definitions'].keys).to include 'SomethingCustom'
92
+ expect(subject['definitions']['SomethingCustom']).to eq(
93
+ 'type' => 'object', 'properties' => { 'text' => { 'type' => 'string', 'description' => 'Content of something.' } }
94
+ )
95
+
96
+ expect(subject['definitions'].keys).to include 'KindCustom'
97
+ expect(subject['definitions']['KindCustom']).to eq(
98
+ 'type' => 'object',
99
+ 'properties' => {
100
+ 'title' => { 'type' => 'string', 'description' => 'Title of the kind.' },
101
+ 'something' => {
102
+ '$ref' => '#/definitions/SomethingCustom',
103
+ 'description' => 'Something interesting.'
104
+ }
105
+ },
106
+ 'description' => 'This returns kind and something or an error'
107
+ )
108
+ end
55
109
  end
56
110
 
57
- it 'should document specified models' do
58
- expect(subject['paths']['/kind']['get']['parameters']).to eq [{
59
- 'in' => 'query',
60
- 'name' => 'something',
61
- 'description' => 'Something interesting.',
62
- 'type' => 'SomethingCustom',
63
- 'required' => false
64
- }]
65
-
66
- expect(subject['definitions'].keys).to include 'SomethingCustom'
67
- expect(subject['definitions']['SomethingCustom']).to eq(
68
- 'type' => 'object', 'properties' => { 'text' => { 'type' => 'string', 'description' => 'Content of something.' } }
69
- )
70
-
71
- expect(subject['definitions'].keys).to include 'KindCustom'
72
- expect(subject['definitions']['KindCustom']).to eq(
73
- 'type' => 'object',
74
- 'properties' => {
75
- 'title' => { 'type' => 'string', 'description' => 'Title of the kind.' },
76
- 'something' => {
77
- '$ref' => '#/definitions/SomethingCustom',
78
- 'description' => 'Something interesting.'
79
- }
80
- },
81
- 'description' => 'This returns kind and something or an error'
82
- )
111
+ describe 'child' do
112
+ subject do
113
+ get '/swagger_doc/child'
114
+ JSON.parse(last_response.body)
115
+ end
116
+
117
+ it 'should document specified models' do
118
+ expect(subject['definitions'].keys).to include 'MyAPI::Child'
119
+ expect(subject['definitions']['MyAPI::Child']).to eq(
120
+ 'type' => 'object',
121
+ 'properties' => {
122
+ 'title' => { 'type' => 'string', 'description' => 'Title of the parent.' },
123
+ 'child' => { 'type' => 'string', 'description' => 'Child property.' }
124
+ },
125
+ 'description' => 'This returns a child entity'
126
+ )
127
+ end
83
128
  end
84
129
  end
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: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Vandecasteele
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-20 00:00:00.000000000 Z
11
+ date: 2020-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grape
@@ -16,15 +16,15 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.3.0
19
+ version: '1.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.3.0
27
- description:
26
+ version: '1.3'
27
+ description:
28
28
  email:
29
29
  - tim.vandecasteele@gmail.com
30
30
  executables: []
@@ -156,6 +156,7 @@ files:
156
156
  - spec/swagger_v2/guarded_endpoint_spec.rb
157
157
  - spec/swagger_v2/hide_api_spec.rb
158
158
  - spec/swagger_v2/host_spec.rb
159
+ - spec/swagger_v2/inheritance_and_discriminator_spec.rb
159
160
  - spec/swagger_v2/mount_override_api_spec.rb
160
161
  - spec/swagger_v2/mounted_target_class_spec.rb
161
162
  - spec/swagger_v2/namespace_tags_prefix_spec.rb
@@ -179,7 +180,7 @@ homepage: https://github.com/ruby-grape/grape-swagger
179
180
  licenses:
180
181
  - MIT
181
182
  metadata: {}
182
- post_install_message:
183
+ post_install_message:
183
184
  rdoc_options: []
184
185
  require_paths:
185
186
  - lib
@@ -195,7 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
196
  version: '0'
196
197
  requirements: []
197
198
  rubygems_version: 3.1.2
198
- signing_key:
199
+ signing_key:
199
200
  specification_version: 4
200
201
  summary: Add auto generated documentation to your Grape API that can be displayed
201
202
  with Swagger.
@@ -279,6 +280,7 @@ test_files:
279
280
  - spec/swagger_v2/guarded_endpoint_spec.rb
280
281
  - spec/swagger_v2/hide_api_spec.rb
281
282
  - spec/swagger_v2/host_spec.rb
283
+ - spec/swagger_v2/inheritance_and_discriminator_spec.rb
282
284
  - spec/swagger_v2/mount_override_api_spec.rb
283
285
  - spec/swagger_v2/mounted_target_class_spec.rb
284
286
  - spec/swagger_v2/namespace_tags_prefix_spec.rb