sinatra-contrib 1.3.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 +135 -0
- data/Rakefile +75 -0
- data/ideas.md +29 -0
- data/lib/sinatra/capture.rb +42 -0
- data/lib/sinatra/config_file.rb +151 -0
- data/lib/sinatra/content_for.rb +111 -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 +45 -0
- data/lib/sinatra/cookies.rb +331 -0
- data/lib/sinatra/decompile.rb +113 -0
- data/lib/sinatra/engine_tracking.rb +96 -0
- data/lib/sinatra/extension.rb +95 -0
- data/lib/sinatra/json.rb +134 -0
- data/lib/sinatra/link_header.rb +132 -0
- data/lib/sinatra/multi_route.rb +81 -0
- data/lib/sinatra/namespace.rb +282 -0
- data/lib/sinatra/reloader.rb +384 -0
- data/lib/sinatra/respond_with.rb +245 -0
- data/lib/sinatra/streaming.rb +267 -0
- data/lib/sinatra/test_helpers.rb +87 -0
- data/sinatra-contrib.gemspec +125 -0
- data/spec/capture_spec.rb +80 -0
- data/spec/config_file/key_value.yml +6 -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 +44 -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 +201 -0
- data/spec/cookies_spec.rb +782 -0
- data/spec/decompile_spec.rb +44 -0
- data/spec/extension_spec.rb +33 -0
- data/spec/json_spec.rb +115 -0
- data/spec/link_header_spec.rb +100 -0
- data/spec/multi_route_spec.rb +45 -0
- data/spec/namespace/foo.erb +1 -0
- data/spec/namespace/nested/foo.erb +1 -0
- data/spec/namespace_spec.rb +623 -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 +289 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/streaming_spec.rb +436 -0
- metadata +256 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
class <%= name %> < <%= parent %>
|
2
|
+
<% if enable_reloader %>
|
3
|
+
register Sinatra::Reloader
|
4
|
+
enable :reloader
|
5
|
+
<% end %>
|
6
|
+
<% unless inline_templates.nil? %>
|
7
|
+
enable :inline_templates
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<% extensions.each do |extension| %>
|
11
|
+
register <%= extension %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<% middlewares.each do |middleware| %>
|
15
|
+
use <%= middleware %>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<% filters.each do |filter| %>
|
19
|
+
<%= filter %>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<% errors.each do |number, code| %>
|
23
|
+
error <%= number %> do
|
24
|
+
<%= code %>
|
25
|
+
end
|
26
|
+
<% end %>
|
27
|
+
|
28
|
+
<% routes.each do |route| %>
|
29
|
+
<%= route %>
|
30
|
+
<% end %>
|
31
|
+
end
|
32
|
+
|
33
|
+
<% unless inline_templates.nil? %>
|
34
|
+
__END__
|
35
|
+
|
36
|
+
<% inline_templates.each_pair do |name, content| %>
|
37
|
+
@@<%= name %>
|
38
|
+
<%= content %>
|
39
|
+
<% end %>
|
40
|
+
<% end %>
|
@@ -0,0 +1,441 @@
|
|
1
|
+
require 'backports'
|
2
|
+
require_relative 'spec_helper'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
describe Sinatra::Reloader do
|
6
|
+
# Returns the temporary directory.
|
7
|
+
def tmp_dir
|
8
|
+
File.expand_path('../../tmp', __FILE__)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the path of the Sinatra application file created by
|
12
|
+
# +setup_example_app+.
|
13
|
+
def app_file_path
|
14
|
+
File.join(tmp_dir, "example_app_#{@@example_app_counter}.rb")
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the name of the Sinatra application created by
|
18
|
+
# +setup_example_app+: 'ExampleApp1' for the first application,
|
19
|
+
# 'ExampleApp2' fo the second one, and so on...
|
20
|
+
def app_name
|
21
|
+
"ExampleApp#{@@example_app_counter}"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the (constant of the) Sinatra application created by
|
25
|
+
# +setup_example_app+.
|
26
|
+
def app_const
|
27
|
+
Module.const_get(app_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Writes a file with a Sinatra application using the template
|
31
|
+
# located at <tt>specs/reloader/app.rb.erb</tt>. It expects an
|
32
|
+
# +options+ hash, with an array of strings containing the
|
33
|
+
# application's routes (+:routes+ key), a hash with the inline
|
34
|
+
# template's names as keys and the bodys as values
|
35
|
+
# (+:inline_templates+ key) and an optional application name
|
36
|
+
# (+:name+) otherwise +app_name+ is used.
|
37
|
+
#
|
38
|
+
# It ensures to change the written file's mtime when it already
|
39
|
+
# exists.
|
40
|
+
def write_app_file(options={})
|
41
|
+
options[:routes] ||= ['get("/foo") { erb :foo }']
|
42
|
+
options[:inline_templates] ||= nil
|
43
|
+
options[:extensions] ||= []
|
44
|
+
options[:middlewares] ||= []
|
45
|
+
options[:filters] ||= []
|
46
|
+
options[:errors] ||= {}
|
47
|
+
options[:name] ||= app_name
|
48
|
+
options[:enable_reloader] = true unless options[:enable_reloader] === false
|
49
|
+
options[:parent] ||= 'Sinatra::Base'
|
50
|
+
|
51
|
+
update_file(app_file_path) do |f|
|
52
|
+
template_path = File.expand_path('../reloader/app.rb.erb', __FILE__)
|
53
|
+
template = Tilt.new(template_path, nil, :trim => '<>')
|
54
|
+
f.write template.render(Object.new, options)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
alias update_app_file write_app_file
|
59
|
+
|
60
|
+
# It calls <tt>File.open(path, 'w', &block)</tt> all the times
|
61
|
+
# needed to change the file's mtime.
|
62
|
+
def update_file(path, &block)
|
63
|
+
original_mtime = File.exist?(path) ? File.mtime(path) : Time.at(0)
|
64
|
+
new_time = original_mtime + 1
|
65
|
+
File.open(path, 'w', &block)
|
66
|
+
File.utime(new_time, new_time, path)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Writes a Sinatra application to a file, requires the file, sets
|
70
|
+
# the new application as the one being tested and enables the
|
71
|
+
# reloader.
|
72
|
+
def setup_example_app(options={})
|
73
|
+
@@example_app_counter ||= 0
|
74
|
+
@@example_app_counter += 1
|
75
|
+
|
76
|
+
FileUtils.mkdir_p(tmp_dir)
|
77
|
+
write_app_file(options)
|
78
|
+
$LOADED_FEATURES.delete app_file_path
|
79
|
+
require app_file_path
|
80
|
+
self.app = app_const
|
81
|
+
app_const.enable :reloader
|
82
|
+
end
|
83
|
+
|
84
|
+
after(:all) { FileUtils.rm_rf(tmp_dir) }
|
85
|
+
|
86
|
+
describe "default route reloading mechanism" do
|
87
|
+
before(:each) do
|
88
|
+
setup_example_app(:routes => ['get("/foo") { "foo" }'])
|
89
|
+
end
|
90
|
+
|
91
|
+
it "doesn't mess up the application" do
|
92
|
+
get('/foo').body.should == 'foo'
|
93
|
+
end
|
94
|
+
|
95
|
+
it "knows when a route has been modified" do
|
96
|
+
update_app_file(:routes => ['get("/foo") { "bar" }'])
|
97
|
+
get('/foo').body.should == 'bar'
|
98
|
+
end
|
99
|
+
|
100
|
+
it "knows when a route has been added" do
|
101
|
+
update_app_file(
|
102
|
+
:routes => ['get("/foo") { "foo" }', 'get("/bar") { "bar" }']
|
103
|
+
)
|
104
|
+
get('/foo').body.should == 'foo'
|
105
|
+
get('/bar').body.should == 'bar'
|
106
|
+
end
|
107
|
+
|
108
|
+
it "knows when a route has been removed" do
|
109
|
+
update_app_file(:routes => ['get("/bar") { "bar" }'])
|
110
|
+
get('/foo').status.should == 404
|
111
|
+
end
|
112
|
+
|
113
|
+
it "doesn't try to reload a removed file" do
|
114
|
+
update_app_file(:routes => ['get("/foo") { "i shall not be reloaded" }'])
|
115
|
+
FileUtils.rm app_file_path
|
116
|
+
get('/foo').body.strip.should == 'foo'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "default inline templates reloading mechanism" do
|
121
|
+
before(:each) do
|
122
|
+
setup_example_app(
|
123
|
+
:routes => ['get("/foo") { erb :foo }'],
|
124
|
+
:inline_templates => { :foo => 'foo' }
|
125
|
+
)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "doesn't mess up the application" do
|
129
|
+
get('/foo').body.strip.should == 'foo'
|
130
|
+
end
|
131
|
+
|
132
|
+
it "reloads inline templates in the app file" do
|
133
|
+
update_app_file(
|
134
|
+
:routes => ['get("/foo") { erb :foo }'],
|
135
|
+
:inline_templates => { :foo => 'bar' }
|
136
|
+
)
|
137
|
+
get('/foo').body.strip.should == 'bar'
|
138
|
+
end
|
139
|
+
|
140
|
+
it "reloads inline templates in other file" do
|
141
|
+
setup_example_app(:routes => ['get("/foo") { erb :foo }'])
|
142
|
+
template_file_path = File.join(tmp_dir, 'templates.rb')
|
143
|
+
File.open(template_file_path, 'w') do |f|
|
144
|
+
f.write "__END__\n\n@@foo\nfoo"
|
145
|
+
end
|
146
|
+
require template_file_path
|
147
|
+
app_const.inline_templates= template_file_path
|
148
|
+
get('/foo').body.strip.should == 'foo'
|
149
|
+
update_file(template_file_path) do |f|
|
150
|
+
f.write "__END__\n\n@@foo\nbar"
|
151
|
+
end
|
152
|
+
get('/foo').body.strip.should == 'bar'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "default middleware reloading mechanism" do
|
157
|
+
it "knows when a middleware has been added" do
|
158
|
+
setup_example_app(:routes => ['get("/foo") { "foo" }'])
|
159
|
+
update_app_file(
|
160
|
+
:routes => ['get("/foo") { "foo" }'],
|
161
|
+
:middlewares => [Rack::Head]
|
162
|
+
)
|
163
|
+
get('/foo') # ...to perform the reload
|
164
|
+
app_const.middleware.should_not be_empty
|
165
|
+
end
|
166
|
+
|
167
|
+
it "knows when a middleware has been removed" do
|
168
|
+
setup_example_app(
|
169
|
+
:routes => ['get("/foo") { "foo" }'],
|
170
|
+
:middlewares => [Rack::Head]
|
171
|
+
)
|
172
|
+
update_app_file(:routes => ['get("/foo") { "foo" }'])
|
173
|
+
get('/foo') # ...to perform the reload
|
174
|
+
app_const.middleware.should be_empty
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "default filter reloading mechanism" do
|
179
|
+
it "knows when a before filter has been added" do
|
180
|
+
setup_example_app(:routes => ['get("/foo") { "foo" }'])
|
181
|
+
expect {
|
182
|
+
update_app_file(
|
183
|
+
:routes => ['get("/foo") { "foo" }'],
|
184
|
+
:filters => ['before { @hi = "hi" }']
|
185
|
+
)
|
186
|
+
get('/foo') # ...to perform the reload
|
187
|
+
}.to change { app_const.filters[:before].size }.by(1)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "knows when an after filter has been added" do
|
191
|
+
setup_example_app(:routes => ['get("/foo") { "foo" }'])
|
192
|
+
expect {
|
193
|
+
update_app_file(
|
194
|
+
:routes => ['get("/foo") { "foo" }'],
|
195
|
+
:filters => ['after { @bye = "bye" }']
|
196
|
+
)
|
197
|
+
get('/foo') # ...to perform the reload
|
198
|
+
}.to change { app_const.filters[:after].size }.by(1)
|
199
|
+
end
|
200
|
+
|
201
|
+
it "knows when a before filter has been removed" do
|
202
|
+
setup_example_app(
|
203
|
+
:routes => ['get("/foo") { "foo" }'],
|
204
|
+
:filters => ['before { @hi = "hi" }']
|
205
|
+
)
|
206
|
+
expect {
|
207
|
+
update_app_file(:routes => ['get("/foo") { "foo" }'])
|
208
|
+
get('/foo') # ...to perform the reload
|
209
|
+
}.to change { app_const.filters[:before].size }.by(-1)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "knows when an after filter has been removed" do
|
213
|
+
setup_example_app(
|
214
|
+
:routes => ['get("/foo") { "foo" }'],
|
215
|
+
:filters => ['after { @bye = "bye" }']
|
216
|
+
)
|
217
|
+
expect {
|
218
|
+
update_app_file(:routes => ['get("/foo") { "foo" }'])
|
219
|
+
get('/foo') # ...to perform the reload
|
220
|
+
}.to change { app_const.filters[:after].size }.by(-1)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe "error reloading" do
|
225
|
+
before do
|
226
|
+
setup_example_app(
|
227
|
+
:routes => ['get("/secret") { 403 }'],
|
228
|
+
:errors => { 403 => "'Access forbiden'" }
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "doesn't mess up the application" do
|
233
|
+
get('/secret').should be_client_error
|
234
|
+
get('/secret').body.strip.should == 'Access forbiden'
|
235
|
+
end
|
236
|
+
|
237
|
+
it "knows when a error has been added" do
|
238
|
+
update_app_file(:errors => { 404 => "'Nowhere'" })
|
239
|
+
get('/nowhere').should be_not_found
|
240
|
+
get('/nowhere').body.should == 'Nowhere'
|
241
|
+
end
|
242
|
+
|
243
|
+
it "knows when a error has been removed" do
|
244
|
+
update_app_file(:routes => ['get("/secret") { 403 }'])
|
245
|
+
get('/secret').should be_client_error
|
246
|
+
get('/secret').body.should_not == 'Access forbiden'
|
247
|
+
end
|
248
|
+
|
249
|
+
it "knows when a error has been modified" do
|
250
|
+
update_app_file(
|
251
|
+
:routes => ['get("/secret") { 403 }'],
|
252
|
+
:errors => { 403 => "'What are you doing here?'" }
|
253
|
+
)
|
254
|
+
get('/secret').should be_client_error
|
255
|
+
get('/secret').body.should == 'What are you doing here?'
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
describe "extension reloading" do
|
260
|
+
it "doesn't duplicate routes with every reload" do
|
261
|
+
module ::RouteExtension
|
262
|
+
def self.registered(klass)
|
263
|
+
klass.get('/bar') { 'bar' }
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
setup_example_app(
|
268
|
+
:routes => ['get("/foo") { "foo" }'],
|
269
|
+
:extensions => ['RouteExtension']
|
270
|
+
)
|
271
|
+
|
272
|
+
expect {
|
273
|
+
update_app_file(
|
274
|
+
:routes => ['get("/foo") { "foo" }'],
|
275
|
+
:extensions => ['RouteExtension']
|
276
|
+
)
|
277
|
+
get('/foo') # ...to perform the reload
|
278
|
+
}.to_not change { app_const.routes['GET'].size }
|
279
|
+
end
|
280
|
+
|
281
|
+
it "doesn't duplicate middleware with every reload" do
|
282
|
+
module ::MiddlewareExtension
|
283
|
+
def self.registered(klass)
|
284
|
+
klass.use Rack::Head
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
setup_example_app(
|
289
|
+
:routes => ['get("/foo") { "foo" }'],
|
290
|
+
:extensions => ['MiddlewareExtension']
|
291
|
+
)
|
292
|
+
|
293
|
+
expect {
|
294
|
+
update_app_file(
|
295
|
+
:routes => ['get("/foo") { "foo" }'],
|
296
|
+
:extensions => ['MiddlewareExtension']
|
297
|
+
)
|
298
|
+
get('/foo') # ...to perform the reload
|
299
|
+
}.to_not change { app_const.middleware.size }
|
300
|
+
end
|
301
|
+
|
302
|
+
it "doesn't duplicate before filters with every reload" do
|
303
|
+
module ::BeforeFilterExtension
|
304
|
+
def self.registered(klass)
|
305
|
+
klass.before { @hi = 'hi' }
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
setup_example_app(
|
310
|
+
:routes => ['get("/foo") { "foo" }'],
|
311
|
+
:extensions => ['BeforeFilterExtension']
|
312
|
+
)
|
313
|
+
|
314
|
+
expect {
|
315
|
+
update_app_file(
|
316
|
+
:routes => ['get("/foo") { "foo" }'],
|
317
|
+
:extensions => ['BeforeFilterExtension']
|
318
|
+
)
|
319
|
+
get('/foo') # ...to perform the reload
|
320
|
+
}.to_not change { app_const.filters[:before].size }
|
321
|
+
end
|
322
|
+
|
323
|
+
it "doesn't duplicate after filters with every reload" do
|
324
|
+
module ::AfterFilterExtension
|
325
|
+
def self.registered(klass)
|
326
|
+
klass.after { @bye = 'bye' }
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
setup_example_app(
|
331
|
+
:routes => ['get("/foo") { "foo" }'],
|
332
|
+
:extensions => ['AfterFilterExtension']
|
333
|
+
)
|
334
|
+
|
335
|
+
expect {
|
336
|
+
update_app_file(
|
337
|
+
:routes => ['get("/foo") { "foo" }'],
|
338
|
+
:extensions => ['AfterFilterExtension']
|
339
|
+
)
|
340
|
+
get('/foo') # ...to perform the reload
|
341
|
+
}.to_not change { app_const.filters[:after].size }
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
describe ".dont_reload" do
|
346
|
+
before(:each) do
|
347
|
+
setup_example_app(
|
348
|
+
:routes => ['get("/foo") { erb :foo }'],
|
349
|
+
:inline_templates => { :foo => 'foo' }
|
350
|
+
)
|
351
|
+
end
|
352
|
+
|
353
|
+
it "allows to specify a file to stop from being reloaded" do
|
354
|
+
app_const.dont_reload app_file_path
|
355
|
+
update_app_file(:routes => ['get("/foo") { "bar" }'])
|
356
|
+
get('/foo').body.strip.should == 'foo'
|
357
|
+
end
|
358
|
+
|
359
|
+
it "allows to specify a glob to stop matching files from being reloaded" do
|
360
|
+
app_const.dont_reload '**/*.rb'
|
361
|
+
update_app_file(:routes => ['get("/foo") { "bar" }'])
|
362
|
+
get('/foo').body.strip.should == 'foo'
|
363
|
+
end
|
364
|
+
|
365
|
+
it "doesn't interfere with other application's reloading policy" do
|
366
|
+
app_const.dont_reload '**/*.rb'
|
367
|
+
setup_example_app(:routes => ['get("/foo") { "foo" }'])
|
368
|
+
update_app_file(:routes => ['get("/foo") { "bar" }'])
|
369
|
+
get('/foo').body.strip.should == 'bar'
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
describe ".also_reload" do
|
374
|
+
before(:each) do
|
375
|
+
setup_example_app(:routes => ['get("/foo") { Foo.foo }'])
|
376
|
+
@foo_path = File.join(tmp_dir, 'foo.rb')
|
377
|
+
update_file(@foo_path) do |f|
|
378
|
+
f.write 'class Foo; def self.foo() "foo" end end'
|
379
|
+
end
|
380
|
+
$LOADED_FEATURES.delete @foo_path
|
381
|
+
require @foo_path
|
382
|
+
app_const.also_reload @foo_path
|
383
|
+
end
|
384
|
+
|
385
|
+
it "allows to specify a file to be reloaded" do
|
386
|
+
get('/foo').body.strip.should == 'foo'
|
387
|
+
update_file(@foo_path) do |f|
|
388
|
+
f.write 'class Foo; def self.foo() "bar" end end'
|
389
|
+
end
|
390
|
+
get('/foo').body.strip.should == 'bar'
|
391
|
+
end
|
392
|
+
|
393
|
+
it "allows to specify glob to reaload matching files" do
|
394
|
+
get('/foo').body.strip.should == 'foo'
|
395
|
+
update_file(@foo_path) do |f|
|
396
|
+
f.write 'class Foo; def self.foo() "bar" end end'
|
397
|
+
end
|
398
|
+
get('/foo').body.strip.should == 'bar'
|
399
|
+
end
|
400
|
+
|
401
|
+
it "doesn't try to reload a removed file" do
|
402
|
+
update_file(@foo_path) do |f|
|
403
|
+
f.write 'class Foo; def self.foo() "bar" end end'
|
404
|
+
end
|
405
|
+
FileUtils.rm @foo_path
|
406
|
+
get('/foo').body.strip.should == 'foo'
|
407
|
+
end
|
408
|
+
|
409
|
+
it "doesn't interfere with other application's reloading policy" do
|
410
|
+
app_const.also_reload '**/*.rb'
|
411
|
+
setup_example_app(:routes => ['get("/foo") { Foo.foo }'])
|
412
|
+
get('/foo').body.strip.should == 'foo'
|
413
|
+
update_file(@foo_path) do |f|
|
414
|
+
f.write 'class Foo; def self.foo() "bar" end end'
|
415
|
+
end
|
416
|
+
get('/foo').body.strip.should == 'foo'
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
it "automatically registers the reloader in the subclasses" do
|
421
|
+
class ::Parent < Sinatra::Base
|
422
|
+
register Sinatra::Reloader
|
423
|
+
enable :reloader
|
424
|
+
end
|
425
|
+
|
426
|
+
setup_example_app(
|
427
|
+
:routes => ['get("/foo") { "foo" }'],
|
428
|
+
:enable_reloader => false,
|
429
|
+
:parent => 'Parent'
|
430
|
+
)
|
431
|
+
|
432
|
+
update_app_file(
|
433
|
+
:routes => ['get("/foo") { "bar" }'],
|
434
|
+
:enable_reloader => false,
|
435
|
+
:parent => 'Parent'
|
436
|
+
)
|
437
|
+
|
438
|
+
get('/foo').body.should == 'bar'
|
439
|
+
end
|
440
|
+
|
441
|
+
end
|