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.
@@ -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
@@ -0,0 +1,4 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe FSEvents do
4
+ end
@@ -0,0 +1 @@
1
+ --colour
@@ -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'
@@ -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