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