rf-web/vendor/bundle/gems/rb-inotify-0.10.0/spec/notifier_spec.rb

171 lines
4.2 KiB
Ruby
Raw Normal View History

2019-10-21 08:18:17 +00:00
require 'spec_helper'
require 'tmpdir'
require 'concurrent'
describe INotify::Notifier do
describe "instance" do
around do |block|
Dir.mktmpdir do |dir|
@root = Pathname.new(dir)
@notifier = INotify::Notifier.new
begin
block.call
ensure
@notifier.close
end
end
end
let(:dir) do
@root.join("foo").tap(&:mkdir)
end
let(:another_dir) do
@root.join("bar").tap(&:mkdir)
end
it "stops" do
@notifier.stop
end
describe :process do
it "gets events" do
events = recording(dir, :create)
dir.join("test.txt").write("hello world")
@notifier.process
expect(events.size).to eq(1)
expect(events.first.name).to eq("test.txt")
expect(events.first.absolute_name).to eq(dir.join("test.txt").to_s)
end
it "gets simultaneous events" do
events = recording(dir, :create)
dir.join("one.txt").write("hello world")
dir.join("two.txt").write("hello world")
@notifier.process
expect(events.map(&:name)).to match_array(%w(one.txt two.txt))
end
it "separates events between watches" do
bar_events = nil
foo_events = recording(dir, :create)
bar_events = recording(another_dir, :create)
dir.join("test.txt").write("hello world")
another_dir.join("test_two.txt").write("hello world")
@notifier.process
expect(foo_events.size).to eq(1)
expect(foo_events.first.name).to eq("test.txt")
expect(foo_events.first.absolute_name).to eq(dir.join("test.txt").to_s)
expect(bar_events.size).to eq(1)
expect(bar_events.first.name).to eq("test_two.txt")
expect(bar_events.first.absolute_name).to eq(another_dir.join("test_two.txt").to_s)
end
end
describe :run do
it "processes repeatedly until stopped" do
barriers = Array.new(3) { Concurrent::Event.new }
barrier_queue = barriers.dup
events = recording(dir, :create) { barrier_queue.shift.set }
run_thread = Thread.new { @notifier.run }
dir.join("one.txt").write("hello world")
barriers.shift.wait(1) or raise "timeout"
expect(events.map(&:name)).to match_array(%w(one.txt))
dir.join("two.txt").write("hello world")
barriers.shift.wait(1) or raise "timeout"
expect(events.map(&:name)).to match_array(%w(one.txt two.txt))
@notifier.stop
dir.join("three.txt").write("hello world")
barriers.shift.wait(1)
dir.join("four.txt").write("hello world")
run_thread.join
expect(events.map(&:name)).to match_array(%w(one.txt two.txt))
end
end
describe :fd do
it "returns an integer" do
expect(@notifier.fd).to be_an(Integer)
end
end
describe :to_io do
it "returns a ruby IO" do
expect(@notifier.to_io).to be_an(::IO)
end
it "matches the fd" do
expect(@notifier.to_io.fileno).to eq(@notifier.fd)
end
it "caches its result" do
expect(@notifier.to_io).to be(@notifier.to_io)
end
it "is selectable" do
events = recording(dir, :create)
expect(select([@notifier.to_io], nil, nil, 0.2)).to be_nil
dir.join("test.txt").write("hello world")
expect(select([@notifier.to_io], nil, nil, 0.2)).to eq([[@notifier.to_io], [], []])
@notifier.process
expect(select([@notifier.to_io], nil, nil, 0.2)).to be_nil
end
end
private
def recording(dir, *flags, callback: nil)
events = []
@notifier.watch(dir.to_s, *flags) do |event|
events << event
yield if block_given?
end
events
end
end
describe "mixed instances" do
it "doesn't tangle fds" do
notifiers = Array.new(30) { INotify::Notifier.new }
notifiers.each(&:to_io)
one = Array.new(10) { IO.pipe.last }
notifiers.each(&:close)
two = Array.new(10) { IO.pipe.last }
notifiers = nil
GC.start
_, writable, _ = select(nil, one, nil, 1)
expect(writable).to match_array(one)
_, writable, _ = select(nil, two, nil, 1)
expect(writable).to match_array(two)
end
end
end