This repository has been archived by the owner on May 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 129
/
respond_with_spec.rb
299 lines (248 loc) · 7.84 KB
/
respond_with_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
require 'backports'
require 'multi_json'
require_relative 'spec_helper'
require_relative 'okjson'
describe Sinatra::RespondWith do
def provides(*args)
@provides = args
end
def respond_app(&block)
types = @provides
mock_app do
set :app_file, __FILE__
set :views, root + '/respond_with'
register Sinatra::RespondWith
respond_to(*types) if types
class_eval(&block)
end
end
def respond_to(*args, &block)
respond_app { get('/') { respond_to(*args, &block) } }
end
def respond_with(*args, &block)
respond_app { get('/') { respond_with(*args, &block) } }
end
def req(*types)
p = types.shift if types.first.is_a? String and types.first.start_with? '/'
accept = types.map { |t| Sinatra::Base.mime_type(t).to_s }.join ','
get (p || '/'), {}, 'HTTP_ACCEPT' => accept
end
describe "Helpers#respond_to" do
it 'allows defining handlers by file extensions' do
respond_to do |format|
format.html { "html!" }
format.json { "json!" }
end
req(:html).body.should == "html!"
req(:json).body.should == "json!"
end
it 'respects quality' do
respond_to do |format|
format.html { "html!" }
format.json { "json!" }
end
req("text/html;q=0.7, application/json;q=0.3").body.should == "html!"
req("text/html;q=0.3, application/json;q=0.7").body.should == "json!"
end
it 'allows using mime types' do
respond_to do |format|
format.on('text/html') { "html!" }
format.json { "json!" }
end
req(:html).body.should == "html!"
end
it 'allows using wildcards in format matchers' do
respond_to do |format|
format.on('text/*') { "text!" }
format.json { "json!" }
end
req(:html).body.should == "text!"
end
it 'allows using catch all wildcards in format matchers' do
respond_to do |format|
format.on('*/*') { "anything!" }
format.json { "json!" }
end
req(:html).body.should == "anything!"
end
it 'prefers concret over generic' do
respond_to do |format|
format.on('text/*') { "text!" }
format.on('*/*') { "anything!" }
format.json { "json!" }
end
req(:json).body.should == "json!"
req(:html).body.should == "text!"
end
it 'does not set up default handlers' do
respond_to
req.should_not be_ok
status.should == 406
end
end
describe "Helpers#respond_with" do
describe "matching" do
it 'allows defining handlers by file extensions' do
respond_with(:ignore) do |format|
format.html { "html!" }
format.json { "json!" }
end
req(:html).body.should == "html!"
req(:json).body.should == "json!"
end
it 'respects quality' do
respond_with(:ignore) do |format|
format.html { "html!" }
format.json { "json!" }
end
req("text/html;q=0.7, application/json;q=0.3").body.should == "html!"
req("text/html;q=0.3, application/json;q=0.7").body.should == "json!"
end
it 'allows using mime types' do
respond_with(:ignore) do |format|
format.on('text/html') { "html!" }
format.json { "json!" }
end
req(:html).body.should == "html!"
end
it 'allows using wildcards in format matchers' do
respond_with(:ignore) do |format|
format.on('text/*') { "text!" }
format.json { "json!" }
end
req(:html).body.should == "text!"
end
it 'allows using catch all wildcards in format matchers' do
respond_with(:ignore) do |format|
format.on('*/*') { "anything!" }
format.json { "json!" }
end
req(:html).body.should == "anything!"
end
it 'prefers concret over generic' do
respond_with(:ignore) do |format|
format.on('text/*') { "text!" }
format.on('*/*') { "anything!" }
format.json { "json!" }
end
req(:json).body.should == "json!"
req(:html).body.should == "text!"
end
end
describe "default behavior" do
it 'converts objects to json out of the box' do
respond_with 'a' => 'b'
OkJson.decode(req(:json).body).should == {'a' => 'b'}
end
it 'handles multiple routes correctly' do
respond_app do
get('/') { respond_with 'a' => 'b' }
get('/:name') { respond_with 'a' => params[:name] }
end
OkJson.decode(req('/', :json).body).should == {'a' => 'b'}
OkJson.decode(req('/b', :json).body).should == {'a' => 'b'}
OkJson.decode(req('/c', :json).body).should == {'a' => 'c'}
end
it "calls to_EXT if available" do
respond_with Struct.new(:to_pdf).new("hello")
req(:pdf).body.should == "hello"
end
it 'results in a 406 if format cannot be produced' do
respond_with({})
req(:html).should_not be_ok
status.should == 406
end
end
describe 'templates' do
it 'looks for templates with name.target.engine' do
respond_with :foo, :name => 'World'
req(:html).should be_ok
body.should == "Hello World!"
end
it 'looks for templates with name.engine for specific engines' do
respond_with :bar
req(:html).should be_ok
body.should == "Girl! I wanna take you to a ... bar!"
end
it 'does not use name.engine for engines producing other formats' do
respond_with :not_html
req(:html).should_not be_ok
status.should == 406
body.should be_empty
end
it 'falls back to #json if no template is found' do
respond_with :foo, :name => 'World'
req(:json).should be_ok
OkJson.decode(body).should == {'name' => 'World'}
end
it 'favors templates over #json' do
respond_with :bar, :name => 'World'
req(:json).should be_ok
body.should == 'json!'
end
it 'falls back to to_EXT if no template is found' do
object = {:name => 'World'}
def object.to_pdf; "hi" end
respond_with :foo, object
req(:pdf).should be_ok
body.should == "hi"
end
unless defined? JRUBY_VERSION
it 'uses yajl for json' do
respond_with :baz
req(:json).should be_ok
body.should == "\"yajl!\""
end
end
end
describe 'customizing' do
it 'allows customizing' do
respond_with(:foo, :name => 'World') { |f| f.html { 'html!' }}
req(:html).should be_ok
body.should == "html!"
end
it 'falls back to default behavior if none matches' do
respond_with(:foo, :name => 'World') { |f| f.json { 'json!' }}
req(:html).should be_ok
body.should == "Hello World!"
end
it 'favors generic rule over default behavior' do
respond_with(:foo, :name => 'World') { |f| f.on('*/*') { 'generic!' }}
req(:html).should be_ok
body.should == "generic!"
end
end
end
describe :respond_to do
it 'acts as global provides condition' do
respond_app do
respond_to :json, :html
get('/a') { 'ok' }
get('/b') { 'ok' }
end
req('/b', :xml).should_not be_ok
req('/b', :html).should be_ok
end
it 'still allows provides' do
respond_app do
respond_to :json, :html
get('/a') { 'ok' }
get('/b', :provides => :json) { 'ok' }
end
req('/b', :html).should_not be_ok
req('/b', :json).should be_ok
end
it 'plays well with namespaces' do
respond_app do
register Sinatra::Namespace
namespace '/a' do
respond_to :json
get { 'json' }
end
get('/b') { 'anything' }
end
req('/a', :html).should_not be_ok
req('/b', :html).should be_ok
end
end
end