grape 0.0.0.alpha.2 → 0.1.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.
- data/.rspec +1 -1
- data/Gemfile +5 -3
- data/Gemfile.lock +17 -13
- data/README.rdoc +10 -1
- data/VERSION +1 -1
- data/grape.gemspec +28 -10
- data/lib/grape.rb +19 -7
- data/lib/grape/api.rb +174 -0
- data/lib/grape/endpoint.rb +65 -0
- data/lib/grape/middleware/auth/basic.rb +30 -0
- data/lib/grape/middleware/base.rb +7 -0
- data/lib/grape/middleware/error.rb +3 -2
- data/lib/grape/middleware/formatter.rb +55 -8
- data/lib/grape/middleware/prefixer.rb +5 -4
- data/lib/grape/middleware/versioner.rb +4 -0
- data/lib/grape/middleware_stack.rb +35 -0
- data/spec/grape/api_spec.rb +283 -0
- data/spec/grape/endpoint_spec.rb +75 -0
- data/spec/grape/middleware/auth/basic_spec.rb +31 -0
- data/spec/grape/middleware/formatter_spec.rb +54 -2
- data/spec/grape/middleware/prefixer_spec.rb +5 -0
- data/spec/grape/middleware/versioner_spec.rb +11 -0
- data/spec/grape/middleware_stack_spec.rb +47 -0
- data/spec/spec_helper.rb +5 -0
- metadata +62 -26
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Grape::Endpoint do
|
4
|
+
subject { Class.new(Grape::API) }
|
5
|
+
before { subject.default_format :txt }
|
6
|
+
def app; subject end
|
7
|
+
|
8
|
+
describe '#status' do
|
9
|
+
it 'should be callable from within a block' do
|
10
|
+
subject.get('/home') do
|
11
|
+
status 206
|
12
|
+
"Hello"
|
13
|
+
end
|
14
|
+
|
15
|
+
get '/home'
|
16
|
+
last_response.status.should == 206
|
17
|
+
last_response.body.should == "Hello"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#header' do
|
22
|
+
it 'should be callable from within a block' do
|
23
|
+
subject.get('/hey') do
|
24
|
+
header 'X-Awesome', 'true'
|
25
|
+
"Awesome"
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/hey'
|
29
|
+
last_response.headers['X-Awesome'].should == 'true'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#params' do
|
34
|
+
it 'should be available to the caller' do
|
35
|
+
subject.get('/hey') do
|
36
|
+
params[:howdy]
|
37
|
+
end
|
38
|
+
|
39
|
+
get '/hey?howdy=hey'
|
40
|
+
last_response.body.should == 'hey'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should parse from path segments' do
|
44
|
+
subject.get('/hey/:id') do
|
45
|
+
params[:id]
|
46
|
+
end
|
47
|
+
|
48
|
+
get '/hey/12'
|
49
|
+
last_response.body.should == '12'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#error!' do
|
54
|
+
it 'should accept a message' do
|
55
|
+
subject.get('/hey') do
|
56
|
+
error! "This is not valid."
|
57
|
+
"This is valid."
|
58
|
+
end
|
59
|
+
|
60
|
+
get '/hey'
|
61
|
+
last_response.status.should == 403
|
62
|
+
last_response.body.should == "This is not valid."
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should accept a code' do
|
66
|
+
subject.get('/hey') do
|
67
|
+
error! "Unauthorized.", 401
|
68
|
+
end
|
69
|
+
|
70
|
+
get '/hey'
|
71
|
+
last_response.status.should == 401
|
72
|
+
last_response.body.should == "Unauthorized."
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
describe Grape::Middleware::Auth::Basic do
|
6
|
+
def app
|
7
|
+
Rack::Builder.new do |b|
|
8
|
+
b.use Grape::Middleware::Error
|
9
|
+
b.use(Grape::Middleware::Auth::Basic) do |u,p|
|
10
|
+
u && p && u == p
|
11
|
+
end
|
12
|
+
b.run lambda{|env| [200, {}, "Hello there."]}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should throw a 401 if no auth is given' do
|
17
|
+
@proc = lambda{ false }
|
18
|
+
get '/whatever'
|
19
|
+
last_response.status.should == 401
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should authenticate if given valid creds' do
|
23
|
+
get '/whatever', {}, 'HTTP_AUTHORIZATION' => encode_basic('admin','admin')
|
24
|
+
last_response.status.should == 200
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should throw a 401 is wrong auth is given' do
|
28
|
+
get '/whatever', {}, 'HTTP_AUTHORIZATION' => encode_basic('admin','wrong')
|
29
|
+
last_response.status.should == 401
|
30
|
+
end
|
31
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Grape::Middleware::Formatter do
|
4
|
-
subject{ Grape::Middleware::Formatter.new(app)}
|
4
|
+
subject{ Grape::Middleware::Formatter.new(app, :default_format => :json)}
|
5
5
|
before{ subject.stub!(:dup).and_return(subject) }
|
6
6
|
|
7
7
|
let(:app){ lambda{|env| [200, {}, [@body]]} }
|
@@ -10,7 +10,30 @@ describe Grape::Middleware::Formatter do
|
|
10
10
|
it 'should look at the bodies for possibly serializable data' do
|
11
11
|
@body = {"abc" => "def"}
|
12
12
|
status, headers, bodies = *subject.call({'PATH_INFO' => '/somewhere'})
|
13
|
-
bodies.
|
13
|
+
bodies.each{|b| b.should == MultiJson.encode(@body) }
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should call #to_json first if it is available' do
|
17
|
+
@body = "string"
|
18
|
+
@body.instance_eval do
|
19
|
+
def to_json
|
20
|
+
"\"bar\""
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
subject.call({'PATH_INFO' => '/somewhere'}).last.each{|b| b.should == '"bar"'}
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should serialize the #serializable_hash if that is available' do
|
28
|
+
class SimpleExample
|
29
|
+
def serializable_hash
|
30
|
+
{:abc => 'def'}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
@body = SimpleExample.new
|
35
|
+
|
36
|
+
subject.call({'PATH_INFO' => '/somewhere'}).last.each{|b| b.should == '{"abc":"def"}'}
|
14
37
|
end
|
15
38
|
end
|
16
39
|
|
@@ -32,4 +55,33 @@ describe Grape::Middleware::Formatter do
|
|
32
55
|
err.should == {:status => 406, :message => "The requested format is not supported."}
|
33
56
|
end
|
34
57
|
end
|
58
|
+
|
59
|
+
context 'Accept header detection' do
|
60
|
+
it 'should detect from the Accept header' do
|
61
|
+
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/xml'})
|
62
|
+
subject.env['api.format'].should == :xml
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should look for case-indifferent headers' do
|
66
|
+
subject.call({'PATH_INFO' => '/info', 'accept' => 'application/xml'})
|
67
|
+
subject.env['api.format'].should == :xml
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should use quality rankings to determine formats' do
|
71
|
+
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/json; q=0.3,application/xml; q=1.0'})
|
72
|
+
subject.env['api.format'].should == :xml
|
73
|
+
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/json; q=1.0,application/xml; q=0.3'})
|
74
|
+
subject.env['api.format'].should == :json
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should handle quality rankings mixed with nothing' do
|
78
|
+
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/json,application/xml; q=1.0'})
|
79
|
+
subject.env['api.format'].should == :xml
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should properly parse headers with other attributes' do
|
83
|
+
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/json; abc=2.3; q=1.0,application/xml; q=0.7'})
|
84
|
+
subject.env['api.format'].should == :json
|
85
|
+
end
|
86
|
+
end
|
35
87
|
end
|
@@ -22,4 +22,9 @@ describe Grape::Middleware::Prefixer do
|
|
22
22
|
it 'should pass through unaltered if there is no prefix' do
|
23
23
|
subject.call('PATH_INFO' => '/awesome').last.should == '/awesome'
|
24
24
|
end
|
25
|
+
|
26
|
+
it 'should only remove the first instance of the prefix' do
|
27
|
+
@options = {:prefix => 'api'}
|
28
|
+
subject.call('PATH_INFO' => '/api/v1/api/awesome').last.should == '/v1/api/awesome'
|
29
|
+
end
|
25
30
|
end
|
@@ -26,4 +26,15 @@ describe Grape::Middleware::Versioner do
|
|
26
26
|
subject.call('PATH_INFO' => '/awesome/radical').last.should be_nil
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
context 'with specified versions' do
|
31
|
+
before{ @options = {:versions => ['v1', 'v2']}}
|
32
|
+
it 'should throw an error if a non-allowed version is specified' do
|
33
|
+
catch(:error){subject.call('PATH_INFO' => '/v3/awesome')}[:status].should == 404
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should allow versions that have been specified' do
|
37
|
+
subject.call('PATH_INFO' => '/v1/asoasd').last.should == 'v1'
|
38
|
+
end
|
39
|
+
end
|
29
40
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Grape::MiddlewareStack do
|
4
|
+
subject { Grape::MiddlewareStack.new }
|
5
|
+
|
6
|
+
it 'should be able to add middlewares' do
|
7
|
+
subject.use Grape::Middleware::Error
|
8
|
+
subject.stack.first.should == [Grape::Middleware::Error]
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'class uniqueness' do
|
12
|
+
it 'should not increase the stack size when doubling up on a use' do
|
13
|
+
2.times{ subject.use Grape::Middleware::Error }
|
14
|
+
subject.stack.size.should == 1
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should increase the stack size when a novel class is added' do
|
18
|
+
subject.use Grape::Middleware::Error
|
19
|
+
subject.use Grape::Middleware::Prefixer
|
20
|
+
subject.use Grape::Middleware::Error
|
21
|
+
subject.stack.should == [[Grape::Middleware::Error], [Grape::Middleware::Prefixer]]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#run' do
|
26
|
+
class ExampleMiddleware
|
27
|
+
def initialize(app, say = 'what')
|
28
|
+
@app = app
|
29
|
+
@say = say
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(env)
|
33
|
+
(env['say'] ||= []) << @say
|
34
|
+
@app.call(env)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
before do
|
39
|
+
subject.use ExampleMiddleware
|
40
|
+
subject.use ExampleMiddleware, 'yo'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should call the middlewares in the stack' do
|
44
|
+
subject.to_app(lambda{|env| env['say'].should == ['yo']}).call({})
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -10,6 +10,11 @@ Bundler.setup :default, :test
|
|
10
10
|
require 'rspec'
|
11
11
|
require 'rack/test'
|
12
12
|
|
13
|
+
require 'base64'
|
14
|
+
def encode_basic(username, password)
|
15
|
+
"Basic " + Base64.encode64("#{username}:#{password}")
|
16
|
+
end
|
17
|
+
|
13
18
|
RSpec.configure do |config|
|
14
19
|
config.include Rack::Test::Methods
|
15
20
|
end
|
metadata
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
- alpha
|
11
|
-
- 2
|
12
|
-
version: 0.0.0.alpha.2
|
10
|
+
version: 0.1.0
|
13
11
|
platform: ruby
|
14
12
|
authors:
|
15
13
|
- Michael Bleigh
|
@@ -17,7 +15,7 @@ autorequire:
|
|
17
15
|
bindir: bin
|
18
16
|
cert_chain: []
|
19
17
|
|
20
|
-
date: 2010-
|
18
|
+
date: 2010-11-13 00:00:00 -06:00
|
21
19
|
default_executable:
|
22
20
|
dependencies:
|
23
21
|
- !ruby/object:Gem::Dependency
|
@@ -41,12 +39,14 @@ dependencies:
|
|
41
39
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
42
40
|
none: false
|
43
41
|
requirements:
|
44
|
-
- -
|
42
|
+
- - ~>
|
45
43
|
- !ruby/object:Gem::Version
|
46
|
-
hash:
|
44
|
+
hash: 29
|
47
45
|
segments:
|
48
46
|
- 0
|
49
|
-
|
47
|
+
- 6
|
48
|
+
- 13
|
49
|
+
version: 0.6.13
|
50
50
|
requirement: *id002
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
52
|
prerelease: false
|
@@ -65,23 +65,21 @@ dependencies:
|
|
65
65
|
- !ruby/object:Gem::Dependency
|
66
66
|
prerelease: false
|
67
67
|
type: :runtime
|
68
|
-
name:
|
68
|
+
name: json
|
69
69
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
70
70
|
none: false
|
71
71
|
requirements:
|
72
|
-
- -
|
72
|
+
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
hash:
|
74
|
+
hash: 3
|
75
75
|
segments:
|
76
|
-
- 3
|
77
76
|
- 0
|
78
|
-
|
79
|
-
version: 3.0.0
|
77
|
+
version: "0"
|
80
78
|
requirement: *id004
|
81
79
|
- !ruby/object:Gem::Dependency
|
82
80
|
prerelease: false
|
83
|
-
type: :
|
84
|
-
name:
|
81
|
+
type: :runtime
|
82
|
+
name: multi_json
|
85
83
|
version_requirements: &id005 !ruby/object:Gem::Requirement
|
86
84
|
none: false
|
87
85
|
requirements:
|
@@ -94,8 +92,8 @@ dependencies:
|
|
94
92
|
requirement: *id005
|
95
93
|
- !ruby/object:Gem::Dependency
|
96
94
|
prerelease: false
|
97
|
-
type: :
|
98
|
-
name:
|
95
|
+
type: :runtime
|
96
|
+
name: multi_xml
|
99
97
|
version_requirements: &id006 !ruby/object:Gem::Requirement
|
100
98
|
none: false
|
101
99
|
requirements:
|
@@ -106,6 +104,34 @@ dependencies:
|
|
106
104
|
- 0
|
107
105
|
version: "0"
|
108
106
|
requirement: *id006
|
107
|
+
- !ruby/object:Gem::Dependency
|
108
|
+
prerelease: false
|
109
|
+
type: :development
|
110
|
+
name: rake
|
111
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
hash: 3
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
version: "0"
|
120
|
+
requirement: *id007
|
121
|
+
- !ruby/object:Gem::Dependency
|
122
|
+
prerelease: false
|
123
|
+
type: :development
|
124
|
+
name: jeweler
|
125
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
hash: 3
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
version: "0"
|
134
|
+
requirement: *id008
|
109
135
|
description: A Ruby framework for rapid API development with great conventions.
|
110
136
|
email: michael@intridea.com
|
111
137
|
executables: []
|
@@ -129,18 +155,26 @@ files:
|
|
129
155
|
- autotest/discover.rb
|
130
156
|
- grape.gemspec
|
131
157
|
- lib/grape.rb
|
158
|
+
- lib/grape/api.rb
|
159
|
+
- lib/grape/endpoint.rb
|
160
|
+
- lib/grape/middleware/auth/basic.rb
|
132
161
|
- lib/grape/middleware/auth/oauth2.rb
|
133
162
|
- lib/grape/middleware/base.rb
|
134
163
|
- lib/grape/middleware/error.rb
|
135
164
|
- lib/grape/middleware/formatter.rb
|
136
165
|
- lib/grape/middleware/prefixer.rb
|
137
166
|
- lib/grape/middleware/versioner.rb
|
167
|
+
- lib/grape/middleware_stack.rb
|
168
|
+
- spec/grape/api_spec.rb
|
169
|
+
- spec/grape/endpoint_spec.rb
|
170
|
+
- spec/grape/middleware/auth/basic_spec.rb
|
138
171
|
- spec/grape/middleware/auth/oauth2_spec.rb
|
139
172
|
- spec/grape/middleware/base_spec.rb
|
140
173
|
- spec/grape/middleware/error_spec.rb
|
141
174
|
- spec/grape/middleware/formatter_spec.rb
|
142
175
|
- spec/grape/middleware/prefixer_spec.rb
|
143
176
|
- spec/grape/middleware/versioner_spec.rb
|
177
|
+
- spec/grape/middleware_stack_spec.rb
|
144
178
|
- spec/grape_spec.rb
|
145
179
|
- spec/spec_helper.rb
|
146
180
|
has_rdoc: true
|
@@ -164,14 +198,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
198
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
199
|
none: false
|
166
200
|
requirements:
|
167
|
-
- - "
|
201
|
+
- - ">="
|
168
202
|
- !ruby/object:Gem::Version
|
169
|
-
hash:
|
203
|
+
hash: 3
|
170
204
|
segments:
|
171
|
-
-
|
172
|
-
|
173
|
-
- 1
|
174
|
-
version: 1.3.1
|
205
|
+
- 0
|
206
|
+
version: "0"
|
175
207
|
requirements: []
|
176
208
|
|
177
209
|
rubyforge_project:
|
@@ -180,11 +212,15 @@ signing_key:
|
|
180
212
|
specification_version: 3
|
181
213
|
summary: A Ruby framework for rapid API development.
|
182
214
|
test_files:
|
215
|
+
- spec/grape/api_spec.rb
|
216
|
+
- spec/grape/endpoint_spec.rb
|
217
|
+
- spec/grape/middleware/auth/basic_spec.rb
|
183
218
|
- spec/grape/middleware/auth/oauth2_spec.rb
|
184
219
|
- spec/grape/middleware/base_spec.rb
|
185
220
|
- spec/grape/middleware/error_spec.rb
|
186
221
|
- spec/grape/middleware/formatter_spec.rb
|
187
222
|
- spec/grape/middleware/prefixer_spec.rb
|
188
223
|
- spec/grape/middleware/versioner_spec.rb
|
224
|
+
- spec/grape/middleware_stack_spec.rb
|
189
225
|
- spec/grape_spec.rb
|
190
226
|
- spec/spec_helper.rb
|