sinatra-contrib 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +135 -0
  3. data/Rakefile +75 -0
  4. data/ideas.md +29 -0
  5. data/lib/sinatra/capture.rb +42 -0
  6. data/lib/sinatra/config_file.rb +151 -0
  7. data/lib/sinatra/content_for.rb +111 -0
  8. data/lib/sinatra/contrib.rb +39 -0
  9. data/lib/sinatra/contrib/all.rb +2 -0
  10. data/lib/sinatra/contrib/setup.rb +53 -0
  11. data/lib/sinatra/contrib/version.rb +45 -0
  12. data/lib/sinatra/cookies.rb +331 -0
  13. data/lib/sinatra/decompile.rb +113 -0
  14. data/lib/sinatra/engine_tracking.rb +96 -0
  15. data/lib/sinatra/extension.rb +95 -0
  16. data/lib/sinatra/json.rb +134 -0
  17. data/lib/sinatra/link_header.rb +132 -0
  18. data/lib/sinatra/multi_route.rb +81 -0
  19. data/lib/sinatra/namespace.rb +282 -0
  20. data/lib/sinatra/reloader.rb +384 -0
  21. data/lib/sinatra/respond_with.rb +245 -0
  22. data/lib/sinatra/streaming.rb +267 -0
  23. data/lib/sinatra/test_helpers.rb +87 -0
  24. data/sinatra-contrib.gemspec +125 -0
  25. data/spec/capture_spec.rb +80 -0
  26. data/spec/config_file/key_value.yml +6 -0
  27. data/spec/config_file/missing_env.yml +4 -0
  28. data/spec/config_file/with_envs.yml +7 -0
  29. data/spec/config_file/with_nested_envs.yml +11 -0
  30. data/spec/config_file_spec.rb +44 -0
  31. data/spec/content_for/different_key.erb +1 -0
  32. data/spec/content_for/different_key.erubis +1 -0
  33. data/spec/content_for/different_key.haml +2 -0
  34. data/spec/content_for/different_key.slim +2 -0
  35. data/spec/content_for/layout.erb +1 -0
  36. data/spec/content_for/layout.erubis +1 -0
  37. data/spec/content_for/layout.haml +1 -0
  38. data/spec/content_for/layout.slim +1 -0
  39. data/spec/content_for/multiple_blocks.erb +4 -0
  40. data/spec/content_for/multiple_blocks.erubis +4 -0
  41. data/spec/content_for/multiple_blocks.haml +8 -0
  42. data/spec/content_for/multiple_blocks.slim +8 -0
  43. data/spec/content_for/multiple_yields.erb +3 -0
  44. data/spec/content_for/multiple_yields.erubis +3 -0
  45. data/spec/content_for/multiple_yields.haml +3 -0
  46. data/spec/content_for/multiple_yields.slim +3 -0
  47. data/spec/content_for/passes_values.erb +1 -0
  48. data/spec/content_for/passes_values.erubis +1 -0
  49. data/spec/content_for/passes_values.haml +1 -0
  50. data/spec/content_for/passes_values.slim +1 -0
  51. data/spec/content_for/same_key.erb +1 -0
  52. data/spec/content_for/same_key.erubis +1 -0
  53. data/spec/content_for/same_key.haml +2 -0
  54. data/spec/content_for/same_key.slim +2 -0
  55. data/spec/content_for/takes_values.erb +1 -0
  56. data/spec/content_for/takes_values.erubis +1 -0
  57. data/spec/content_for/takes_values.haml +3 -0
  58. data/spec/content_for/takes_values.slim +3 -0
  59. data/spec/content_for_spec.rb +201 -0
  60. data/spec/cookies_spec.rb +782 -0
  61. data/spec/decompile_spec.rb +44 -0
  62. data/spec/extension_spec.rb +33 -0
  63. data/spec/json_spec.rb +115 -0
  64. data/spec/link_header_spec.rb +100 -0
  65. data/spec/multi_route_spec.rb +45 -0
  66. data/spec/namespace/foo.erb +1 -0
  67. data/spec/namespace/nested/foo.erb +1 -0
  68. data/spec/namespace_spec.rb +623 -0
  69. data/spec/okjson.rb +581 -0
  70. data/spec/reloader/app.rb.erb +40 -0
  71. data/spec/reloader_spec.rb +441 -0
  72. data/spec/respond_with/bar.erb +1 -0
  73. data/spec/respond_with/bar.json.erb +1 -0
  74. data/spec/respond_with/foo.html.erb +1 -0
  75. data/spec/respond_with/not_html.sass +2 -0
  76. data/spec/respond_with_spec.rb +289 -0
  77. data/spec/spec_helper.rb +6 -0
  78. data/spec/streaming_spec.rb +436 -0
  79. metadata +256 -0
@@ -0,0 +1,3 @@
1
+ = yield_content :foo
2
+ = yield_content :foo
3
+ = yield_content :foo
@@ -0,0 +1,3 @@
1
+ = yield_content :foo
2
+ = yield_content :foo
3
+ = yield_content :foo
@@ -0,0 +1 @@
1
+ <%= yield_content :foo, 1, 2 %>
@@ -0,0 +1 @@
1
+ <%= yield_content :foo, 1, 2 %>
@@ -0,0 +1 @@
1
+ = yield_content :foo, 1, 2
@@ -0,0 +1 @@
1
+ == yield_content :foo, 1, 2
@@ -0,0 +1 @@
1
+ <% content_for :foo do %>foo<% end %>
@@ -0,0 +1 @@
1
+ <% content_for :foo do %>foo<% end %>
@@ -0,0 +1,2 @@
1
+ - content_for :foo do
2
+ foo
@@ -0,0 +1,2 @@
1
+ - content_for :foo do
2
+ | foo
@@ -0,0 +1 @@
1
+ <% content_for :foo do |a, b| %><i><%= a %></i> <%= b %><% end %>
@@ -0,0 +1 @@
1
+ <% content_for :foo do |a, b| %><i><%= a %></i> <%= b %><% end %>
@@ -0,0 +1,3 @@
1
+ - content_for :foo do |a, b|
2
+ %i= a
3
+ =b
@@ -0,0 +1,3 @@
1
+ - content_for :foo do |a, b|
2
+ i= a
3
+ = b
@@ -0,0 +1,201 @@
1
+ require 'backports'
2
+ require_relative 'spec_helper'
3
+
4
+ describe Sinatra::ContentFor do
5
+ subject do
6
+ Sinatra.new do
7
+ helpers Sinatra::ContentFor
8
+ set :views, File.expand_path("../content_for", __FILE__)
9
+ end.new!
10
+ end
11
+
12
+ Tilt.prefer Tilt::ERBTemplate
13
+
14
+ extend Forwardable
15
+ def_delegators :subject, :content_for, :yield_content
16
+ def render(engine, template)
17
+ subject.send(:render, engine, template, :layout => false).gsub(/\s/, '')
18
+ end
19
+
20
+ describe "without templates" do
21
+ it 'renders blocks declared with the same key you use when rendering' do
22
+ content_for(:foo) { "foo" }
23
+ yield_content(:foo).should == "foo"
24
+ end
25
+
26
+ it 'renders blocks more than once' do
27
+ content_for(:foo) { "foo" }
28
+ 3.times { yield_content(:foo).should == "foo" }
29
+ end
30
+
31
+ it 'does not render a block with a different key' do
32
+ content_for(:bar) { "bar" }
33
+ yield_content(:foo).should be_empty
34
+ end
35
+
36
+ it 'renders multiple blocks with the same key' do
37
+ content_for(:foo) { "foo" }
38
+ content_for(:foo) { "bar" }
39
+ content_for(:bar) { "WON'T RENDER ME" }
40
+ content_for(:foo) { "baz" }
41
+ yield_content(:foo).should == "foobarbaz"
42
+ end
43
+
44
+ it 'renders multiple blocks more than once' do
45
+ content_for(:foo) { "foo" }
46
+ content_for(:foo) { "bar" }
47
+ content_for(:bar) { "WON'T RENDER ME" }
48
+ content_for(:foo) { "baz" }
49
+ 3.times { yield_content(:foo).should == "foobarbaz" }
50
+ end
51
+
52
+ it 'passes values to the blocks' do
53
+ content_for(:foo) { |a| a.upcase }
54
+ yield_content(:foo, 'a').should == "A"
55
+ yield_content(:foo, 'b').should == "B"
56
+ end
57
+ end
58
+
59
+ # TODO: liquid radius markaby builder nokogiri
60
+ engines = %w[erb erubis haml slim]
61
+
62
+ engines.each do |inner|
63
+ describe inner.capitalize do
64
+ before :all do
65
+ begin
66
+ require inner
67
+ rescue LoadError => e
68
+ pending "Skipping: " << e.message
69
+ end
70
+ end
71
+
72
+ describe "with yield_content in Ruby" do
73
+ it 'renders blocks declared with the same key you use when rendering' do
74
+ render inner, :same_key
75
+ yield_content(:foo).strip.should == "foo"
76
+ end
77
+
78
+ it 'renders blocks more than once' do
79
+ render inner, :same_key
80
+ 3.times { yield_content(:foo).strip.should == "foo" }
81
+ end
82
+
83
+ it 'does not render a block with a different key' do
84
+ render inner, :different_key
85
+ yield_content(:foo).should be_empty
86
+ end
87
+
88
+ it 'renders multiple blocks with the same key' do
89
+ render inner, :multiple_blocks
90
+ yield_content(:foo).gsub(/\s/, '').should == "foobarbaz"
91
+ end
92
+
93
+ it 'renders multiple blocks more than once' do
94
+ render inner, :multiple_blocks
95
+ 3.times { yield_content(:foo).gsub(/\s/, '').should == "foobarbaz" }
96
+ end
97
+
98
+ it 'passes values to the blocks' do
99
+ render inner, :takes_values
100
+ yield_content(:foo, 1, 2).gsub(/\s/, '').should == "<i>1</i>2"
101
+ end
102
+ end
103
+
104
+ describe "with content_for in Ruby" do
105
+ it 'renders blocks declared with the same key you use when rendering' do
106
+ content_for(:foo) { "foo" }
107
+ render(inner, :layout).should == "foo"
108
+ end
109
+
110
+ it 'renders blocks more than once' do
111
+ content_for(:foo) { "foo" }
112
+ render(inner, :multiple_yields).should == "foofoofoo"
113
+ end
114
+
115
+ it 'does not render a block with a different key' do
116
+ content_for(:bar) { "foo" }
117
+ render(inner, :layout).should be_empty
118
+ end
119
+
120
+ it 'renders multiple blocks with the same key' do
121
+ content_for(:foo) { "foo" }
122
+ content_for(:foo) { "bar" }
123
+ content_for(:bar) { "WON'T RENDER ME" }
124
+ content_for(:foo) { "baz" }
125
+ render(inner, :layout).should == "foobarbaz"
126
+ end
127
+
128
+ it 'renders multiple blocks more than once' do
129
+ content_for(:foo) { "foo" }
130
+ content_for(:foo) { "bar" }
131
+ content_for(:bar) { "WON'T RENDER ME" }
132
+ content_for(:foo) { "baz" }
133
+ render(inner, :multiple_yields).should == "foobarbazfoobarbazfoobarbaz"
134
+ end
135
+
136
+ it 'passes values to the blocks' do
137
+ content_for(:foo) { |a,b| "<i>#{a}</i>#{b}" }
138
+ render(inner, :passes_values).should == "<i>1</i>2"
139
+ end
140
+ end
141
+
142
+ engines.each do |outer|
143
+ describe "with yield_content in #{outer.capitalize}" do
144
+ def body
145
+ last_response.body.gsub(/\s/, '')
146
+ end
147
+
148
+ before :all do
149
+ begin
150
+ require outer
151
+ rescue LoadError => e
152
+ pending "Skipping: " << e.message
153
+ end
154
+ end
155
+
156
+ before do
157
+ mock_app do
158
+ helpers Sinatra::ContentFor
159
+ set inner, :layout_engine => outer
160
+ set :views, File.expand_path("../content_for", __FILE__)
161
+ get('/:view') { render(inner, params[:view].to_sym) }
162
+ get('/:layout/:view') do
163
+ render inner, params[:view].to_sym, :layout => params[:layout].to_sym
164
+ end
165
+ end
166
+ end
167
+
168
+ it 'renders blocks declared with the same key you use when rendering' do
169
+ get('/same_key').should be_ok
170
+ body.should == "foo"
171
+ end
172
+
173
+ it 'renders blocks more than once' do
174
+ get('/multiple_yields/same_key').should be_ok
175
+ body.should == "foofoofoo"
176
+ end
177
+
178
+ it 'does not render a block with a different key' do
179
+ get('/different_key').should be_ok
180
+ body.should be_empty
181
+ end
182
+
183
+ it 'renders multiple blocks with the same key' do
184
+ get('/multiple_blocks').should be_ok
185
+ body.should == "foobarbaz"
186
+ end
187
+
188
+ it 'renders multiple blocks more than once' do
189
+ get('/multiple_yields/multiple_blocks').should be_ok
190
+ body.should == "foobarbazfoobarbazfoobarbaz"
191
+ end
192
+
193
+ it 'passes values to the blocks' do
194
+ get('/passes_values/takes_values').should be_ok
195
+ body.should == "<i>1</i>2"
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,782 @@
1
+ require 'backports'
2
+ require_relative 'spec_helper'
3
+
4
+ describe Sinatra::Cookies do
5
+ def cookie_route(*cookies, &block)
6
+ result = nil
7
+ set_cookie(cookies)
8
+ @cookie_app.get('/') do
9
+ result = instance_eval(&block)
10
+ "ok"
11
+ end
12
+ get '/'
13
+ last_response.should be_ok
14
+ body.should be == "ok"
15
+ result
16
+ end
17
+
18
+ def cookies(*set_cookies)
19
+ cookie_route(*set_cookies) { cookies }
20
+ end
21
+
22
+ before do
23
+ app = nil
24
+ mock_app do
25
+ helpers Sinatra::Cookies
26
+ app = self
27
+ end
28
+ @cookie_app = app
29
+ clear_cookies
30
+ end
31
+
32
+ describe :cookie_route do
33
+ it 'runs the block' do
34
+ ran = false
35
+ cookie_route { ran = true }
36
+ ran.should be_true
37
+ end
38
+
39
+ it 'returns the block result' do
40
+ cookie_route { 42 }.should be == 42
41
+ end
42
+ end
43
+
44
+ describe :== do
45
+ it 'is comparable to hashes' do
46
+ cookies.should be == {}
47
+ end
48
+
49
+ it 'is comparable to anything that responds to to_hash' do
50
+ other = Struct.new(:to_hash).new({})
51
+ cookies.should be == other
52
+ end
53
+ end
54
+
55
+ describe :[] do
56
+ it 'allows access to request cookies' do
57
+ cookies("foo=bar")["foo"].should be == "bar"
58
+ end
59
+
60
+ it 'takes symbols as keys' do
61
+ cookies("foo=bar")[:foo].should be == "bar"
62
+ end
63
+
64
+ it 'returns nil for missing keys' do
65
+ cookies("foo=bar")['bar'].should be_nil
66
+ end
67
+
68
+ it 'allows access to response cookies' do
69
+ cookie_route do
70
+ response.set_cookie 'foo', 'bar'
71
+ cookies['foo']
72
+ end.should be == 'bar'
73
+ end
74
+
75
+ it 'favors response cookies over request cookies' do
76
+ cookie_route('foo=bar') do
77
+ response.set_cookie 'foo', 'baz'
78
+ cookies['foo']
79
+ end.should be == 'baz'
80
+ end
81
+
82
+
83
+ it 'takes the last value for response cookies' do
84
+ cookie_route do
85
+ response.set_cookie 'foo', 'bar'
86
+ response.set_cookie 'foo', 'baz'
87
+ cookies['foo']
88
+ end.should be == 'baz'
89
+ end
90
+ end
91
+
92
+ describe :[]= do
93
+ it 'sets cookies to httponly' do
94
+ cookie_route do
95
+ cookies['foo'] = 'bar'
96
+ response['Set-Cookie'].lines.detect { |l| l.start_with? 'foo=' }
97
+ end.should include('HttpOnly')
98
+ end
99
+
100
+ it 'sets the domain' do
101
+ cookie_route do
102
+ cookies['foo'] = 'bar'
103
+ response['Set-Cookie'].lines.detect { |l| l.start_with? 'foo=' }
104
+ end.should include('domain=example.org')
105
+ end
106
+
107
+ it 'sets path to / by default' do
108
+ cookie_route do
109
+ cookies['foo'] = 'bar'
110
+ response['Set-Cookie'].lines.detect { |l| l.start_with? 'foo=' }
111
+ end.should include('path=/')
112
+ end
113
+
114
+ it 'sets path to the script_name if app is nested' do
115
+ cookie_route do
116
+ request.script_name = '/foo'
117
+ cookies['foo'] = 'bar'
118
+ response['Set-Cookie'].lines.detect { |l| l.start_with? 'foo=' }
119
+ end.should include('path=/foo')
120
+ end
121
+
122
+ it 'sets a cookie' do
123
+ cookie_route { cookies['foo'] = 'bar' }
124
+ cookie_jar['foo'].should be == 'bar'
125
+ end
126
+
127
+ it 'adds a value to the cookies hash' do
128
+ cookie_route do
129
+ cookies['foo'] = 'bar'
130
+ cookies['foo']
131
+ end.should be == 'bar'
132
+ end
133
+ end
134
+
135
+ describe :assoc do
136
+ it 'behaves like Hash#assoc' do
137
+ cookies('foo=bar').assoc('foo') == ['foo', 'bar']
138
+ end
139
+ end if Hash.method_defined? :assoc
140
+
141
+ describe :clear do
142
+ it 'removes request cookies from cookies hash' do
143
+ jar = cookies('foo=bar')
144
+ jar['foo'].should be == 'bar'
145
+ jar.clear
146
+ jar['foo'].should be_nil
147
+ end
148
+
149
+ it 'removes response cookies from cookies hash' do
150
+ cookie_route do
151
+ cookies['foo'] = 'bar'
152
+ cookies.clear
153
+ cookies['foo']
154
+ end.should be_nil
155
+ end
156
+
157
+ it 'expiers existing cookies' do
158
+ cookie_route("foo=bar") do
159
+ cookies.clear
160
+ response['Set-Cookie']
161
+ end.should include("foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT")
162
+ end
163
+ end
164
+
165
+ describe :compare_by_identity? do
166
+ it { cookies.should_not be_compare_by_identity }
167
+ end
168
+
169
+ describe :default do
170
+ it { cookies.default.should be_nil }
171
+ end
172
+
173
+ describe :default_proc do
174
+ it { cookies.default_proc.should be_nil }
175
+ end
176
+
177
+ describe :delete do
178
+ it 'removes request cookies from cookies hash' do
179
+ jar = cookies('foo=bar')
180
+ jar['foo'].should be == 'bar'
181
+ jar.delete 'foo'
182
+ jar['foo'].should be_nil
183
+ end
184
+
185
+ it 'removes response cookies from cookies hash' do
186
+ cookie_route do
187
+ cookies['foo'] = 'bar'
188
+ cookies.clear
189
+ cookies['foo']
190
+ end.should be_nil
191
+ end
192
+
193
+ it 'expiers existing cookies' do
194
+ cookie_route("foo=bar") do
195
+ cookies.delete 'foo'
196
+ response['Set-Cookie']
197
+ end.should include("foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT")
198
+ end
199
+
200
+ it 'does not touch other cookies' do
201
+ cookie_route("foo=bar", "bar=baz") do
202
+ cookies.delete 'foo'
203
+ cookies['bar']
204
+ end.should be == 'baz'
205
+ end
206
+
207
+ it 'returns the previous value for request cookies' do
208
+ cookie_route("foo=bar") do
209
+ cookies.delete "foo"
210
+ end.should be == "bar"
211
+ end
212
+
213
+ it 'returns the previous value for response cookies' do
214
+ cookie_route do
215
+ cookies['foo'] = 'bar'
216
+ cookies.delete "foo"
217
+ end.should be == "bar"
218
+ end
219
+
220
+ it 'returns nil for non-existing cookies' do
221
+ cookie_route { cookies.delete("foo") }.should be_nil
222
+ end
223
+ end
224
+
225
+ describe :delete_if do
226
+ it 'deletes cookies that match the block' do
227
+ cookie_route('foo=bar') do
228
+ cookies['bar'] = 'baz'
229
+ cookies['baz'] = 'foo'
230
+ cookies.delete_if { |*a| a.include? 'bar' }
231
+ cookies.values_at 'foo', 'bar', 'baz'
232
+ end.should be == [nil, nil, 'foo']
233
+ end
234
+ end
235
+
236
+ describe :each do
237
+ it 'loops through cookies' do
238
+ keys = []
239
+ foo = nil
240
+ bar = nil
241
+
242
+ cookie_route('foo=bar', 'bar=baz') do
243
+ cookies.each do |key, value|
244
+ foo = value if key == 'foo'
245
+ bar = value if key == 'bar'
246
+ keys << key
247
+ end
248
+ end
249
+
250
+ keys.sort.should be == ['bar', 'foo']
251
+ foo.should be == 'bar'
252
+ bar.should be == 'baz'
253
+ end
254
+
255
+ it 'favors response over request cookies' do
256
+ seen = false
257
+ cookie_route('foo=bar') do
258
+ cookies[:foo] = 'baz'
259
+ cookies.each do |key, value|
260
+ key.should == 'foo'
261
+ value.should == 'baz'
262
+ seen.should == false
263
+ seen = true
264
+ end
265
+ end
266
+ end
267
+
268
+ it 'does not loop through deleted cookies' do
269
+ cookie_route('foo=bar') do
270
+ cookies.delete :foo
271
+ cookies.each { fail }
272
+ end
273
+ end
274
+
275
+ it 'returns an enumerator' do
276
+ cookie_route('foo=bar') do
277
+ enum = cookies.each
278
+ enum.each { |key, value| key.should == 'foo' }
279
+ end
280
+ end
281
+ end
282
+
283
+ describe :each_key do
284
+ it 'loops through cookies' do
285
+ keys = []
286
+
287
+ cookie_route('foo=bar', 'bar=baz') do
288
+ cookies.each_key do |key|
289
+ keys << key
290
+ end
291
+ end
292
+
293
+ keys.sort.should be == ['bar', 'foo']
294
+ end
295
+
296
+ it 'only yields keys once' do
297
+ seen = false
298
+ cookie_route('foo=bar') do
299
+ cookies[:foo] = 'baz'
300
+ cookies.each_key do |key|
301
+ seen.should == false
302
+ seen = true
303
+ end
304
+ end
305
+ end
306
+
307
+ it 'does not loop through deleted cookies' do
308
+ cookie_route('foo=bar') do
309
+ cookies.delete :foo
310
+ cookies.each_key { fail }
311
+ end
312
+ end
313
+
314
+ it 'returns an enumerator' do
315
+ cookie_route('foo=bar') do
316
+ enum = cookies.each_key
317
+ enum.each { |key| key.should == 'foo' }
318
+ end
319
+ end
320
+ end
321
+
322
+ describe :each_pair do
323
+ it 'loops through cookies' do
324
+ keys = []
325
+ foo = nil
326
+ bar = nil
327
+
328
+ cookie_route('foo=bar', 'bar=baz') do
329
+ cookies.each_pair do |key, value|
330
+ foo = value if key == 'foo'
331
+ bar = value if key == 'bar'
332
+ keys << key
333
+ end
334
+ end
335
+
336
+ keys.sort.should be == ['bar', 'foo']
337
+ foo.should be == 'bar'
338
+ bar.should be == 'baz'
339
+ end
340
+
341
+ it 'favors response over request cookies' do
342
+ seen = false
343
+ cookie_route('foo=bar') do
344
+ cookies[:foo] = 'baz'
345
+ cookies.each_pair do |key, value|
346
+ key.should == 'foo'
347
+ value.should == 'baz'
348
+ seen.should == false
349
+ seen = true
350
+ end
351
+ end
352
+ end
353
+
354
+ it 'does not loop through deleted cookies' do
355
+ cookie_route('foo=bar') do
356
+ cookies.delete :foo
357
+ cookies.each_pair { fail }
358
+ end
359
+ end
360
+
361
+ it 'returns an enumerator' do
362
+ cookie_route('foo=bar') do
363
+ enum = cookies.each_pair
364
+ enum.each { |key, value| key.should == 'foo' }
365
+ end
366
+ end
367
+ end
368
+
369
+ describe :each_value do
370
+ it 'loops through cookies' do
371
+ values = []
372
+
373
+ cookie_route('foo=bar', 'bar=baz') do
374
+ cookies.each_value do |value|
375
+ values << value
376
+ end
377
+ end
378
+
379
+ values.sort.should be == ['bar', 'baz']
380
+ end
381
+
382
+ it 'favors response over request cookies' do
383
+ seen = false
384
+ cookie_route('foo=bar') do
385
+ cookies[:foo] = 'baz'
386
+ cookies.each_value do |value|
387
+ value.should == 'baz'
388
+ seen.should == false
389
+ seen = true
390
+ end
391
+ end
392
+ end
393
+
394
+ it 'does not loop through deleted cookies' do
395
+ cookie_route('foo=bar') do
396
+ cookies.delete :foo
397
+ cookies.each_value { fail }
398
+ end
399
+ end
400
+
401
+ it 'returns an enumerator' do
402
+ cookie_route('foo=bar') do
403
+ enum = cookies.each_value
404
+ enum.each { |value| value.should == 'bar' }
405
+ end
406
+ end
407
+ end
408
+
409
+ describe :empty? do
410
+ it 'returns true if there are no cookies' do
411
+ cookies.should be_empty
412
+ end
413
+
414
+ it 'returns false if there are request cookies' do
415
+ cookies('foo=bar').should_not be_empty
416
+ end
417
+
418
+ it 'returns false if there are response cookies' do
419
+ cookie_route do
420
+ cookies['foo'] = 'bar'
421
+ cookies.empty?
422
+ end.should be_false
423
+ end
424
+
425
+ it 'becomes true if response cookies are removed' do
426
+ cookie_route do
427
+ cookies['foo'] = 'bar'
428
+ cookies.delete :foo
429
+ cookies.empty?
430
+ end.should be_true
431
+ end
432
+
433
+ it 'becomes true if request cookies are removed' do
434
+ cookie_route('foo=bar') do
435
+ cookies.delete :foo
436
+ cookies.empty?
437
+ end.should be_true
438
+ end
439
+
440
+ it 'becomes true after clear' do
441
+ cookie_route('foo=bar', 'bar=baz') do
442
+ cookies['foo'] = 'bar'
443
+ cookies.clear
444
+ cookies.empty?
445
+ end.should be_true
446
+ end
447
+ end
448
+
449
+ describe :fetch do
450
+ it 'returns values from request cookies' do
451
+ cookies('foo=bar').fetch('foo').should be == 'bar'
452
+ end
453
+
454
+ it 'returns values from response cookies' do
455
+ cookie_route do
456
+ cookies['foo'] = 'bar'
457
+ cookies.fetch('foo')
458
+ end.should be == 'bar'
459
+ end
460
+
461
+ it 'favors response over request cookies' do
462
+ cookie_route('foo=baz') do
463
+ cookies['foo'] = 'bar'
464
+ cookies.fetch('foo')
465
+ end.should be == 'bar'
466
+ end
467
+
468
+ it 'raises an exception if key does not exist' do
469
+ error = RUBY_VERSION >= '1.9' ? KeyError : IndexError
470
+ expect { cookies.fetch('foo') }.to raise_exception(error)
471
+ end
472
+
473
+ it 'returns the block result if missing' do
474
+ cookies.fetch('foo') { 'bar' }.should be == 'bar'
475
+ end
476
+ end
477
+
478
+ describe :flatten do
479
+ it { cookies('foo=bar').flatten.should be == {'foo' => 'bar'}.flatten }
480
+ end if Hash.method_defined? :flatten
481
+
482
+ describe :has_key? do
483
+ it 'checks request cookies' do
484
+ cookies('foo=bar').should have_key('foo')
485
+ end
486
+
487
+ it 'checks response cookies' do
488
+ jar = cookies
489
+ jar['foo'] = 'bar'
490
+ jar.should have_key(:foo)
491
+ end
492
+
493
+ it 'does not use deleted cookies' do
494
+ jar = cookies('foo=bar')
495
+ jar.delete :foo
496
+ jar.should_not have_key('foo')
497
+ end
498
+ end
499
+
500
+ describe :has_value? do
501
+ it 'checks request cookies' do
502
+ cookies('foo=bar').should have_value('bar')
503
+ end
504
+
505
+ it 'checks response cookies' do
506
+ jar = cookies
507
+ jar[:foo] = 'bar'
508
+ jar.should have_value('bar')
509
+ end
510
+
511
+ it 'does not use deleted cookies' do
512
+ jar = cookies('foo=bar')
513
+ jar.delete :foo
514
+ jar.should_not have_value('bar')
515
+ end
516
+ end
517
+
518
+ describe :include? do
519
+ it 'checks request cookies' do
520
+ cookies('foo=bar').should include('foo')
521
+ end
522
+
523
+ it 'checks response cookies' do
524
+ jar = cookies
525
+ jar['foo'] = 'bar'
526
+ jar.should include(:foo)
527
+ end
528
+
529
+ it 'does not use deleted cookies' do
530
+ jar = cookies('foo=bar')
531
+ jar.delete :foo
532
+ jar.should_not include('foo')
533
+ end
534
+ end
535
+
536
+ describe :index do
537
+ it 'checks request cookies' do
538
+ cookies('foo=bar').index('bar').should be == 'foo'
539
+ end
540
+
541
+ it 'checks response cookies' do
542
+ jar = cookies
543
+ jar['foo'] = 'bar'
544
+ jar.index('bar').should be == 'foo'
545
+ end
546
+
547
+ it 'returns nil when missing' do
548
+ cookies('foo=bar').index('baz').should be_nil
549
+ end
550
+ end if RUBY_VERSION < '1.9'
551
+
552
+ describe :keep_if do
553
+ it 'removes entries' do
554
+ jar = cookies('foo=bar', 'bar=baz')
555
+ jar.keep_if { |*args| args == ['bar', 'baz'] }
556
+ jar.should be == {'bar' => 'baz'}
557
+ end
558
+ end
559
+
560
+ describe :key do
561
+ it 'checks request cookies' do
562
+ cookies('foo=bar').key('bar').should be == 'foo'
563
+ end
564
+
565
+ it 'checks response cookies' do
566
+ jar = cookies
567
+ jar['foo'] = 'bar'
568
+ jar.key('bar').should be == 'foo'
569
+ end
570
+
571
+ it 'returns nil when missing' do
572
+ cookies('foo=bar').key('baz').should be_nil
573
+ end
574
+ end
575
+
576
+ describe :key? do
577
+ it 'checks request cookies' do
578
+ cookies('foo=bar').key?('foo').should be_true
579
+ end
580
+
581
+ it 'checks response cookies' do
582
+ jar = cookies
583
+ jar['foo'] = 'bar'
584
+ jar.key?(:foo).should be_true
585
+ end
586
+
587
+ it 'does not use deleted cookies' do
588
+ jar = cookies('foo=bar')
589
+ jar.delete :foo
590
+ jar.key?('foo').should be_false
591
+ end
592
+ end
593
+
594
+ describe :keys do
595
+ it { cookies('foo=bar').keys.should == ['foo'] }
596
+ end
597
+
598
+ describe :length do
599
+ it { cookies.length.should == 0 }
600
+ it { cookies('foo=bar').length.should == 1 }
601
+ end
602
+
603
+ describe :member? do
604
+ it 'checks request cookies' do
605
+ cookies('foo=bar').member?('foo').should be_true
606
+ end
607
+
608
+ it 'checks response cookies' do
609
+ jar = cookies
610
+ jar['foo'] = 'bar'
611
+ jar.member?(:foo).should be_true
612
+ end
613
+
614
+ it 'does not use deleted cookies' do
615
+ jar = cookies('foo=bar')
616
+ jar.delete :foo
617
+ jar.member?('foo').should be_false
618
+ end
619
+ end
620
+
621
+ describe :merge do
622
+ it 'is mergable with a hash' do
623
+ cookies('foo=bar').merge(:bar => :baz).should be == {"foo" => "bar", :bar => :baz}
624
+ end
625
+
626
+ it 'does not create cookies' do
627
+ jar = cookies('foo=bar')
628
+ jar.merge(:bar => 'baz')
629
+ jar.should_not include(:bar)
630
+ end
631
+
632
+ it 'takes a block for conflict resolution' do
633
+ update = {'foo' => 'baz', 'bar' => 'baz'}
634
+ merged = cookies('foo=bar').merge(update) do |key, old, other|
635
+ key.should be == 'foo'
636
+ old.should be == 'bar'
637
+ other.should be == 'baz'
638
+ 'foo'
639
+ end
640
+ merged['foo'].should be == 'foo'
641
+ end
642
+ end
643
+
644
+ describe :merge! do
645
+ it 'creates cookies' do
646
+ jar = cookies('foo=bar')
647
+ jar.merge! :bar => 'baz'
648
+ jar.should include('bar')
649
+ end
650
+
651
+ it 'overrides existing values' do
652
+ jar = cookies('foo=bar')
653
+ jar.merge! :foo => "baz"
654
+ jar["foo"].should be == "baz"
655
+ end
656
+
657
+ it 'takes a block for conflict resolution' do
658
+ update = {'foo' => 'baz', 'bar' => 'baz'}
659
+ jar = cookies('foo=bar')
660
+ jar.merge!(update) do |key, old, other|
661
+ key.should be == 'foo'
662
+ old.should be == 'bar'
663
+ other.should be == 'baz'
664
+ 'foo'
665
+ end
666
+ jar['foo'].should be == 'foo'
667
+ end
668
+ end
669
+
670
+ describe :rassoc do
671
+ it 'behaves like Hash#assoc' do
672
+ cookies('foo=bar').rassoc('bar') == ['foo', 'bar']
673
+ end
674
+ end if Hash.method_defined? :rassoc
675
+
676
+ describe :reject do
677
+ it 'removes entries from new hash' do
678
+ jar = cookies('foo=bar', 'bar=baz')
679
+ sub = jar.reject { |*args| args == ['bar', 'baz'] }
680
+ sub.should be == {'foo' => 'bar'}
681
+ jar['bar'].should be == 'baz'
682
+ end
683
+ end
684
+
685
+ describe :reject! do
686
+ it 'removes entries' do
687
+ jar = cookies('foo=bar', 'bar=baz')
688
+ jar.reject! { |*args| args == ['bar', 'baz'] }
689
+ jar.should be == {'foo' => 'bar'}
690
+ end
691
+ end
692
+
693
+ describe :replace do
694
+ it 'replaces entries' do
695
+ jar = cookies('foo=bar', 'bar=baz')
696
+ jar.replace 'foo' => 'baz', 'baz' => 'bar'
697
+ jar.should be == {'foo' => 'baz', 'baz' => 'bar'}
698
+ end
699
+ end
700
+
701
+ describe :select do
702
+ it 'removes entries from new hash' do
703
+ jar = cookies('foo=bar', 'bar=baz')
704
+ sub = jar.select { |*args| args != ['bar', 'baz'] }
705
+ sub.should be == {'foo' => 'bar'}.select { true }
706
+ jar['bar'].should be == 'baz'
707
+ end
708
+ end
709
+
710
+ describe :select! do
711
+ it 'removes entries' do
712
+ jar = cookies('foo=bar', 'bar=baz')
713
+ jar.select! { |*args| args != ['bar', 'baz'] }
714
+ jar.should be == {'foo' => 'bar'}
715
+ end
716
+ end if Hash.method_defined? :select!
717
+
718
+ describe :shift do
719
+ it 'removes from the hash' do
720
+ jar = cookies('foo=bar')
721
+ jar.shift.should be == ['foo', 'bar']
722
+ jar.should_not include('bar')
723
+ end
724
+ end
725
+
726
+ describe :size do
727
+ it { cookies.size.should == 0 }
728
+ it { cookies('foo=bar').size.should == 1 }
729
+ end
730
+
731
+ describe :update do
732
+ it 'creates cookies' do
733
+ jar = cookies('foo=bar')
734
+ jar.update :bar => 'baz'
735
+ jar.should include('bar')
736
+ end
737
+
738
+ it 'overrides existing values' do
739
+ jar = cookies('foo=bar')
740
+ jar.update :foo => "baz"
741
+ jar["foo"].should be == "baz"
742
+ end
743
+
744
+ it 'takes a block for conflict resolution' do
745
+ merge = {'foo' => 'baz', 'bar' => 'baz'}
746
+ jar = cookies('foo=bar')
747
+ jar.update(merge) do |key, old, other|
748
+ key.should be == 'foo'
749
+ old.should be == 'bar'
750
+ other.should be == 'baz'
751
+ 'foo'
752
+ end
753
+ jar['foo'].should be == 'foo'
754
+ end
755
+ end
756
+
757
+ describe :value? do
758
+ it 'checks request cookies' do
759
+ cookies('foo=bar').value?('bar').should be_true
760
+ end
761
+
762
+ it 'checks response cookies' do
763
+ jar = cookies
764
+ jar[:foo] = 'bar'
765
+ jar.value?('bar').should be_true
766
+ end
767
+
768
+ it 'does not use deleted cookies' do
769
+ jar = cookies('foo=bar')
770
+ jar.delete :foo
771
+ jar.value?('bar').should_not be_true
772
+ end
773
+ end
774
+
775
+ describe :values do
776
+ it { cookies('foo=bar', 'bar=baz').values.sort.should be == ['bar', 'baz'] }
777
+ end
778
+
779
+ describe :values_at do
780
+ it { cookies('foo=bar', 'bar=baz').values_at('foo').should be == ['bar'] }
781
+ end
782
+ end