grape-swagger 0.7.2 → 0.8.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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rubocop.yml +36 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +3 -0
  7. data/CHANGELOG.md +90 -0
  8. data/CONTRIBUTING.md +126 -0
  9. data/Gemfile +1 -21
  10. data/LICENSE.txt +1 -1
  11. data/README.md +397 -0
  12. data/RELEASING.md +80 -0
  13. data/Rakefile +6 -23
  14. data/UPGRADING.md +47 -0
  15. data/grape-swagger.gemspec +26 -84
  16. data/lib/grape-swagger.rb +237 -111
  17. data/lib/grape-swagger/errors.rb +9 -0
  18. data/lib/grape-swagger/markdown.rb +23 -0
  19. data/lib/grape-swagger/markdown/kramdown_adapter.rb +37 -0
  20. data/lib/grape-swagger/markdown/redcarpet_adapter.rb +89 -0
  21. data/lib/grape-swagger/version.rb +3 -0
  22. data/spec/api_description_spec.rb +41 -0
  23. data/spec/api_global_models_spec.rb +76 -0
  24. data/spec/api_models_spec.rb +190 -93
  25. data/spec/default_api_spec.rb +31 -36
  26. data/spec/form_params_spec.rb +56 -53
  27. data/spec/grape-swagger_helper_spec.rb +88 -49
  28. data/spec/grape-swagger_spec.rb +7 -5
  29. data/spec/hide_api_spec.rb +58 -55
  30. data/spec/markdown/kramdown_adapter_spec.rb +38 -0
  31. data/spec/markdown/markdown_spec.rb +27 -0
  32. data/spec/markdown/redcarpet_adapter_spec.rb +81 -0
  33. data/spec/namespaced_api_spec.rb +47 -0
  34. data/spec/non_default_api_spec.rb +372 -222
  35. data/spec/response_model_spec.rb +80 -0
  36. data/spec/simple_mounted_api_spec.rb +113 -118
  37. data/spec/spec_helper.rb +0 -1
  38. data/spec/version_spec.rb +8 -0
  39. data/test/api.rb +62 -0
  40. data/test/config.ru +10 -2
  41. data/test/splines.png +0 -0
  42. metadata +145 -91
  43. data/.rvmrc +0 -48
  44. data/CHANGELOG.markdown +0 -55
  45. data/Gemfile.lock +0 -94
  46. data/README.markdown +0 -168
  47. data/VERSION +0 -1
  48. data/test/nested_api.rb +0 -30
@@ -1,10 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Default API" do
4
-
3
+ describe 'Default API' do
5
4
  context 'with no additional options' do
6
- before :all do
7
- class NotAMountedApi < Grape::API
5
+ def app
6
+ Class.new(Grape::API) do
8
7
  format :json
9
8
  desc 'This gets something.'
10
9
  get '/something' do
@@ -14,37 +13,36 @@ describe "Default API" do
14
13
  end
15
14
  end
16
15
 
17
- def app; NotAMountedApi; end
18
-
19
- it "should document something" do
16
+ subject do
20
17
  get '/swagger_doc'
21
- JSON.parse(last_response.body).should == {
22
- "apiVersion" => "0.1",
23
- "swaggerVersion" => "1.2",
24
- "basePath" => "http://example.org",
25
- "info" => {},
26
- "produces" => ["application/json"],
27
- "operations" => [],
28
- "apis" => [
29
- { "path" => "/swagger_doc/something.{format}" },
30
- { "path" => "/swagger_doc/swagger_doc.{format}" }
18
+ JSON.parse(last_response.body)
19
+ end
20
+
21
+ it 'documents api' do
22
+ expect(subject).to eq(
23
+ 'apiVersion' => '0.1',
24
+ 'swaggerVersion' => '1.2',
25
+ 'info' => {},
26
+ 'produces' => ['application/json'],
27
+ 'apis' => [
28
+ { 'path' => '/something.{format}', 'description' => 'Operations about somethings' },
29
+ { 'path' => '/swagger_doc.{format}', 'description' => 'Operations about swagger_docs' }
31
30
  ]
32
- }
31
+ )
33
32
  end
34
-
35
- context "path inside the apis array" do
36
- it "should start with a forward slash" do
37
- get '/swagger_doc'
38
- JSON.parse(last_response.body)['apis'].each do |api|
39
- api['path'].should start_with "/"
33
+
34
+ context 'path inside the apis array' do
35
+ it 'starts with a forward slash' do
36
+ subject['apis'].each do |api|
37
+ expect(api['path']).to start_with '/'
40
38
  end
41
39
  end
42
40
  end
43
41
  end
44
42
 
45
- context 'with API info' do
46
- before :all do
47
- class ApiInfoTest < Grape::API
43
+ context 'with additional info' do
44
+ def app
45
+ Class.new(Grape::API) do
48
46
  format :json
49
47
  add_swagger_documentation info: {
50
48
  title: 'My API Title',
@@ -55,20 +53,18 @@ describe "Default API" do
55
53
  contact: 'support@test.com'
56
54
  }
57
55
  end
58
- get '/swagger_doc'
59
56
  end
60
57
 
61
- def app; ApiInfoTest; end
62
-
63
58
  subject do
59
+ get '/swagger_doc'
64
60
  JSON.parse(last_response.body)['info']
65
61
  end
66
62
 
67
- it 'should document API title' do
63
+ it 'documents API title' do
68
64
  expect(subject['title']).to eql('My API Title')
69
65
  end
70
66
 
71
- it 'should document API description' do
67
+ it 'documents API description' do
72
68
  expect(subject['description']).to eql('A description of my API')
73
69
  end
74
70
 
@@ -76,17 +72,16 @@ describe "Default API" do
76
72
  expect(subject['license']).to eql('Apache 2')
77
73
  end
78
74
 
79
- it 'should document the license url' do
75
+ it 'documents the license url' do
80
76
  expect(subject['licenseUrl']).to eql('http://test.com')
81
77
  end
82
78
 
83
- it 'should document the terms of service url' do
79
+ it 'documents the terms of service url' do
84
80
  expect(subject['termsOfServiceUrl']).to eql('http://terms.com')
85
81
  end
86
82
 
87
- it 'should document the contact email' do
83
+ it 'documents the contact email' do
88
84
  expect(subject['contact']).to eql('support@test.com')
89
85
  end
90
86
  end
91
-
92
87
  end
@@ -1,29 +1,30 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Form Params" do
4
-
5
- before :all do
6
- class FormParamApi < Grape::API
3
+ describe 'Form Params' do
4
+ def app
5
+ Class.new(Grape::API) do
7
6
  format :json
8
7
 
9
8
  params do
10
- requires :name, type: String, desc: "name of item"
9
+ requires :name, type: String, desc: 'name of item'
11
10
  end
12
11
  post '/items' do
13
12
  {}
14
13
  end
15
14
 
16
15
  params do
17
- requires :id, type: Integer, desc: "id of item"
18
- requires :name, type: String, desc: "name of item"
16
+ requires :id, type: Integer, desc: 'id of item'
17
+ requires :name, type: String, desc: 'name of item'
18
+ requires :conditions, type: Integer, desc: 'conditions of item', values: [1, 2, 3]
19
19
  end
20
20
  put '/items/:id' do
21
21
  {}
22
22
  end
23
23
 
24
24
  params do
25
- requires :id, type: Integer, desc: "id of item"
26
- requires :name, type: String, desc: "name of item"
25
+ requires :id, type: Integer, desc: 'id of item'
26
+ requires :name, type: String, desc: 'name of item'
27
+ optional :conditions, type: String, desc: 'conditions of item', values: proc { %w(1 2) }
27
28
  end
28
29
  patch '/items/:id' do
29
30
  {}
@@ -33,51 +34,53 @@ describe "Form Params" do
33
34
  end
34
35
  end
35
36
 
36
- def app; FormParamApi; end
37
-
38
- it "retrieves the documentation form params" do
37
+ subject do
39
38
  get '/swagger_doc/items.json'
39
+ JSON.parse(last_response.body)
40
+ end
40
41
 
41
- JSON.parse(last_response.body).should == {
42
- "apiVersion" => "0.1",
43
- "swaggerVersion" => "1.2",
44
- "resourcePath" => "",
45
- "basePath"=>"http://example.org",
46
- "apis" => [
47
- {
48
- "path" => "/items.{format}",
49
- "operations" => [
50
- {
51
- "produces" => ["application/json"],
52
- "notes" => "",
53
- "summary" => "",
54
- "nickname" => "POST-items---format-",
55
- "httpMethod" => "POST",
56
- "parameters" => [ { "paramType" => "form", "name" => "name", "description" => "name of item", "type" => "String", "dataType" => "String", "required" => true } ]
57
- }
58
- ]
59
- }, {
60
- "path" => "/items/{id}.{format}",
61
- "operations" => [
62
- {
63
- "produces" => ["application/json"],
64
- "notes" => "",
65
- "summary" => "",
66
- "nickname" => "PUT-items--id---format-",
67
- "httpMethod" => "PUT",
68
- "parameters" => [ { "paramType" => "path", "name" => "id", "description" => "id of item", "type" => "Integer", "dataType" => "Integer", "required" => true }, { "paramType" => "form", "name" => "name", "description" => "name of item", "type" => "String", "dataType" => "String", "required" => true } ]
69
- },
70
- {
71
- "produces" => ["application/json"],
72
- "notes" => "",
73
- "summary" => "",
74
- "nickname" => "PATCH-items--id---format-",
75
- "httpMethod" => "PATCH",
76
- "parameters" => [ { "paramType" => "path", "name" => "id", "description" => "id of item", "type" => "Integer", "dataType" => "Integer", "required" => true }, { "paramType" => "form", "name" => "name", "description" => "name of item", "type" => "String", "dataType" => "String", "required" => true } ]
77
- }
78
- ]
79
- }
80
- ]
81
- }
42
+ it 'retrieves the documentation form params' do
43
+ expect(subject['apis']).to eq([
44
+ {
45
+ 'path' => '/items.{format}',
46
+ 'operations' => [
47
+ {
48
+ 'notes' => '',
49
+ 'summary' => '',
50
+ 'nickname' => 'POST-items---format-',
51
+ 'method' => 'POST',
52
+ 'parameters' => [{ 'paramType' => 'form', 'name' => 'name', 'description' => 'name of item', 'type' => 'string', 'required' => true, 'allowMultiple' => false }],
53
+ 'type' => 'void'
54
+ }
55
+ ]
56
+ }, {
57
+ 'path' => '/items/{id}.{format}',
58
+ 'operations' => [
59
+ {
60
+ 'notes' => '',
61
+ 'summary' => '',
62
+ 'nickname' => 'PUT-items--id---format-',
63
+ 'method' => 'PUT',
64
+ 'parameters' => [
65
+ { 'paramType' => 'path', 'name' => 'id', 'description' => 'id of item', 'type' => 'integer', 'required' => true, 'allowMultiple' => false, 'format' => 'int32' },
66
+ { 'paramType' => 'form', 'name' => 'name', 'description' => 'name of item', 'type' => 'string', 'required' => true, 'allowMultiple' => false },
67
+ { 'paramType' => 'form', 'name' => 'conditions', 'description' => 'conditions of item', 'type' => 'integer', 'required' => true, 'allowMultiple' => false, 'format' => 'int32', 'enum' => [1, 2, 3] }
68
+ ],
69
+ 'type' => 'void'
70
+ },
71
+ {
72
+ 'notes' => '',
73
+ 'summary' => '',
74
+ 'nickname' => 'PATCH-items--id---format-',
75
+ 'method' => 'PATCH',
76
+ 'parameters' => [
77
+ { 'paramType' => 'path', 'name' => 'id', 'description' => 'id of item', 'type' => 'integer', 'required' => true, 'allowMultiple' => false, 'format' => 'int32' },
78
+ { 'paramType' => 'form', 'name' => 'name', 'description' => 'name of item', 'type' => 'string', 'required' => true, 'allowMultiple' => false },
79
+ { 'paramType' => 'form', 'name' => 'conditions', 'description' => 'conditions of item', 'type' => 'string', 'required' => false, 'allowMultiple' => false, 'enum' => %w(1 2) }
80
+ ],
81
+ 'type' => 'void'
82
+ }
83
+ ]
84
+ }])
82
85
  end
83
86
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "helpers" do
3
+ describe 'helpers' do
4
4
 
5
5
  before :all do
6
6
  class HelperTestAPI < Grape::API
@@ -8,98 +8,137 @@ describe "helpers" do
8
8
  end
9
9
  end
10
10
 
11
- before :each do
12
- @api = Object.new
11
+ subject do
12
+ api = Object.new
13
13
 
14
14
  # after injecting grape-swagger into the Test API we get the helper methods
15
15
  # back from the first endpoint's class (the API mounted by grape-swagger
16
16
  # to serve the swagger_doc
17
17
 
18
- @api.extend HelperTestAPI.endpoints.first.options[:app].helpers
18
+ api.extend HelperTestAPI.endpoints.first.options[:app].helpers
19
+ api
19
20
  end
20
21
 
21
- context "parsing parameters" do
22
- it "parses params as query strings for a GET" do
22
+ context 'parsing parameters' do
23
+ it 'parses params as query strings for a GET' do
23
24
  params = {
24
- name: { type: 'String', desc: "A name", required: true, defaultValue: 'default' },
25
+ name: { type: 'String', desc: 'A name', required: true, default: 'default' },
25
26
  level: 'max'
26
27
  }
27
- path = "/coolness"
28
- method = "GET"
29
- @api.parse_params(params, path, method).should == [
30
- { paramType: "query", name: :name, description: "A name", type: "String", dataType: "String", required: true, defaultValue: 'default' },
31
- { paramType: "query", name: :level, description: "", type: "String", dataType: "String", required: false }
28
+ path = '/coolness'
29
+ method = 'GET'
30
+ expect(subject.parse_params(params, path, method)).to eq [
31
+ { paramType: 'query', name: :name, description: 'A name', type: 'string', required: true, allowMultiple: false, defaultValue: 'default' },
32
+ { paramType: 'query', name: :level, description: '', type: 'string', required: false, allowMultiple: false }
32
33
  ]
33
34
  end
34
35
 
35
- it "parses params as form for a POST" do
36
+ it 'parses params as form for a POST' do
36
37
  params = {
37
- name: { type: 'String', :desc => "A name", required: true },
38
+ name: { type: 'String', desc: 'A name', required: true },
38
39
  level: 'max'
39
40
  }
40
- path = "/coolness"
41
- method = "POST"
42
- @api.parse_params(params, path, method).should == [
43
- { paramType: "form", name: :name, description: "A name", type: "String", dataType: "String", required: true },
44
- { paramType: "form", name: :level, description: "", type: "String", dataType: "String", required: false }
41
+ path = '/coolness'
42
+ method = 'POST'
43
+ expect(subject.parse_params(params, path, method)).to eq [
44
+ { paramType: 'form', name: :name, description: 'A name', type: 'string', required: true, allowMultiple: false },
45
+ { paramType: 'form', name: :level, description: '', type: 'string', required: false, allowMultiple: false }
45
46
  ]
46
47
  end
47
48
 
48
- context "custom type" do
49
+ it 'parses file param' do
50
+ params = {
51
+ rack: {
52
+ type: 'Rack::Multipart::UploadedFile',
53
+ desc: 'rack file',
54
+ datafile: 'content',
55
+ required: true
56
+ },
57
+ rails: {
58
+ type: 'Hash',
59
+ desc: 'rails file',
60
+ datafile: 'content',
61
+ required: true
62
+ }
63
+ }
64
+ path = '/coolness'
65
+ method = 'POST'
66
+ expect(subject.parse_params(params, path, method)).to eq [
67
+ {
68
+ paramType: 'body',
69
+ name: :rack,
70
+ description: 'rack file',
71
+ type: 'File',
72
+ required: true,
73
+ allowMultiple: false
74
+ },
75
+ {
76
+ paramType: 'body',
77
+ name: :rails,
78
+ description: 'rails file',
79
+ type: 'File',
80
+ required: true,
81
+ allowMultiple: false
82
+ }
83
+ ]
84
+
85
+ end
86
+
87
+ context 'custom type' do
49
88
  before :all do
50
89
  class CustomType
51
90
  end
52
91
  end
53
- it "parses a custom parameters" do
92
+ it 'parses a custom parameters' do
54
93
  params = {
55
- option: { type: CustomType, desc: "Custom option" }
94
+ option: { type: CustomType, desc: 'Custom option' }
56
95
  }
57
- path = "/coolness"
58
- method = "GET"
59
- @api.parse_params(params, path, method).should == [
60
- { paramType: "query", name: :option, description: "Custom option", type: "CustomType", dataType: "CustomType", required: false }
96
+ path = '/coolness'
97
+ method = 'GET'
98
+ expect(subject.parse_params(params, path, method)).to eq [
99
+ { paramType: 'query', name: :option, description: 'Custom option', type: 'CustomType', required: false, allowMultiple: false }
61
100
  ]
62
101
  end
63
102
  end
64
103
 
65
104
  end
66
105
 
67
- context "parsing the path" do
68
- it "parses the path" do
69
- path = ":abc/def(.:format)"
70
- @api.parse_path(path, nil).should == "{abc}/def.{format}"
106
+ context 'parsing the path' do
107
+ it 'parses the path' do
108
+ path = ':abc/def(.:format)'
109
+ expect(subject.parse_path(path, nil)).to eq '{abc}/def.{format}'
71
110
  end
72
111
 
73
- it "parses a path that has vars with underscores in the name" do
74
- path = "abc/:def_g(.:format)"
75
- @api.parse_path(path, nil).should == "abc/{def_g}.{format}"
112
+ it 'parses a path that has vars with underscores in the name' do
113
+ path = 'abc/:def_g(.:format)'
114
+ expect(subject.parse_path(path, nil)).to eq 'abc/{def_g}.{format}'
76
115
  end
77
116
 
78
- it "parses a path that has vars with numbers in the name" do
79
- path = "abc/:sha1(.:format)"
80
- @api.parse_path(path, nil).should == "abc/{sha1}.{format}"
117
+ it 'parses a path that has vars with numbers in the name' do
118
+ path = 'abc/:sha1(.:format)'
119
+ expect(subject.parse_path(path, nil)).to eq 'abc/{sha1}.{format}'
81
120
  end
82
121
 
83
- it "parses a path that has multiple variables" do
84
- path1 = "abc/:def/:geh(.:format)"
85
- path2 = "abc/:def:geh(.:format)"
86
- @api.parse_path(path1, nil).should == "abc/{def}/{geh}.{format}"
87
- @api.parse_path(path2, nil).should == "abc/{def}{geh}.{format}"
122
+ it 'parses a path that has multiple variables' do
123
+ path1 = 'abc/:def/:geh(.:format)'
124
+ path2 = 'abc/:def:geh(.:format)'
125
+ expect(subject.parse_path(path1, nil)).to eq 'abc/{def}/{geh}.{format}'
126
+ expect(subject.parse_path(path2, nil)).to eq 'abc/{def}{geh}.{format}'
88
127
  end
89
128
 
90
- it "parses the path with a specified version" do
91
- path = ":abc/{version}/def(.:format)"
92
- @api.parse_path(path, 'v1').should == "{abc}/v1/def.{format}"
129
+ it 'parses the path with a specified version' do
130
+ path = ':abc/{version}/def(.:format)'
131
+ expect(subject.parse_path(path, 'v1')).to eq '{abc}/v1/def.{format}'
93
132
  end
94
133
  end
95
134
 
96
- context "parsing header parameters" do
97
- it "parses params for the header" do
135
+ context 'parsing header parameters' do
136
+ it 'parses params for the header' do
98
137
  params = {
99
- "XAuthToken" => { description: "A required header.", required: true, defaultValue: 'default' }
138
+ 'XAuthToken' => { description: 'A required header.', required: true, default: 'default' }
100
139
  }
101
- @api.parse_header_params(params).should == [
102
- { paramType: "header", name: "XAuthToken", description: "A required header.", type: "String", dataType: "String", required: true, defaultValue: 'default' }
140
+ expect(subject.parse_header_params(params)).to eq [
141
+ { paramType: 'header', name: 'XAuthToken', description: 'A required header.', type: 'String', required: true, defaultValue: 'default' }
103
142
  ]
104
143
  end
105
144
  end
@@ -1,13 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Grape::API do
4
-
5
- it "added combined-routes" do
6
- Grape::API.should respond_to :combined_routes
4
+ it 'added combined-routes' do
5
+ expect(Grape::API).to respond_to :combined_routes
7
6
  end
8
7
 
9
- it "added add_swagger_documentation" do
10
- Grape::API.should respond_to :add_swagger_documentation
8
+ it 'added add_swagger_documentation' do
9
+ expect(Grape::API).to respond_to :add_swagger_documentation
11
10
  end
12
11
 
12
+ it 'added combined-namespaces' do
13
+ expect(Grape::API).to respond_to :combined_namespaces
14
+ end
13
15
  end