grape 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -2
- data/.rubocop_todo.yml +80 -0
- data/.travis.yml +2 -2
- data/CHANGELOG.md +21 -2
- data/Gemfile +1 -6
- data/Guardfile +1 -5
- data/README.md +110 -27
- data/Rakefile +1 -1
- data/UPGRADING.md +35 -0
- data/grape.gemspec +5 -2
- data/lib/grape.rb +20 -4
- data/lib/grape/api.rb +25 -467
- data/lib/grape/api/helpers.rb +7 -0
- data/lib/grape/dsl/callbacks.rb +27 -0
- data/lib/grape/dsl/configuration.rb +27 -0
- data/lib/grape/dsl/helpers.rb +86 -0
- data/lib/grape/dsl/inside_route.rb +227 -0
- data/lib/grape/dsl/middleware.rb +33 -0
- data/lib/grape/dsl/parameters.rb +79 -0
- data/lib/grape/dsl/request_response.rb +152 -0
- data/lib/grape/dsl/routing.rb +172 -0
- data/lib/grape/dsl/validations.rb +29 -0
- data/lib/grape/endpoint.rb +6 -226
- data/lib/grape/error_formatter/base.rb +28 -0
- data/lib/grape/error_formatter/json.rb +2 -0
- data/lib/grape/error_formatter/txt.rb +2 -0
- data/lib/grape/error_formatter/xml.rb +2 -0
- data/lib/grape/exceptions/base.rb +6 -0
- data/lib/grape/exceptions/validation.rb +3 -3
- data/lib/grape/exceptions/validation_errors.rb +19 -6
- data/lib/grape/locale/en.yml +5 -3
- data/lib/grape/middleware/auth/base.rb +28 -12
- data/lib/grape/middleware/auth/dsl.rb +35 -0
- data/lib/grape/middleware/auth/strategies.rb +24 -0
- data/lib/grape/middleware/auth/strategy_info.rb +15 -0
- data/lib/grape/validations.rb +3 -92
- data/lib/grape/validations/at_least_one_of.rb +25 -0
- data/lib/grape/validations/coerce.rb +2 -2
- data/lib/grape/validations/exactly_one_of.rb +2 -2
- data/lib/grape/validations/mutual_exclusion.rb +2 -2
- data/lib/grape/validations/presence.rb +1 -1
- data/lib/grape/validations/regexp.rb +1 -1
- data/lib/grape/validations/values.rb +1 -1
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api/helpers_spec.rb +36 -0
- data/spec/grape/api_spec.rb +72 -19
- data/spec/grape/dsl/callbacks_spec.rb +44 -0
- data/spec/grape/dsl/configuration_spec.rb +37 -0
- data/spec/grape/dsl/helpers_spec.rb +54 -0
- data/spec/grape/dsl/inside_route_spec.rb +222 -0
- data/spec/grape/dsl/middleware_spec.rb +40 -0
- data/spec/grape/dsl/parameters_spec.rb +108 -0
- data/spec/grape/dsl/request_response_spec.rb +123 -0
- data/spec/grape/dsl/routing_spec.rb +132 -0
- data/spec/grape/dsl/validations_spec.rb +55 -0
- data/spec/grape/endpoint_spec.rb +60 -11
- data/spec/grape/entity_spec.rb +9 -4
- data/spec/grape/exceptions/validation_errors_spec.rb +31 -1
- data/spec/grape/middleware/auth/base_spec.rb +34 -0
- data/spec/grape/middleware/auth/dsl_spec.rb +53 -0
- data/spec/grape/middleware/auth/strategies_spec.rb +81 -0
- data/spec/grape/middleware/error_spec.rb +33 -1
- data/spec/grape/middleware/exception_spec.rb +13 -0
- data/spec/grape/validations/at_least_one_of_spec.rb +63 -0
- data/spec/grape/validations/exactly_one_of_spec.rb +1 -1
- data/spec/grape/validations/presence_spec.rb +159 -122
- data/spec/grape/validations/zh-CN.yml +1 -1
- data/spec/grape/validations_spec.rb +77 -15
- data/spec/spec_helper.rb +1 -0
- data/spec/support/endpoint_faker.rb +23 -0
- metadata +93 -15
- data/lib/grape/middleware/auth/basic.rb +0 -13
- data/lib/grape/middleware/auth/digest.rb +0 -13
- data/lib/grape/middleware/auth/oauth2.rb +0 -83
- data/spec/grape/middleware/auth/basic_spec.rb +0 -31
- data/spec/grape/middleware/auth/digest_spec.rb +0 -47
- data/spec/grape/middleware/auth/oauth2_spec.rb +0 -135
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Grape
|
4
|
+
module DSL
|
5
|
+
module MiddlewareSpec
|
6
|
+
class Dummy
|
7
|
+
include Grape::DSL::Middleware
|
8
|
+
|
9
|
+
def self.settings
|
10
|
+
@settings ||= Grape::Util::HashStack.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.imbue(key, value)
|
14
|
+
settings.imbue(key, value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
describe Middleware do
|
19
|
+
subject { Class.new(MiddlewareSpec::Dummy) }
|
20
|
+
let(:proc) { ->() {} }
|
21
|
+
|
22
|
+
describe '.use' do
|
23
|
+
it 'adds a middleware' do
|
24
|
+
expect(subject).to receive(:imbue).with(:middleware, [[:my_middleware, :arg1, proc]])
|
25
|
+
|
26
|
+
subject.use :my_middleware, :arg1, &proc
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.middleware' do
|
32
|
+
it 'returns the middleware stack' do
|
33
|
+
subject.use :my_middleware, :arg1, &proc
|
34
|
+
|
35
|
+
expect(subject.middleware).to eq [[:my_middleware, :arg1, proc]]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Grape
|
4
|
+
module DSL
|
5
|
+
module ParametersSpec
|
6
|
+
class Dummy
|
7
|
+
include Grape::DSL::Parameters
|
8
|
+
|
9
|
+
def validate_attributes(*args)
|
10
|
+
@validate_attributes = *args
|
11
|
+
end
|
12
|
+
|
13
|
+
# rubocop:disable TrivialAccessors
|
14
|
+
def validate_attrs
|
15
|
+
@validate_attributes
|
16
|
+
end
|
17
|
+
# rubocop:enable TrivialAccessors
|
18
|
+
|
19
|
+
def push_declared_params(*args)
|
20
|
+
@push_declared_params = args
|
21
|
+
end
|
22
|
+
|
23
|
+
# rubocop:disable TrivialAccessors
|
24
|
+
def push_declared_paras
|
25
|
+
@push_declared_params
|
26
|
+
end
|
27
|
+
# rubocop:enable TrivialAccessors
|
28
|
+
|
29
|
+
def validates(*args)
|
30
|
+
@validates = *args
|
31
|
+
end
|
32
|
+
|
33
|
+
# rubocop:disable TrivialAccessors
|
34
|
+
def valids
|
35
|
+
@validates
|
36
|
+
end
|
37
|
+
# rubocop:enable TrivialAccessors
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe Parameters do
|
42
|
+
subject { ParametersSpec::Dummy.new }
|
43
|
+
|
44
|
+
xdescribe '#use' do
|
45
|
+
it 'does some thing'
|
46
|
+
end
|
47
|
+
|
48
|
+
xdescribe '#use_scope' do
|
49
|
+
it 'does some thing'
|
50
|
+
end
|
51
|
+
|
52
|
+
xdescribe '#includes' do
|
53
|
+
it 'does some thing'
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#requires' do
|
57
|
+
it 'adds a required parameter' do
|
58
|
+
subject.requires :id, type: Integer, desc: 'Identity.'
|
59
|
+
|
60
|
+
expect(subject.validate_attrs).to eq([[:id], { type: Integer, desc: 'Identity.' }])
|
61
|
+
expect(subject.push_declared_paras).to eq([[:id]])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#optional' do
|
66
|
+
it 'adds an optional parameter' do
|
67
|
+
subject.optional :id, type: Integer, desc: 'Identity.'
|
68
|
+
|
69
|
+
expect(subject.valids).to eq([[:id], { type: Integer, desc: 'Identity.' }])
|
70
|
+
expect(subject.push_declared_paras).to eq([[:id]])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#mutually_exclusive' do
|
75
|
+
it 'adds an mutally exclusive parameter validation' do
|
76
|
+
subject.mutually_exclusive :media, :audio
|
77
|
+
|
78
|
+
expect(subject.valids).to eq([[:media, :audio], { mutual_exclusion: true }])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#exactly_one_of' do
|
83
|
+
it 'adds an exactly of one parameter validation' do
|
84
|
+
subject.exactly_one_of :media, :audio
|
85
|
+
|
86
|
+
expect(subject.valids).to eq([[:media, :audio], { exactly_one_of: true }])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#at_least_one_of' do
|
91
|
+
it 'adds an at least one of parameter validation' do
|
92
|
+
subject.at_least_one_of :media, :audio
|
93
|
+
|
94
|
+
expect(subject.valids).to eq([[:media, :audio], { at_least_one_of: true }])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
xdescribe '#group' do
|
99
|
+
it 'does some thing'
|
100
|
+
end
|
101
|
+
|
102
|
+
xdescribe '#params' do
|
103
|
+
it 'does some thing'
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Grape
|
4
|
+
module DSL
|
5
|
+
module RequestResponseSpec
|
6
|
+
class Dummy
|
7
|
+
include Grape::DSL::RequestResponse
|
8
|
+
|
9
|
+
def self.settings
|
10
|
+
@settings ||= Grape::Util::HashStack.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.set(key, value)
|
14
|
+
settings[key.to_sym] = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.imbue(key, value)
|
18
|
+
settings.imbue(key, value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe RequestResponse do
|
24
|
+
subject { Class.new(RequestResponseSpec::Dummy) }
|
25
|
+
let(:c_type) { 'application/json' }
|
26
|
+
let(:format) { 'txt' }
|
27
|
+
|
28
|
+
describe '.default_format' do
|
29
|
+
it 'sets the default format' do
|
30
|
+
expect(subject).to receive(:set).with(:default_format, :format)
|
31
|
+
subject.default_format :format
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns the format without paramter' do
|
35
|
+
subject.default_format :format
|
36
|
+
|
37
|
+
expect(subject.default_format).to eq :format
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '.format' do
|
42
|
+
it 'sets a new format' do
|
43
|
+
expect(subject).to receive(:set).with(:format, format.to_sym)
|
44
|
+
expect(subject).to receive(:set).with(:default_error_formatter, Grape::ErrorFormatter::Txt)
|
45
|
+
|
46
|
+
subject.format format
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '.formatter' do
|
51
|
+
it 'sets the formatter for a content type' do
|
52
|
+
expect(subject.settings).to receive(:imbue).with(:formatters, c_type.to_sym => :formatter)
|
53
|
+
subject.formatter c_type, :formatter
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '.parser' do
|
58
|
+
it 'sets a parser for a content type' do
|
59
|
+
expect(subject.settings).to receive(:imbue).with(:parsers, c_type.to_sym => :parser)
|
60
|
+
subject.parser c_type, :parser
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '.default_error_formatter' do
|
65
|
+
it 'sets a new error formatter' do
|
66
|
+
expect(subject).to receive(:set).with(:default_error_formatter, Grape::ErrorFormatter::Json)
|
67
|
+
subject.default_error_formatter :json
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '.error_formatter' do
|
72
|
+
it 'sets a error_formatter' do
|
73
|
+
format = 'txt'
|
74
|
+
expect(subject.settings).to receive(:imbue).with(:error_formatters, format.to_sym => :error_formatter)
|
75
|
+
subject.error_formatter format, :error_formatter
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'understands syntactic sugar' do
|
79
|
+
expect(subject.settings).to receive(:imbue).with(:error_formatters, format.to_sym => :error_formatter)
|
80
|
+
subject.error_formatter format, with: :error_formatter
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '.content_type' do
|
85
|
+
it 'sets a content type for a format' do
|
86
|
+
expect(subject.settings).to receive(:imbue).with(:content_types, format.to_sym => c_type)
|
87
|
+
subject.content_type format, c_type
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '.content_types' do
|
92
|
+
it 'returns all content types' do
|
93
|
+
expect(subject.content_types).to eq(xml: "application/xml",
|
94
|
+
serializable_hash: "application/json",
|
95
|
+
json: "application/json",
|
96
|
+
jsonapi: "application/vnd.api+json",
|
97
|
+
atom: "application/atom+xml",
|
98
|
+
rss: "application/rss+xml",
|
99
|
+
txt: "text/plain")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '.default_error_status' do
|
104
|
+
it 'sets a default error status' do
|
105
|
+
expect(subject).to receive(:set).with(:default_error_status, 500)
|
106
|
+
subject.default_error_status 500
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
xdescribe '.rescue_from' do
|
111
|
+
it 'does some thing'
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '.represent' do
|
115
|
+
it 'sets a presenter for a class' do
|
116
|
+
presenter = Class.new
|
117
|
+
expect(subject).to receive(:imbue).with(:representations, ThisClass: presenter)
|
118
|
+
subject.represent :ThisClass, with: presenter
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Grape
|
4
|
+
module DSL
|
5
|
+
module RoutingSpec
|
6
|
+
class Dummy
|
7
|
+
include Grape::DSL::Routing
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Routing do
|
12
|
+
subject { Class.new(RoutingSpec::Dummy) }
|
13
|
+
let(:proc) { ->() {} }
|
14
|
+
let(:options) { { a: :b } }
|
15
|
+
let(:path) { '/dummy' }
|
16
|
+
|
17
|
+
xdescribe '.version' do
|
18
|
+
it 'does some thing'
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.prefix' do
|
22
|
+
it 'sets a prefix for route' do
|
23
|
+
prefix = '/api'
|
24
|
+
expect(subject).to receive(:set).with(:root_prefix, prefix)
|
25
|
+
subject.prefix prefix
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.do_not_route_head!' do
|
30
|
+
it 'sets do not route head option' do
|
31
|
+
expect(subject).to receive(:set).with(:do_not_route_head, true)
|
32
|
+
subject.do_not_route_head!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '.do_not_route_options!' do
|
37
|
+
it 'sets do not route options option' do
|
38
|
+
expect(subject).to receive(:set).with(:do_not_route_options, true)
|
39
|
+
subject.do_not_route_options!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
xdescribe '.mount' do
|
44
|
+
it 'does some thing'
|
45
|
+
end
|
46
|
+
xdescribe '.route' do
|
47
|
+
it 'does some thing'
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '.get' do
|
51
|
+
it 'delegates to .route' do
|
52
|
+
expect(subject).to receive(:route).with('GET', path, options)
|
53
|
+
subject.get path, options, &proc
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '.post' do
|
58
|
+
it 'delegates to .route' do
|
59
|
+
expect(subject).to receive(:route).with('POST', path, options)
|
60
|
+
subject.post path, options, &proc
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '.put' do
|
65
|
+
it 'delegates to .route' do
|
66
|
+
expect(subject).to receive(:route).with('PUT', path, options)
|
67
|
+
subject.put path, options, &proc
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '.head' do
|
72
|
+
it 'delegates to .route' do
|
73
|
+
expect(subject).to receive(:route).with('HEAD', path, options)
|
74
|
+
subject.head path, options, &proc
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '.delete' do
|
79
|
+
it 'delegates to .route' do
|
80
|
+
expect(subject).to receive(:route).with('DELETE', path, options)
|
81
|
+
subject.delete path, options, &proc
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '.options' do
|
86
|
+
it 'delegates to .route' do
|
87
|
+
expect(subject).to receive(:route).with('OPTIONS', path, options)
|
88
|
+
subject.options path, options, &proc
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '.patch' do
|
93
|
+
it 'delegates to .route' do
|
94
|
+
expect(subject).to receive(:route).with('PATCH', path, options)
|
95
|
+
subject.patch path, options, &proc
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
xdescribe '.namespace' do
|
100
|
+
it 'does some thing'
|
101
|
+
end
|
102
|
+
|
103
|
+
xdescribe '.group' do
|
104
|
+
it 'does some thing'
|
105
|
+
end
|
106
|
+
|
107
|
+
xdescribe '.resource' do
|
108
|
+
it 'does some thing'
|
109
|
+
end
|
110
|
+
|
111
|
+
xdescribe '.resources' do
|
112
|
+
it 'does some thing'
|
113
|
+
end
|
114
|
+
|
115
|
+
xdescribe '.segment' do
|
116
|
+
it 'does some thing'
|
117
|
+
end
|
118
|
+
|
119
|
+
xdescribe '.routes' do
|
120
|
+
it 'does some thing'
|
121
|
+
end
|
122
|
+
|
123
|
+
xdescribe '.route_param' do
|
124
|
+
it 'does some thing'
|
125
|
+
end
|
126
|
+
|
127
|
+
xdescribe '.versions' do
|
128
|
+
it 'does some thing'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Grape
|
4
|
+
module DSL
|
5
|
+
module ValidationsSpec
|
6
|
+
class Dummy
|
7
|
+
include Grape::DSL::Validations
|
8
|
+
|
9
|
+
def self.settings
|
10
|
+
@settings ||= Grape::Util::HashStack.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Validations do
|
16
|
+
subject { ValidationsSpec::Dummy }
|
17
|
+
|
18
|
+
describe '.reset_validations!' do
|
19
|
+
before do
|
20
|
+
subject.settings.peek[:declared_params] = ['dummy']
|
21
|
+
subject.settings.peek[:validations] = ['dummy']
|
22
|
+
subject.reset_validations!
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'resets declared params' do
|
26
|
+
expect(subject.settings.peek[:declared_params]).to be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'resets validations' do
|
30
|
+
expect(subject.settings.peek[:validations]).to be_empty
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.params' do
|
35
|
+
it 'returns a ParamsScope' do
|
36
|
+
expect(subject.params).to be_a Grape::Validations::ParamsScope
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'evaluates block' do
|
40
|
+
expect { subject.params { raise 'foo' } }.to raise_error RuntimeError, 'foo'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.document_attribute' do
|
45
|
+
before do
|
46
|
+
subject.document_attribute([full_name: 'xxx'], foo: 'bar')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'creates last_description' do
|
50
|
+
expect(subject.instance_variable_get(:'@last_description')).to eq(params: { 'xxx' => { foo: 'bar' } })
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|