extension reloading
This commit is contained in:
parent
c562abc2c9
commit
4e01a613a8
|
@ -183,9 +183,9 @@ module Sinatra
|
|||
source_location = block.respond_to?(:source_location) ?
|
||||
block.source_location.first : caller_files[1]
|
||||
signature = super
|
||||
Watcher::List.for(self).watch(source_location, Watcher::Element.new(
|
||||
:route, { :verb => verb, :signature => signature }
|
||||
))
|
||||
watch_element(
|
||||
source_location, :route, { :verb => verb, :signature => signature }
|
||||
)
|
||||
signature
|
||||
end
|
||||
|
||||
|
@ -196,7 +196,7 @@ module Sinatra
|
|||
def inline_templates=(file=nil)
|
||||
file = (file.nil? || file == true) ?
|
||||
(caller_files[1] || File.expand_path($0)) : file
|
||||
Watcher::List.for(self).watch_inline_templates(file)
|
||||
watch_element(file, :inline_templates)
|
||||
super
|
||||
end
|
||||
|
||||
|
@ -205,9 +205,7 @@ module Sinatra
|
|||
# middleware beign used.
|
||||
def use(middleware, *args, &block)
|
||||
path = caller_files[1] || File.expand_path($0)
|
||||
Watcher::List.for(self).watch(path, Watcher::Element.new(
|
||||
:middleware, [middleware, args, block]
|
||||
))
|
||||
watch_element(path, :middleware, [middleware, args, block])
|
||||
super
|
||||
end
|
||||
|
||||
|
@ -215,9 +213,18 @@ module Sinatra
|
|||
source_location = block.respond_to?(:source_location) ?
|
||||
block.source_location.first : caller_files[1]
|
||||
result = super
|
||||
Watcher::List.for(self).watch(source_location, Watcher::Element.new(
|
||||
:"#{type}_filter", filters[type].last
|
||||
))
|
||||
watch_element(source_location, :"#{type}_filter", filters[type].last)
|
||||
result
|
||||
end
|
||||
|
||||
# Does everything Sinatra::Base#register does, but it also lets
|
||||
# the reloader know that an extension is beign registered, because
|
||||
# the elements defined in its +registered+ method need a special
|
||||
# treatment.
|
||||
def register(*extensions, &block)
|
||||
start_registering_extension
|
||||
result = super
|
||||
stop_registering_extension
|
||||
result
|
||||
end
|
||||
end
|
||||
|
@ -253,6 +260,44 @@ module Sinatra
|
|||
def dont_reload(glob)
|
||||
Dir[glob].each { |path| Watcher::List.for(self).ignore(path) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :register_path
|
||||
|
||||
# Indicates an extesion is beign registered.
|
||||
def start_registering_extension
|
||||
@register_path = caller_files[2]
|
||||
end
|
||||
|
||||
# Indicates the extesion has been registered.
|
||||
def stop_registering_extension
|
||||
@register_path = nil
|
||||
end
|
||||
|
||||
# Indicates whether or not an extension is being registered.
|
||||
def registering_extension?
|
||||
!register_path.nil?
|
||||
end
|
||||
|
||||
# Builds a Watcher::Element from +type+ and +representation+ and
|
||||
# tells the Watcher::List for the current application to watch it
|
||||
# in the file located at +path+.
|
||||
#
|
||||
# If an extension is beign registered, it also tells the list to
|
||||
# watch it in the file where the extesion has been registered.
|
||||
# This prevents the duplication of the elements added by the
|
||||
# extension in its +registered+ method with every reload.
|
||||
def watch_element(path, type, representation=nil)
|
||||
list = Watcher::List.for(self)
|
||||
if type == :inline_templates
|
||||
list.watch_inline_templates(path)
|
||||
else
|
||||
element = Watcher::Element.new(type, representation)
|
||||
list.watch(path, element)
|
||||
list.watch(register_path, element) if registering_extension?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@ class <%= name %> < Sinatra::Base
|
|||
enable :inline_templates
|
||||
<% end %>
|
||||
|
||||
<% extensions.each do |extension| %>
|
||||
register <%= extension %>
|
||||
<% end %>
|
||||
|
||||
<% middlewares.each do |middleware| %>
|
||||
use <%= middleware %>
|
||||
<% end %>
|
||||
|
|
|
@ -40,6 +40,7 @@ describe Sinatra::Reloader do
|
|||
def write_app_file(options={})
|
||||
options[:routes] ||= ['get("/foo") { erb :foo }']
|
||||
options[:inline_templates] ||= nil
|
||||
options[:extensions] ||= []
|
||||
options[:middlewares] ||= []
|
||||
options[:filters] ||= []
|
||||
options[:name] ||= app_name
|
||||
|
@ -218,6 +219,100 @@ describe Sinatra::Reloader do
|
|||
end
|
||||
end
|
||||
|
||||
describe "extension reloading" do
|
||||
it "doesn't duplicate routes with every reload" do
|
||||
module ::RouteExtension
|
||||
def self.registered(klass)
|
||||
klass.get('/bar') { 'bar' }
|
||||
end
|
||||
end
|
||||
|
||||
setup_example_app(
|
||||
:routes => ['get("/foo") { "foo" }'],
|
||||
:extensions => ['RouteExtension']
|
||||
)
|
||||
|
||||
expect {
|
||||
3.times do
|
||||
update_app_file(
|
||||
:routes => ['get("/foo") { "foo" }'],
|
||||
:extensions => ['RouteExtension']
|
||||
)
|
||||
get('/foo') # ...to perform the reload
|
||||
end
|
||||
}.to_not change { app_const.routes['GET'].size }
|
||||
end
|
||||
|
||||
it "doesn't duplicate middleware with every reload" do
|
||||
module ::MiddlewareExtension
|
||||
def self.registered(klass)
|
||||
klass.use Rack::Head
|
||||
end
|
||||
end
|
||||
|
||||
setup_example_app(
|
||||
:routes => ['get("/foo") { "foo" }'],
|
||||
:extensions => ['MiddlewareExtension']
|
||||
)
|
||||
|
||||
expect {
|
||||
3.times do
|
||||
update_app_file(
|
||||
:routes => ['get("/foo") { "foo" }'],
|
||||
:extensions => ['MiddlewareExtension']
|
||||
)
|
||||
get('/foo') # ...to perform the reload
|
||||
end
|
||||
}.to_not change { app_const.middleware.size }
|
||||
end
|
||||
|
||||
it "doesn't duplicate before filters with every reload" do
|
||||
module ::BeforeFilterExtension
|
||||
def self.registered(klass)
|
||||
klass.before { @hi = 'hi' }
|
||||
end
|
||||
end
|
||||
|
||||
setup_example_app(
|
||||
:routes => ['get("/foo") { "foo" }'],
|
||||
:extensions => ['BeforeFilterExtension']
|
||||
)
|
||||
|
||||
expect {
|
||||
3.times do
|
||||
update_app_file(
|
||||
:routes => ['get("/foo") { "foo" }'],
|
||||
:extensions => ['BeforeFilterExtension']
|
||||
)
|
||||
get('/foo') # ...to perform the reload
|
||||
end
|
||||
}.to_not change { app_const.filters[:before].size }
|
||||
end
|
||||
|
||||
it "doesn't duplicate after filters with every reload" do
|
||||
module ::AfterFilterExtension
|
||||
def self.registered(klass)
|
||||
klass.after { @bye = 'bye' }
|
||||
end
|
||||
end
|
||||
|
||||
setup_example_app(
|
||||
:routes => ['get("/foo") { "foo" }'],
|
||||
:extensions => ['AfterFilterExtension']
|
||||
)
|
||||
|
||||
expect {
|
||||
3.times do
|
||||
update_app_file(
|
||||
:routes => ['get("/foo") { "foo" }'],
|
||||
:extensions => ['AfterFilterExtension']
|
||||
)
|
||||
get('/foo') # ...to perform the reload
|
||||
end
|
||||
}.to_not change { app_const.filters[:after].size }
|
||||
end
|
||||
end
|
||||
|
||||
describe ".dont_reload" do
|
||||
before(:each) do
|
||||
setup_example_app(
|
||||
|
|
Loading…
Reference in New Issue