listen 2.7.4 → 2.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +232 -0
- data/.travis.yml +6 -3
- data/Gemfile +9 -1
- data/Guardfile +6 -1
- data/README.md +17 -4
- data/lib/listen.rb +9 -4
- data/lib/listen/adapter.rb +5 -7
- data/lib/listen/adapter/base.rb +8 -5
- data/lib/listen/adapter/bsd.rb +58 -21
- data/lib/listen/adapter/darwin.rb +2 -4
- data/lib/listen/adapter/linux.rb +20 -10
- data/lib/listen/adapter/polling.rb +0 -2
- data/lib/listen/adapter/tcp.rb +6 -5
- data/lib/listen/adapter/windows.rb +8 -6
- data/lib/listen/change.rb +1 -2
- data/lib/listen/cli.rb +25 -22
- data/lib/listen/directory.rb +8 -6
- data/lib/listen/listener.rb +25 -19
- data/lib/listen/record.rb +4 -2
- data/lib/listen/silencer.rb +55 -25
- data/lib/listen/tcp.rb +9 -0
- data/lib/listen/tcp/broadcaster.rb +0 -2
- data/lib/listen/tcp/listener.rb +13 -8
- data/lib/listen/tcp/message.rb +0 -2
- data/lib/listen/version.rb +1 -1
- data/listen.gemspec +4 -3
- data/spec/acceptance/listen_spec.rb +190 -109
- data/spec/acceptance/tcp_spec.rb +28 -26
- data/spec/lib/listen/adapter/base_spec.rb +14 -12
- data/spec/lib/listen/adapter/bsd_spec.rb +5 -2
- data/spec/lib/listen/adapter/darwin_spec.rb +5 -2
- data/spec/lib/listen/adapter/linux_spec.rb +40 -25
- data/spec/lib/listen/adapter/polling_spec.rb +29 -14
- data/spec/lib/listen/adapter/tcp_spec.rb +24 -6
- data/spec/lib/listen/adapter/windows_spec.rb +5 -2
- data/spec/lib/listen/adapter_spec.rb +20 -17
- data/spec/lib/listen/change_spec.rb +36 -26
- data/spec/lib/listen/directory_spec.rb +128 -71
- data/spec/lib/listen/file_spec.rb +67 -34
- data/spec/lib/listen/listener_spec.rb +135 -105
- data/spec/lib/listen/record_spec.rb +32 -29
- data/spec/lib/listen/silencer_spec.rb +78 -56
- data/spec/lib/listen/tcp/broadcaster_spec.rb +3 -2
- data/spec/lib/listen/tcp/listener_spec.rb +17 -11
- data/spec/lib/listen/tcp/message_spec.rb +1 -1
- data/spec/lib/listen_spec.rb +18 -6
- data/spec/spec_helper.rb +5 -1
- data/spec/support/acceptance_helper.rb +3 -3
- data/spec/support/fixtures_helper.rb +10 -9
- metadata +17 -15
data/spec/acceptance/tcp_spec.rb
CHANGED
@@ -6,14 +6,16 @@ describe Listen::TCP do
|
|
6
6
|
|
7
7
|
let(:broadcaster) { Listen.to(Dir.pwd, forward_to: port) }
|
8
8
|
let(:recipient) { Listen.on(port) }
|
9
|
-
let(:callback)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
let(:callback) do
|
10
|
+
lambda do |modified, added, removed|
|
11
|
+
add_changes(:modified, modified)
|
12
|
+
add_changes(:added, added)
|
13
|
+
add_changes(:removed, removed)
|
14
|
+
end
|
15
|
+
end
|
14
16
|
let(:paths) { Pathname.new(Dir.pwd) }
|
15
17
|
|
16
|
-
around { |example| fixtures {
|
18
|
+
around { |example| fixtures { example.run } }
|
17
19
|
|
18
20
|
before do
|
19
21
|
broadcaster.start
|
@@ -25,9 +27,9 @@ describe Listen::TCP do
|
|
25
27
|
end
|
26
28
|
|
27
29
|
it 'still handles local changes' do
|
28
|
-
expect(listen
|
30
|
+
expect(listen do
|
29
31
|
touch 'file.rb'
|
30
|
-
|
32
|
+
end).to eq(
|
31
33
|
modified: [],
|
32
34
|
added: ['file.rb'],
|
33
35
|
removed: []
|
@@ -37,9 +39,9 @@ describe Listen::TCP do
|
|
37
39
|
it 'may be paused and unpaused' do
|
38
40
|
broadcaster.pause
|
39
41
|
|
40
|
-
expect(listen
|
42
|
+
expect(listen do
|
41
43
|
touch 'file.rb'
|
42
|
-
|
44
|
+
end).to eq(
|
43
45
|
modified: [],
|
44
46
|
added: [],
|
45
47
|
removed: []
|
@@ -47,9 +49,9 @@ describe Listen::TCP do
|
|
47
49
|
|
48
50
|
broadcaster.unpause
|
49
51
|
|
50
|
-
expect(listen
|
52
|
+
expect(listen do
|
51
53
|
touch 'file.rb'
|
52
|
-
|
54
|
+
end).to eq(
|
53
55
|
modified: ['file.rb'],
|
54
56
|
added: [],
|
55
57
|
removed: []
|
@@ -59,9 +61,9 @@ describe Listen::TCP do
|
|
59
61
|
it 'may be stopped and restarted' do
|
60
62
|
broadcaster.stop
|
61
63
|
|
62
|
-
expect(listen
|
64
|
+
expect(listen do
|
63
65
|
touch 'file.rb'
|
64
|
-
|
66
|
+
end).to eq(
|
65
67
|
modified: [],
|
66
68
|
added: [],
|
67
69
|
removed: []
|
@@ -69,9 +71,9 @@ describe Listen::TCP do
|
|
69
71
|
|
70
72
|
broadcaster.start
|
71
73
|
|
72
|
-
expect(listen
|
74
|
+
expect(listen do
|
73
75
|
touch 'file.rb'
|
74
|
-
|
76
|
+
end).to eq(
|
75
77
|
modified: ['file.rb'],
|
76
78
|
added: [],
|
77
79
|
removed: []
|
@@ -86,9 +88,9 @@ describe Listen::TCP do
|
|
86
88
|
end
|
87
89
|
|
88
90
|
it 'receives changes over TCP' do
|
89
|
-
expect(listen(1)
|
91
|
+
expect(listen(1) do
|
90
92
|
touch 'file.rb'
|
91
|
-
|
93
|
+
end).to eq(
|
92
94
|
modified: [],
|
93
95
|
added: ['file.rb'],
|
94
96
|
removed: []
|
@@ -98,9 +100,9 @@ describe Listen::TCP do
|
|
98
100
|
it 'may be paused and unpaused' do
|
99
101
|
recipient.pause
|
100
102
|
|
101
|
-
expect(listen(1)
|
103
|
+
expect(listen(1) do
|
102
104
|
touch 'file.rb'
|
103
|
-
|
105
|
+
end).to eq(
|
104
106
|
modified: [],
|
105
107
|
added: [],
|
106
108
|
removed: []
|
@@ -108,9 +110,9 @@ describe Listen::TCP do
|
|
108
110
|
|
109
111
|
recipient.unpause
|
110
112
|
|
111
|
-
expect(listen(1)
|
113
|
+
expect(listen(1) do
|
112
114
|
touch 'file.rb'
|
113
|
-
|
115
|
+
end).to eq(
|
114
116
|
modified: ['file.rb'],
|
115
117
|
added: [],
|
116
118
|
removed: []
|
@@ -120,9 +122,9 @@ describe Listen::TCP do
|
|
120
122
|
it 'may be stopped and restarted' do
|
121
123
|
recipient.stop
|
122
124
|
|
123
|
-
expect(listen(1)
|
125
|
+
expect(listen(1) do
|
124
126
|
touch 'file.rb'
|
125
|
-
|
127
|
+
end).to eq(
|
126
128
|
modified: [],
|
127
129
|
added: [],
|
128
130
|
removed: []
|
@@ -130,9 +132,9 @@ describe Listen::TCP do
|
|
130
132
|
|
131
133
|
recipient.start
|
132
134
|
|
133
|
-
expect(listen(1)
|
135
|
+
expect(listen(1) do
|
134
136
|
touch 'file.rb'
|
135
|
-
|
137
|
+
end).to eq(
|
136
138
|
modified: ['file.rb'],
|
137
139
|
added: [],
|
138
140
|
removed: []
|
@@ -5,30 +5,32 @@ describe Listen::Adapter::Base do
|
|
5
5
|
let(:registry) { double(Celluloid::Registry) }
|
6
6
|
let(:listener) { double(Listen::Listener, registry: registry, options: {}) }
|
7
7
|
|
8
|
-
describe
|
9
|
-
it
|
10
|
-
|
8
|
+
describe '#_latency' do
|
9
|
+
it 'returns default_latency with listener actor latency not present' do
|
10
|
+
latency = Listen::Adapter::Base::DEFAULT_LATENCY
|
11
|
+
expect(adapter.send(:_latency)).to eq latency
|
11
12
|
end
|
12
13
|
|
13
|
-
it
|
14
|
+
it 'returns latency from listener actor if present' do
|
14
15
|
listener.stub(:options) { { latency: 1234 } }
|
15
16
|
expect(adapter.send(:_latency)).to eq 1234
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
|
-
describe
|
20
|
+
describe '#_notify_change' do
|
20
21
|
let(:change_pool) { double(Listen::Change) }
|
21
22
|
let(:change_pool_async) { double('ChangePoolAsync') }
|
22
|
-
before
|
23
|
+
before do
|
23
24
|
change_pool.stub(:async) { change_pool_async }
|
24
25
|
registry.stub(:[]).with(:change_pool) { change_pool }
|
25
|
-
|
26
|
+
end
|
26
27
|
|
27
|
-
context
|
28
|
-
before { listener.stub(:listen?) { true} }
|
28
|
+
context 'listener listen' do
|
29
|
+
before { listener.stub(:listen?) { true } }
|
29
30
|
|
30
|
-
it
|
31
|
-
expect(change_pool_async).to receive(:change).
|
31
|
+
it 'calls change on change_pool asynchronously' do
|
32
|
+
expect(change_pool_async).to receive(:change).
|
33
|
+
with('path', type: 'Dir', recurcise: true)
|
32
34
|
adapter.send(:_notify_change, 'path', type: 'Dir', recurcise: true)
|
33
35
|
end
|
34
36
|
end
|
@@ -36,7 +38,7 @@ describe Listen::Adapter::Base do
|
|
36
38
|
context "listener doesn't listen" do
|
37
39
|
before { listener.stub(:listen?) { false } }
|
38
40
|
|
39
|
-
it
|
41
|
+
it 'calls change on change_pool asynchronously' do
|
40
42
|
expect(change_pool_async).to_not receive(:change)
|
41
43
|
adapter.send(:_notify_change, 'path', type: 'Dir', recurcise: true)
|
42
44
|
end
|
@@ -6,8 +6,8 @@ describe Listen::Adapter::BSD do
|
|
6
6
|
let(:listener) { double(Listen::Listener) }
|
7
7
|
let(:adapter) { described_class.new(listener) }
|
8
8
|
|
9
|
-
describe
|
10
|
-
it
|
9
|
+
describe '.usable?' do
|
10
|
+
it 'returns always true' do
|
11
11
|
expect(described_class).to be_usable
|
12
12
|
end
|
13
13
|
|
@@ -36,4 +36,7 @@ describe Listen::Adapter::BSD do
|
|
36
36
|
expect(described_class).to_not be_usable
|
37
37
|
end
|
38
38
|
end
|
39
|
+
|
40
|
+
specify { expect(described_class).to be_local_fs }
|
41
|
+
|
39
42
|
end
|
@@ -5,8 +5,8 @@ describe Listen::Adapter::Darwin do
|
|
5
5
|
let(:listener) { double(Listen::Listener) }
|
6
6
|
let(:adapter) { described_class.new(listener) }
|
7
7
|
|
8
|
-
describe
|
9
|
-
it
|
8
|
+
describe '.usable?' do
|
9
|
+
it 'returns always true' do
|
10
10
|
expect(described_class).to be_usable
|
11
11
|
end
|
12
12
|
end
|
@@ -36,4 +36,7 @@ describe Listen::Adapter::Darwin do
|
|
36
36
|
expect(described_class).to_not be_usable
|
37
37
|
end
|
38
38
|
end
|
39
|
+
|
40
|
+
specify { expect(described_class).to be_local_fs }
|
41
|
+
|
39
42
|
end
|
@@ -5,8 +5,8 @@ describe Listen::Adapter::Linux do
|
|
5
5
|
let(:listener) { double(Listen::Listener) }
|
6
6
|
let(:adapter) { described_class.new(listener) }
|
7
7
|
|
8
|
-
describe
|
9
|
-
it
|
8
|
+
describe '.usable?' do
|
9
|
+
it 'returns always true' do
|
10
10
|
expect(described_class).to be_usable
|
11
11
|
end
|
12
12
|
end
|
@@ -14,60 +14,72 @@ describe Listen::Adapter::Linux do
|
|
14
14
|
describe '#initialize' do
|
15
15
|
it 'requires rb-inotify gem' do
|
16
16
|
described_class.new(listener)
|
17
|
-
expect(defined?(INotify)).to
|
17
|
+
expect(defined?(INotify)).to be
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
# workaround: Celluloid ignores SystemExit exception messages
|
22
|
-
describe
|
22
|
+
describe 'inotify limit message' do
|
23
23
|
let!(:adapter) { described_class.new(listener) }
|
24
|
-
let(:expected_message) { described_class.const_get('INOTIFY_LIMIT_MESSAGE') }
|
25
24
|
|
26
25
|
before do
|
27
|
-
allow_any_instance_of(INotify::Notifier).to receive(:watch).
|
28
|
-
|
26
|
+
allow_any_instance_of(INotify::Notifier).to receive(:watch).
|
27
|
+
and_raise(Errno::ENOSPC)
|
28
|
+
|
29
|
+
allow(listener).to receive(:directories) { ['foo/dir'] }
|
29
30
|
end
|
30
31
|
|
31
|
-
it
|
32
|
+
it 'should be show before calling abort' do
|
33
|
+
expected_message = described_class.const_get('INOTIFY_LIMIT_MESSAGE')
|
32
34
|
expect(STDERR).to receive(:puts).with(expected_message)
|
33
35
|
|
34
36
|
# Expect RuntimeError here, for the sake of unit testing (actual
|
35
37
|
# handling depends on Celluloid supervisor setup, which is beyond the
|
36
38
|
# scope of adapter tests)
|
37
|
-
expect{adapter.start}.to raise_error RuntimeError, expected_message
|
39
|
+
expect { adapter.start }.to raise_error RuntimeError, expected_message
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
43
|
describe '_worker_callback' do
|
42
44
|
|
43
|
-
let(:expect_change)
|
44
|
-
|
45
|
-
allow_any_instance_of(Listen::Adapter::Base).
|
46
|
-
|
47
|
-
|
45
|
+
let(:expect_change) do
|
46
|
+
lambda do |change|
|
47
|
+
allow_any_instance_of(Listen::Adapter::Base).
|
48
|
+
to receive(:_notify_change).
|
49
|
+
with(
|
50
|
+
Pathname.new('path/foo.txt'),
|
51
|
+
type: 'File',
|
52
|
+
change: change,
|
53
|
+
cookie: 123)
|
54
|
+
end
|
55
|
+
end
|
48
56
|
|
49
|
-
let(:event_callback)
|
50
|
-
|
57
|
+
let(:event_callback) do
|
58
|
+
lambda do |flags|
|
51
59
|
callback = adapter.send(:_worker_callback)
|
52
|
-
callback.call double(:event,
|
53
|
-
|
54
|
-
|
60
|
+
callback.call double(:event,
|
61
|
+
name: 'foo.txt',
|
62
|
+
flags: flags,
|
63
|
+
absolute_name: 'path/foo.txt',
|
64
|
+
cookie: 123)
|
65
|
+
end
|
66
|
+
end
|
55
67
|
|
56
68
|
# use case: close_write is the only way to detect changes
|
57
69
|
# on ecryptfs
|
58
70
|
it 'recognizes close_write as modify' do
|
59
|
-
expect_change.(:modified)
|
60
|
-
event_callback.([:close_write])
|
71
|
+
expect_change.call(:modified)
|
72
|
+
event_callback.call([:close_write])
|
61
73
|
end
|
62
74
|
|
63
75
|
it 'recognizes moved_to as moved_to' do
|
64
|
-
expect_change.(:moved_to)
|
65
|
-
event_callback.([:moved_to])
|
76
|
+
expect_change.call(:moved_to)
|
77
|
+
event_callback.call([:moved_to])
|
66
78
|
end
|
67
79
|
|
68
80
|
it 'recognizes moved_from as moved_from' do
|
69
|
-
expect_change.(:moved_from)
|
70
|
-
event_callback.([:moved_from])
|
81
|
+
expect_change.call(:moved_from)
|
82
|
+
event_callback.call([:moved_from])
|
71
83
|
end
|
72
84
|
end
|
73
85
|
|
@@ -90,4 +102,7 @@ describe Listen::Adapter::Linux do
|
|
90
102
|
expect(described_class).to_not be_usable
|
91
103
|
end
|
92
104
|
end
|
105
|
+
|
106
|
+
specify { expect(described_class).to be_local_fs }
|
107
|
+
|
93
108
|
end
|
@@ -2,44 +2,59 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Listen::Adapter::Polling do
|
4
4
|
let(:registry) { double(Celluloid::Registry) }
|
5
|
-
let(:listener)
|
5
|
+
let(:listener) do
|
6
|
+
double(Listen::Listener,
|
7
|
+
registry: registry,
|
8
|
+
options: {},
|
9
|
+
listen?: true)
|
10
|
+
end
|
11
|
+
|
6
12
|
let(:adapter) { described_class.new(listener) }
|
7
13
|
let(:change_pool) { double(Listen::Change, terminate: true) }
|
8
14
|
let(:change_pool_async) { double('ChangePoolAsync') }
|
9
|
-
|
15
|
+
|
16
|
+
before do
|
10
17
|
change_pool.stub(:async) { change_pool_async }
|
11
18
|
registry.stub(:[]).with(:change_pool) { change_pool }
|
12
|
-
|
19
|
+
end
|
13
20
|
|
14
|
-
describe
|
15
|
-
it
|
21
|
+
describe '.usable?' do
|
22
|
+
it 'returns always true' do
|
16
23
|
expect(described_class).to be_usable
|
17
24
|
end
|
18
25
|
end
|
19
26
|
|
20
|
-
describe
|
27
|
+
describe '#start' do
|
21
28
|
let(:directories) { ['directory_path'] }
|
22
|
-
before
|
29
|
+
before do
|
23
30
|
listener.stub(:options) { {} }
|
24
31
|
listener.stub(:directories) { directories }
|
25
|
-
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'notifies change on every listener directories path' do
|
35
|
+
expect(change_pool_async).to receive(:change).with(
|
36
|
+
'directory_path',
|
37
|
+
type: 'Dir',
|
38
|
+
recursive: true)
|
26
39
|
|
27
|
-
it "notifies change on every listener directories path" do
|
28
|
-
expect(change_pool_async).to receive(:change).with('directory_path', type: 'Dir', recursive: true)
|
29
40
|
t = Thread.new { adapter.start }
|
30
41
|
sleep 0.25
|
31
42
|
t.kill
|
32
43
|
end
|
33
44
|
end
|
34
45
|
|
35
|
-
describe
|
36
|
-
it
|
37
|
-
|
46
|
+
describe '#_latency' do
|
47
|
+
it 'returns default_latency with listener actor latency not present' do
|
48
|
+
expected_latency = Listen::Adapter::Polling::DEFAULT_POLLING_LATENCY
|
49
|
+
expect(adapter.send(:_latency)).to eq expected_latency
|
38
50
|
end
|
39
51
|
|
40
|
-
it
|
52
|
+
it 'returns latency from listener actor if present' do
|
41
53
|
listener.stub(:options) { { latency: 1234 } }
|
42
54
|
expect(adapter.send(:_latency)).to eq 1234
|
43
55
|
end
|
44
56
|
end
|
57
|
+
|
58
|
+
specify { expect(described_class).to be_local_fs }
|
59
|
+
|
45
60
|
end
|
@@ -7,8 +7,16 @@ describe Listen::Adapter::TCP do
|
|
7
7
|
|
8
8
|
subject { described_class.new(listener) }
|
9
9
|
let(:registry) { double(Celluloid::Registry) }
|
10
|
-
|
11
|
-
let(:
|
10
|
+
|
11
|
+
let(:listener) do
|
12
|
+
double(Listen::TCP::Listener,
|
13
|
+
registry: registry,
|
14
|
+
options: {},
|
15
|
+
host: host,
|
16
|
+
port: port)
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:socket) { double(described_class::TCPSocket, close: true, recv: nil) }
|
12
20
|
|
13
21
|
before do
|
14
22
|
described_class::TCPSocket.stub(:new).and_return socket
|
@@ -26,7 +34,10 @@ describe Listen::Adapter::TCP do
|
|
26
34
|
|
27
35
|
describe '#start' do
|
28
36
|
it 'initializes and exposes a socket with listener host and port' do
|
29
|
-
expect(described_class::TCPSocket).
|
37
|
+
expect(described_class::TCPSocket).
|
38
|
+
to receive(:new).
|
39
|
+
with listener.host, listener.port
|
40
|
+
|
30
41
|
subject.start
|
31
42
|
expect(subject.socket).to be socket
|
32
43
|
end
|
@@ -99,12 +110,19 @@ describe Listen::Adapter::TCP do
|
|
99
110
|
'removed' => []
|
100
111
|
)
|
101
112
|
|
102
|
-
expect(subject.wrapped_object).
|
103
|
-
|
104
|
-
|
113
|
+
expect(subject.wrapped_object).
|
114
|
+
to receive(:_notify_change).with '/foo', change: :modified
|
115
|
+
|
116
|
+
expect(subject.wrapped_object).
|
117
|
+
to receive(:_notify_change).with '/bar', change: :modified
|
118
|
+
|
119
|
+
expect(subject.wrapped_object).
|
120
|
+
to receive(:_notify_change).with '/baz', change: :added
|
105
121
|
|
106
122
|
subject.handle_message message
|
107
123
|
end
|
108
124
|
end
|
109
125
|
|
126
|
+
specify { expect(described_class).to_not be_local_fs }
|
127
|
+
|
110
128
|
end
|