Skip to content

Commit

Permalink
Add ChangeObserver.unregister
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Jun 1, 2022
1 parent eec400e commit 26fcb55
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/bootsnap/load_path_cache/cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def push_paths(sender, *paths)
def reinitialize(path_obj = @path_obj)
@mutex.synchronize do
@path_obj = path_obj
ChangeObserver.register(self, @path_obj)
ChangeObserver.register(@path_obj, self)
@index = {}
@dirs = {}
@generated_at = now
Expand Down
15 changes: 13 additions & 2 deletions lib/bootsnap/load_path_cache/change_observer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,22 @@ def uniq!(*args)
end
end

def self.register(observer, arr)
def self.register(arr, observer)
return if arr.frozen? # can't register observer, but no need to.

arr.instance_variable_set(:@lpc_observer, observer)
arr.extend(ArrayMixin)
ArrayMixin.instance_methods.each do |method_name|
arr.singleton_class.send(:define_method, method_name, ArrayMixin.instance_method(method_name))
end
end

def self.unregister(arr)
return unless arr.instance_variable_get(:@lpc_observer)

ArrayMixin.instance_methods.each do |method_name|
arr.singleton_class.send(:remove_method, method_name)
end
arr.instance_variable_set(:@lpc_observer, nil)
end
end
end
Expand Down
25 changes: 22 additions & 3 deletions test/load_path_cache/change_observer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class ChangeObserverTest < MiniTest::Test
def setup
@observer = Object.new
@arr = []
ChangeObserver.register(@observer, @arr)
ChangeObserver.register(@arr, @observer)
end

def test_observes_changes
Expand All @@ -31,6 +31,25 @@ def test_observes_changes
@arr.prepend("j", "k")
end

def test_unregister
@observer.expects(:push_paths).never
@observer.expects(:unshift_paths).never
@observer.expects(:reinitialize).never

ChangeObserver.unregister(@arr)

@arr << "a"
@arr.push("b", "c")
@arr.append("d", "e")
@arr.unshift("f", "g")
@arr.concat(%w(h i))
@arr.prepend("j", "k")
@arr.delete(3)
@arr.compact!
@arr.map!(&:upcase)
assert_equal %w(J K F G A B C D E H I), @arr
end

def test_reinitializes_on_aggressive_modifications
@observer.expects(:push_paths).with(@arr, "a", "b", "c")
@arr.push("a", "b", "c")
Expand All @@ -45,11 +64,11 @@ def test_reinitializes_on_aggressive_modifications

def test_register_frozen
# just assert no crash
ChangeObserver.register(@observer, @arr.dup.freeze)
ChangeObserver.register(@arr.dup.freeze, @observer)
end

def test_register_twice_observes_once
ChangeObserver.register(@observer, @arr)
ChangeObserver.register(@arr, @observer)

@observer.expects(:push_paths).with(@arr, "a").once
@arr << "a"
Expand Down

0 comments on commit 26fcb55

Please # to comment.