Skip to content

Commit

Permalink
Improve after_reload issues (sinatra#1692)
Browse files Browse the repository at this point in the history
* Improve `after_reload` issues
* Make `after_reload` run only if paths were updated.
* Pass the actual reloaded paths to the `after_reload` blocks.

* Fix `after_reload` spec

* Remove hardcoded filename, and check reload isn't called

* Undo oops version change

* Add rspec for existing after_reload blocks without input param

* Guard against passing lambdas

* Reset after_reload block when containing file reloaded

Co-authored-by: Jordan Owens <jkowens@gmail.com>
  • Loading branch information
lilole and jkowens committed Jul 26, 2022
1 parent 9ab6a9f commit ed34907
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
16 changes: 14 additions & 2 deletions sinatra-contrib/lib/sinatra/reloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def removed?
# Allow a block to be executed after any file being reloaded
@@after_reload = []
def after_reload(&block)
@@after_reload << block
@@after_reload << block
end

# When the extension is registered it extends the Sinatra application
Expand All @@ -242,14 +242,26 @@ def self.registered(klass)
# Reloads the modified files, adding, updating and removing the
# needed elements.
def self.perform(klass)
reloaded_paths = []
Watcher::List.for(klass).updated.each do |watcher|
klass.set(:inline_templates, watcher.path) if watcher.inline_templates?
watcher.elements.each { |element| klass.deactivate(element) }
# Deletes all old elements.
watcher.elements.delete_if { true }
$LOADED_FEATURES.delete(watcher.path)
require watcher.path
watcher.update
reloaded_paths << watcher.path
end
return if reloaded_paths.empty?
@@after_reload.each do |block|
block.arity != 0 ? block.call(reloaded_paths) : block.call
end
# Prevents after_reload from increasing each time it's reloaded.
@@after_reload.delete_if do |blk|
path, _ = blk.source_location
path && reloaded_paths.include?(path)
end
@@after_reload.each(&:call)
end

# Contains the methods defined in Sinatra::Base that are overridden.
Expand Down
36 changes: 34 additions & 2 deletions sinatra-contrib/spec/reloader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ def self.registered(klass)

describe ".after_reload" do
before(:each) do
$reloaded = nil
setup_example_app(:routes => ['get("/foo") { Foo.foo }'])
@foo_path = File.join(tmp_dir, 'foo.rb')
update_file(@foo_path) do |f|
Expand All @@ -429,15 +430,46 @@ def self.registered(klass)
end

it "allows block execution after reloading files" do
app_const.after_reload do |files|
$reloaded = files
end
expect($reloaded).to eq(nil)
expect(get('/foo').body.strip).to eq('foo')
expect($reloaded).to eq(nil) # after_reload was not called
update_file(@foo_path) do |f|
f.write 'class Foo; def self.foo() "bar" end end'
end
expect(get("/foo").body.strip).to eq("bar") # Makes the reload happen
expect($reloaded.size).to eq(1)
expect(File.basename($reloaded[0])).to eq(File.basename(@foo_path))
end

it "does not break block without input param" do
app_const.after_reload do
$reloaded = true
$reloaded = "worked without param"
end
expect($reloaded).to eq(nil)
expect(get('/foo').body.strip).to eq('foo')
expect($reloaded).to eq(nil) # after_reload was not called
update_file(@foo_path) do |f|
f.write 'class Foo; def self.foo() "bar" end end'
end
expect { get("/foo") }.to_not raise_error # Makes the reload happen
expect($reloaded).to eq("worked without param")
end

it "handles lambdas with arity 0" do
user_proc = -> { $reloaded = "lambda?=true arity=0" }
expect { user_proc.call(1) }.to raise_error(ArgumentError) # What we avoid
app_const.after_reload(&user_proc)
expect($reloaded).to eq(nil)
expect(get('/foo').body.strip).to eq('foo')
expect($reloaded).to eq(nil) # after_reload was not called
update_file(@foo_path) do |f|
f.write 'class Foo; def self.foo() "bar" end end'
end
expect($reloaded).to eq(true)
expect { get("/foo") }.to_not raise_error # Makes the reload happen
expect($reloaded).to eq("lambda?=true arity=0")
end
end

Expand Down

0 comments on commit ed34907

Please sign in to comment.