fsevents 0.0.1
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.
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +24 -0
- data/README.txt +95 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +73 -0
- data/config/requirements.rb +15 -0
- data/lib/fsevents.rb +10 -0
- data/lib/fsevents/event.rb +19 -0
- data/lib/fsevents/stream.rb +100 -0
- data/lib/fsevents/version.rb +9 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/setup.rb +1585 -0
- data/spec/event_spec.rb +105 -0
- data/spec/fsevents_spec.rb +4 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/stream_spec.rb +565 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +9 -0
- metadata +81 -0
data/spec/event_spec.rb
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
|
+
|
|
3
|
+
describe FSEvents::Event do
|
|
4
|
+
before :each do
|
|
5
|
+
@id = stub('id')
|
|
6
|
+
@path = '.'
|
|
7
|
+
@stream = stub('stream')
|
|
8
|
+
|
|
9
|
+
@event = FSEvents::Event.new(@id, @path, @stream)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe 'when initialized' do
|
|
13
|
+
it 'should accept an id, path, and stream' do
|
|
14
|
+
lambda { FSEvents::Event.new(@id, @path, @stream) }.should_not raise_error(ArgumentError)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should require a stream' do
|
|
18
|
+
lambda { FSEvents::Event.new(@id, @path) }.should raise_error(ArgumentError)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'should require a path' do
|
|
22
|
+
lambda { FSEvents::Event.new(@id) }.should raise_error(ArgumentError)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should require an id' do
|
|
26
|
+
lambda { FSEvents::Event.new }.should raise_error(ArgumentError)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'should store the id' do
|
|
30
|
+
FSEvents::Event.new(@id, @path, @stream).id.should == @id
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'should store the path' do
|
|
34
|
+
FSEvents::Event.new(@id, @path, @stream).path.should == @path
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should store the stream' do
|
|
38
|
+
FSEvents::Event.new(@id, @path, @stream).stream.should == @stream
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'should list files' do
|
|
43
|
+
@event.should respond_to(:files)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe 'listing files' do
|
|
47
|
+
it 'should get files from the path' do
|
|
48
|
+
@event.files.sort.should == Dir["#{@path}/*"].sort
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'should list modified files' do
|
|
53
|
+
@event.should respond_to(:modified_files)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe 'listing modified files' do
|
|
57
|
+
before :each do
|
|
58
|
+
@now = Time.now
|
|
59
|
+
@stream.stubs(:last_event).returns(@now)
|
|
60
|
+
@files = Array.new(5) do |i|
|
|
61
|
+
file = stub("file #{i+1}")
|
|
62
|
+
File.stubs(:mtime).with(file).returns(@now + i - 2)
|
|
63
|
+
file
|
|
64
|
+
end
|
|
65
|
+
@event.stubs(:files).returns(@files)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'should get the file list' do
|
|
69
|
+
@event.expects(:files).returns(@files)
|
|
70
|
+
@event.modified_files
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'should get the last event time from the stream' do
|
|
74
|
+
@stream.expects(:last_event).returns(@now)
|
|
75
|
+
@event.modified_files
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'should return files modified after the last event time' do
|
|
79
|
+
expected_files = @files.values_at(3, 4)
|
|
80
|
+
modified_files = @event.modified_files
|
|
81
|
+
|
|
82
|
+
expected_files.each do |file|
|
|
83
|
+
modified_files.should include(file)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'should return files modified at the last event time' do
|
|
88
|
+
expected_files = @files.values_at(2)
|
|
89
|
+
modified_files = @event.modified_files
|
|
90
|
+
|
|
91
|
+
expected_files.each do |file|
|
|
92
|
+
modified_files.should include(file)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'should not return files not modified after the last event time' do
|
|
97
|
+
unexpected_files = @files.values_at(0, 1)
|
|
98
|
+
modified_files = @event.modified_files
|
|
99
|
+
|
|
100
|
+
unexpected_files.each do |file|
|
|
101
|
+
modified_files.should_not include(file)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
data/spec/spec.opts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'spec'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
require 'rubygems'
|
|
5
|
+
gem 'rspec'
|
|
6
|
+
require 'spec'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# this is my favorite way to require ever
|
|
10
|
+
begin
|
|
11
|
+
require 'mocha'
|
|
12
|
+
rescue LoadError
|
|
13
|
+
require 'rubygems'
|
|
14
|
+
gem 'mocha'
|
|
15
|
+
require 'mocha'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Spec::Runner.configure do |config|
|
|
19
|
+
config.mock_with :mocha
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
|
23
|
+
require 'fsevents'
|
data/spec/stream_spec.rb
ADDED
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
|
+
|
|
3
|
+
describe FSEvents::Stream do
|
|
4
|
+
before :each do
|
|
5
|
+
@path = '/tmp'
|
|
6
|
+
@stream = FSEvents::Stream.new(@path) {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe 'when initialized' do
|
|
10
|
+
it 'should accept a path and callback block' do
|
|
11
|
+
lambda { FSEvents::Stream.new(@path) {} }.should_not raise_error(ArgumentError)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should not require a path' do
|
|
15
|
+
lambda { FSEvents::Stream.new() {} }.should_not raise_error(ArgumentError)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should require a callback block' do
|
|
19
|
+
lambda { FSEvents::Stream.new(@path) }.should raise_error(ArgumentError)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'should accept a hash of options' do
|
|
23
|
+
lambda { FSEvents::Stream.new(@path, :flags => 27 ) {} }.should_not raise_error(ArgumentError)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should accept an array of paths' do
|
|
27
|
+
lambda { FSEvents::Stream.new([@path, '/other/path']) {} }.should_not raise_error
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'should accept an array of paths with options' do
|
|
31
|
+
lambda { FSEvents::Stream.new([@path, '/other/path'], :flags => 27) {} }.should_not raise_error
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should accept multiple paths' do
|
|
35
|
+
lambda { FSEvents::Stream.new(@path, '/other/path') {} }.should_not raise_error
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'should accept multiple paths with options' do
|
|
39
|
+
lambda { FSEvents::Stream.new(@path, '/other/path', :flags => 27) {} }.should_not raise_error
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'should store the callback block' do
|
|
43
|
+
callback = lambda {}
|
|
44
|
+
FSEvents::Stream.new(@path, &callback).callback.should == callback
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe 'handling options' do
|
|
48
|
+
before :each do
|
|
49
|
+
@options = {}
|
|
50
|
+
[:allocator, :context, :since, :latency, :flags].each do |opt|
|
|
51
|
+
@options[opt] = stub(opt.to_s)
|
|
52
|
+
end
|
|
53
|
+
@other_path = '/other/path'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'should store the allocator' do
|
|
57
|
+
FSEvents::Stream.new(@path, @options) {}.allocator.should == @options[:allocator]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'should default the allocator to KCFAllocatorDefault' do
|
|
61
|
+
@options.delete(:allocator)
|
|
62
|
+
FSEvents::Stream.new(@path, @options) {}.allocator.should == OSX::KCFAllocatorDefault
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'should store the context' do
|
|
66
|
+
FSEvents::Stream.new(@path, @options) {}.context.should == @options[:context]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'should default the context to nil' do
|
|
70
|
+
@options.delete(:context)
|
|
71
|
+
FSEvents::Stream.new(@path, @options) {}.context.should == nil
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'should store the path as an array' do
|
|
75
|
+
FSEvents::Stream.new(@path, @options) {}.paths.should == [@path]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'should store an array of paths as-is' do
|
|
79
|
+
FSEvents::Stream.new([@path, @other_path], @options) {}.paths.should == [@path, @other_path]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it 'should store multiple paths as an array' do
|
|
83
|
+
FSEvents::Stream.new(@path, @other_path, @options) {}.paths.should == [@path, @other_path]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'should default the path to the present working directory' do
|
|
87
|
+
FSEvents::Stream.new(@options) {}.paths.should == [Dir.pwd]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "should store 'since' (event ID)" do
|
|
91
|
+
FSEvents::Stream.new(@path, @options) {}.since.should == @options[:since]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "should default 'since' to KFSEventStreamEventIdSinceNow" do
|
|
95
|
+
@options.delete(:since)
|
|
96
|
+
FSEvents::Stream.new(@path, @options) {}.since.should == OSX::KFSEventStreamEventIdSinceNow
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'should store the latency' do
|
|
100
|
+
FSEvents::Stream.new(@path, @options) {}.latency.should == @options[:latency]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'should default the latency to 1.0' do
|
|
104
|
+
@options.delete(:latency)
|
|
105
|
+
FSEvents::Stream.new(@path, @options) {}.latency.should == 1.0
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'should store the flags' do
|
|
109
|
+
FSEvents::Stream.new(@path, @options) {}.flags.should == @options[:flags]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'should default the flags to 0' do
|
|
113
|
+
@options.delete(:flags)
|
|
114
|
+
FSEvents::Stream.new(@path, @options) {}.flags.should == 0
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'should create a stream' do
|
|
120
|
+
@stream.should respond_to(:create)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
describe 'when creating the stream' do
|
|
124
|
+
before :each do
|
|
125
|
+
@args = {}
|
|
126
|
+
[:allocator, :context, :paths, :since, :latency, :flags].each do |arg|
|
|
127
|
+
val = stub(arg.to_s)
|
|
128
|
+
|
|
129
|
+
@stream.stubs(arg).returns(val)
|
|
130
|
+
@args[arg] = val
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
@arg_placeholders = Array.new(7) { anything }
|
|
134
|
+
|
|
135
|
+
@stream_val = stub('stream')
|
|
136
|
+
OSX.stubs(:FSEventStreamCreate).returns(@stream_val)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'should create an FSEvent stream' do
|
|
140
|
+
OSX.expects(:FSEventStreamCreate).returns(@stream_val)
|
|
141
|
+
@stream.create
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'should pass the allocator' do
|
|
145
|
+
args = @arg_placeholders
|
|
146
|
+
args[0] = @args[:allocator]
|
|
147
|
+
OSX.expects(:FSEventStreamCreate).with(*args).returns(@stream_val)
|
|
148
|
+
@stream.create
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it 'should pass the stream callback' do
|
|
152
|
+
# stream_callback returns a different proc every time it's called
|
|
153
|
+
@stream.stubs(:stream_callback).returns(stub('stream callback'))
|
|
154
|
+
args = @arg_placeholders
|
|
155
|
+
args[1] = @stream.stream_callback
|
|
156
|
+
OSX.expects(:FSEventStreamCreate).with(*args).returns(@stream_val)
|
|
157
|
+
@stream.create
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it 'should pass the context' do
|
|
161
|
+
args = @arg_placeholders
|
|
162
|
+
args[2] = @args[:context]
|
|
163
|
+
OSX.expects(:FSEventStreamCreate).with(*args).returns(@stream_val)
|
|
164
|
+
@stream.create
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it 'should pass the paths' do
|
|
168
|
+
args = @arg_placeholders
|
|
169
|
+
args[3] = @args[:paths]
|
|
170
|
+
OSX.expects(:FSEventStreamCreate).with(*args).returns(@stream_val)
|
|
171
|
+
@stream.create
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "should pass 'since' (event ID)" do
|
|
175
|
+
args = @arg_placeholders
|
|
176
|
+
args[4] = @args[:since]
|
|
177
|
+
OSX.expects(:FSEventStreamCreate).with(*args).returns(@stream_val)
|
|
178
|
+
@stream.create
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it 'should pass the latency' do
|
|
182
|
+
args = @arg_placeholders
|
|
183
|
+
args[5] = @args[:latency]
|
|
184
|
+
OSX.expects(:FSEventStreamCreate).with(*args).returns(@stream_val)
|
|
185
|
+
@stream.create
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it 'should pass the flags' do
|
|
189
|
+
args = @arg_placeholders
|
|
190
|
+
args[6] = @args[:flags]
|
|
191
|
+
OSX.expects(:FSEventStreamCreate).with(*args).returns(@stream_val)
|
|
192
|
+
@stream.create
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it 'should store the stream' do
|
|
196
|
+
@stream.create
|
|
197
|
+
@stream.stream.should == @stream_val
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it 'should raise a StreamError exception if the stream could not be created' do
|
|
201
|
+
OSX.stubs(:FSEventStreamCreate).returns(nil)
|
|
202
|
+
lambda { @stream.create }.should raise_error(FSEvents::Stream::StreamError)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it 'should not raise a StreamError exception if the stream could be created' do
|
|
206
|
+
lambda { @stream.create }.should_not raise_error(FSEvents::Stream::StreamError)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
it 'should have a stream callback' do
|
|
211
|
+
@stream.should respond_to(:stream_callback)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
describe 'stream callback' do
|
|
215
|
+
it 'should return a proc' do
|
|
216
|
+
@stream.stream_callback.should be_kind_of(Proc)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
describe 'proc' do
|
|
220
|
+
before :each do
|
|
221
|
+
@callback_arg_order = [:stream, :context, :event_count, :paths, :event_flags, :event_IDs]
|
|
222
|
+
@args_hash = {}
|
|
223
|
+
[:stream, :context].each do |arg|
|
|
224
|
+
@args_hash[arg] = stub(arg.to_s)
|
|
225
|
+
end
|
|
226
|
+
@args_hash[:event_count] = 0
|
|
227
|
+
[:paths, :event_flags, :event_IDs].each do |arg|
|
|
228
|
+
@args_hash[arg] = []
|
|
229
|
+
end
|
|
230
|
+
@args_hash[:paths].stubs(:regard_as)
|
|
231
|
+
|
|
232
|
+
@args = @args_hash.values_at(*@callback_arg_order)
|
|
233
|
+
|
|
234
|
+
@callback = stub('callback', :call => nil)
|
|
235
|
+
@stream.stubs(:callback).returns(@callback)
|
|
236
|
+
|
|
237
|
+
@proc = @stream.stream_callback
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it 'should accept stream, context, event count, paths, event flags, and event IDs' do
|
|
241
|
+
lambda { @proc.call(*@args) }.should_not raise_error(ArgumentError)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it "should regard the paths as '*'" do
|
|
245
|
+
@args_hash[:paths].expects(:regard_as).with('*')
|
|
246
|
+
@proc.call(*@args)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it 'should call the stored callback' do
|
|
250
|
+
@callback.expects(:call)
|
|
251
|
+
@proc.call(*@args)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it 'should collect the paths and IDs, create Event objects, and pass them to the stored callback' do
|
|
255
|
+
event_count = 3
|
|
256
|
+
@args_hash[:event_count] = event_count
|
|
257
|
+
events = []
|
|
258
|
+
event_count.times do |i|
|
|
259
|
+
path = "/some/path/to/dir/number/#{i+1}"
|
|
260
|
+
id = i + 1
|
|
261
|
+
@args_hash[:paths].push path
|
|
262
|
+
@args_hash[:event_IDs].push id
|
|
263
|
+
|
|
264
|
+
event = stub("event #{path}")
|
|
265
|
+
FSEvents::Event.stubs(:new).with(id, path, @stream).returns(event)
|
|
266
|
+
events.push event
|
|
267
|
+
end
|
|
268
|
+
@args = @args_hash.values_at(*@callback_arg_order)
|
|
269
|
+
@callback.expects(:call).with(events)
|
|
270
|
+
@proc.call(*@args)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it "should update the stream's last event" do
|
|
274
|
+
@stream.expects(:update_last_event)
|
|
275
|
+
@proc.call(*@args)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it 'should create' do
|
|
281
|
+
FSEvents::Stream.should respond_to(:create)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
describe 'when creating' do
|
|
285
|
+
before :each do
|
|
286
|
+
@other_path = '/other/path'
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# This is just here for organization and use of the before block.
|
|
290
|
+
# I'd like to ensure that the block is passed to new, but mocha expecation apparently doesn't support that.
|
|
291
|
+
# So instead I stub new for some testing and then have something that actually uses new and sees the callback
|
|
292
|
+
# is the expected block.
|
|
293
|
+
describe do
|
|
294
|
+
before :each do
|
|
295
|
+
@stream.stubs(:create)
|
|
296
|
+
FSEvents::Stream.stubs(:new).returns(@stream)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
it 'should accept arguments and a block' do
|
|
300
|
+
lambda { FSEvents::Stream.create(@path, @other_path, :flags => 27) {} }.should_not raise_error(ArgumentError)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it 'should initialize a new stream object' do
|
|
304
|
+
FSEvents::Stream.expects(:new).returns(@stream)
|
|
305
|
+
FSEvents::Stream.create(@path, @other_path, :flags => 27) {}
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it 'should pass the arguments to the initialization' do
|
|
309
|
+
FSEvents::Stream.expects(:new).with(@path, @other_path, :flags => 27).returns(@stream)
|
|
310
|
+
FSEvents::Stream.create(@path, @other_path, :flags => 27) {}
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
it 'should make the resultant stream object create a stream' do
|
|
314
|
+
@stream.expects(:create)
|
|
315
|
+
FSEvents::Stream.create(@path, @other_path, :flags => 27) {}
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it 'should return the stream object' do
|
|
319
|
+
FSEvents::Stream.create.should == @stream
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
it 'should pass the callback block' do
|
|
324
|
+
callback = lambda {}
|
|
325
|
+
FSEvents::Stream.create(@path, @other_path, :flags => 27, &callback).callback.should == callback
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it 'should schedule itself' do
|
|
330
|
+
@stream.should respond_to(:schedule)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
describe 'when scheduling' do
|
|
334
|
+
before :each do
|
|
335
|
+
OSX.stubs(:FSEventStreamScheduleWithRunLoop)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
it 'should schedule the stream' do
|
|
339
|
+
OSX.expects(:FSEventStreamScheduleWithRunLoop)
|
|
340
|
+
@stream.schedule
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
it 'should pass the stream' do
|
|
344
|
+
OSX.expects(:FSEventStreamScheduleWithRunLoop).with(@stream.stream, anything, anything)
|
|
345
|
+
@stream.schedule
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
it "should use the 'get current' run loop" do
|
|
349
|
+
OSX.expects(:CFRunLoopGetCurrent)
|
|
350
|
+
@stream.schedule
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
it "should pass the 'get current' run loop" do
|
|
354
|
+
# CFRunLoopGetCurrent returns a different value every time it's called, so it's like testing Time.now
|
|
355
|
+
get_current_run_loop = OSX.CFRunLoopGetCurrent
|
|
356
|
+
OSX.stubs(:CFRunLoopGetCurrent).returns(get_current_run_loop)
|
|
357
|
+
|
|
358
|
+
OSX.expects(:FSEventStreamScheduleWithRunLoop).with(anything, get_current_run_loop, anything)
|
|
359
|
+
@stream.schedule
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
it 'should use the default mode' do
|
|
363
|
+
OSX.expects(:FSEventStreamScheduleWithRunLoop).with(anything, anything, OSX::KCFRunLoopDefaultMode)
|
|
364
|
+
@stream.schedule
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
it 'should start itself' do
|
|
369
|
+
@stream.should respond_to(:start)
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
describe 'when starting' do
|
|
373
|
+
before :each do
|
|
374
|
+
OSX.stubs(:FSEventStreamStart).returns(true)
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
it 'should start the stream' do
|
|
378
|
+
OSX.expects(:FSEventStreamStart).with(@stream.stream).returns(true)
|
|
379
|
+
@stream.start
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
it 'should raise a StreamError exception if the stream could not be started' do
|
|
383
|
+
OSX.stubs(:FSEventStreamStart).returns(nil)
|
|
384
|
+
lambda { @stream.start }.should raise_error(FSEvents::Stream::StreamError)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
it 'should not raise a StreamError exception if the stream could be started' do
|
|
388
|
+
lambda { @stream.start }.should_not raise_error(FSEvents::Stream::StreamError)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it 'should update its last event' do
|
|
392
|
+
@stream.expects(:update_last_event)
|
|
393
|
+
@stream.start
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
it 'should update its last event' do
|
|
398
|
+
@stream.should respond_to(:update_last_event)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
describe 'updating its last event' do
|
|
402
|
+
it 'should store the last event time' do
|
|
403
|
+
now = Time.now
|
|
404
|
+
Time.stubs(:now).returns(now)
|
|
405
|
+
@stream.update_last_event
|
|
406
|
+
@stream.last_event.should == now
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
it 'should start up' do
|
|
411
|
+
@stream.should respond_to(:startup)
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
describe 'when starting up' do
|
|
415
|
+
before :each do
|
|
416
|
+
@stream.stubs(:schedule)
|
|
417
|
+
@stream.stubs(:start)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
it 'should schedule' do
|
|
421
|
+
@stream.expects(:schedule)
|
|
422
|
+
@stream.startup
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
it 'should start' do
|
|
426
|
+
@stream.expects(:start)
|
|
427
|
+
@stream.startup
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
it 'should watch' do
|
|
432
|
+
FSEvents::Stream.should respond_to(:watch)
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
describe 'when watching' do
|
|
436
|
+
before :each do
|
|
437
|
+
@other_path = '/other/path'
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
# This is just here for organization and use of the before block.
|
|
441
|
+
# I'd like to ensure that the block is passed to create, but mocha expecation apparently doesn't support that.
|
|
442
|
+
# So instead I stub create for some testing and then have something that actually uses create and sees the callback
|
|
443
|
+
# is the expected block.
|
|
444
|
+
describe do
|
|
445
|
+
before :each do
|
|
446
|
+
@stream.stubs(:startup)
|
|
447
|
+
FSEvents::Stream.stubs(:create).returns(@stream)
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
it 'should accept arguments and a block' do
|
|
451
|
+
lambda { FSEvents::Stream.watch(@path, @other_path, :flags => 27) {} }.should_not raise_error(ArgumentError)
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
it 'should create a stream object' do
|
|
455
|
+
FSEvents::Stream.expects(:create).returns(@stream)
|
|
456
|
+
FSEvents::Stream.watch(@path, @other_path, :flags => 27) {}
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
it 'should pass the arguments to the creation' do
|
|
460
|
+
FSEvents::Stream.expects(:create).with(@path, @other_path, :flags => 27).returns(@stream)
|
|
461
|
+
FSEvents::Stream.watch(@path, @other_path, :flags => 27) {}
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it 'should start up the resultant stream object' do
|
|
465
|
+
@stream.expects(:startup)
|
|
466
|
+
FSEvents::Stream.watch(@path, @other_path, :flags => 27) {}
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
it 'should return the stream object' do
|
|
470
|
+
FSEvents::Stream.watch.should == @stream
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
it 'should pass the callback block' do
|
|
475
|
+
callback = lambda {}
|
|
476
|
+
FSEvents::Stream.watch(@path, @other_path, :flags => 27, &callback).callback.should == callback
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
it 'should stop itself' do
|
|
481
|
+
@stream.should respond_to(:stop)
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
describe 'when stopping' do
|
|
485
|
+
it 'should stop the stream' do
|
|
486
|
+
OSX.expects(:FSEventStreamStop).with(@stream.stream)
|
|
487
|
+
@stream.stop
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
it 'should invalidate itself' do
|
|
492
|
+
@stream.should respond_to(:invalidate)
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
describe 'when invalidating' do
|
|
496
|
+
it 'should invalidate the stream' do
|
|
497
|
+
OSX.expects(:FSEventStreamInvalidate).with(@stream.stream)
|
|
498
|
+
@stream.invalidate
|
|
499
|
+
end
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
it 'should release itself' do
|
|
503
|
+
@stream.should respond_to(:release)
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
describe 'when releasing' do
|
|
507
|
+
before :each do
|
|
508
|
+
OSX.stubs(:FSEventStreamRelease)
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
it 'should release the stream' do
|
|
512
|
+
OSX.expects(:FSEventStreamRelease).with(@stream.stream)
|
|
513
|
+
@stream.release
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
it 'should clear the stream' do
|
|
517
|
+
@stream.release
|
|
518
|
+
@stream.stream.should be_nil
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
it 'should shut down' do
|
|
523
|
+
@stream.should respond_to(:shutdown)
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
describe 'when shutting down' do
|
|
527
|
+
before :each do
|
|
528
|
+
@stream.stubs(:stop)
|
|
529
|
+
@stream.stubs(:invalidate)
|
|
530
|
+
@stream.stubs(:release)
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
it 'should stop' do
|
|
534
|
+
@stream.expects(:stop)
|
|
535
|
+
@stream.shutdown
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
it 'should invalidate' do
|
|
539
|
+
@stream.expects(:invalidate)
|
|
540
|
+
@stream.shutdown
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
it 'should release' do
|
|
544
|
+
@stream.expects(:release)
|
|
545
|
+
@stream.shutdown
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
it 'should run' do
|
|
550
|
+
@stream.should respond_to(:run)
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
describe 'running' do
|
|
554
|
+
it 'should enter the run loop' do
|
|
555
|
+
OSX.expects(:CFRunLoopRun)
|
|
556
|
+
@stream.run
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
describe FSEvents::Stream::StreamError do
|
|
562
|
+
it 'should be a type of StandardError' do
|
|
563
|
+
FSEvents::Stream::StreamError.should < StandardError
|
|
564
|
+
end
|
|
565
|
+
end
|