diff --git a/sinatra-contrib/lib/sinatra/reloader.rb b/sinatra-contrib/lib/sinatra/reloader.rb index aa8edbe1..442f65fc 100644 --- a/sinatra-contrib/lib/sinatra/reloader.rb +++ b/sinatra-contrib/lib/sinatra/reloader.rb @@ -136,6 +136,11 @@ module Sinatra # +ExtensionMethods+ and defines a before filter to +perform+ the # reload of the modified file. def self.registered(klass) + @reloader_loaded_in ||= {} + return if @reloader_loaded_in[klass] + + @reloader_loaded_in[klass] = true + klass.extend BaseMethods klass.extend ExtensionMethods klass.set(:reloader) { klass.development? } @@ -205,6 +210,16 @@ module Sinatra )) super end + + def add_filter(type, path = nil, options = {}, &block) + 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 + )) + result + end end # Contains the methods that the extension adds to the Sinatra @@ -219,6 +234,10 @@ module Sinatra (routes[verb] ||= []).delete(signature) when :middleware then @middleware.delete(element.representation) + when :before_filter then + filters[:before].delete(element.representation) + when :after_filter then + filters[:after].delete(element.representation) end end diff --git a/sinatra-contrib/spec/reloader/app.rb.erb b/sinatra-contrib/spec/reloader/app.rb.erb index c4547048..b08277e7 100644 --- a/sinatra-contrib/spec/reloader/app.rb.erb +++ b/sinatra-contrib/spec/reloader/app.rb.erb @@ -9,6 +9,10 @@ class <%= name %> < Sinatra::Base use <%= middleware %> <% end %> +<% filters.each do |filter| %> + <%= filter %> +<% end %> + <% routes.each do |route| %> <%= route %> <% end %> diff --git a/sinatra-contrib/spec/reloader_spec.rb b/sinatra-contrib/spec/reloader_spec.rb index fad6718e..f5423071 100644 --- a/sinatra-contrib/spec/reloader_spec.rb +++ b/sinatra-contrib/spec/reloader_spec.rb @@ -41,6 +41,7 @@ describe Sinatra::Reloader do options[:routes] ||= ['get("/foo") { erb :foo }'] options[:inline_templates] ||= nil options[:middlewares] ||= [] + options[:filters] ||= [] options[:name] ||= app_name update_file(app_file_path) do |f| @@ -171,6 +172,52 @@ describe Sinatra::Reloader do end end + describe "default filter reloading mechanism" do + it "knows when a before filter has been added" do + setup_example_app(:routes => ['get("/foo") { "foo" }']) + expect { + update_app_file( + :routes => ['get("/foo") { "foo" }'], + :filters => ['before { @hi = "hi" }'] + ) + get('/foo') # ...to perform the reload + }.to change { app_const.filters[:before].size }.by(1) + end + + it "knows when an after filter has been added" do + setup_example_app(:routes => ['get("/foo") { "foo" }']) + expect { + update_app_file( + :routes => ['get("/foo") { "foo" }'], + :filters => ['after { @bye = "bye" }'] + ) + get('/foo') # ...to perform the reload + }.to change { app_const.filters[:after].size }.by(1) + end + + it "knows when a before filter has been removed" do + setup_example_app( + :routes => ['get("/foo") { "foo" }'], + :filters => ['before { @hi = "hi" }'] + ) + expect { + update_app_file(:routes => ['get("/foo") { "foo" }']) + get('/foo') # ...to perform the reload + }.to change { app_const.filters[:before].size }.by(-1) + end + + it "knows when an after filter has been removed" do + setup_example_app( + :routes => ['get("/foo") { "foo" }'], + :filters => ['after { @bye = "bye" }'] + ) + expect { + update_app_file(:routes => ['get("/foo") { "foo" }']) + get('/foo') # ...to perform the reload + }.to change { app_const.filters[:after].size }.by(-1) + end + end + describe ".dont_reload" do before(:each) do setup_example_app(