listen 2.8.4 → 2.8.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/README.md +2 -11
- data/lib/listen/adapter/base.rb +8 -4
- data/lib/listen/adapter/bsd.rb +8 -25
- data/lib/listen/adapter/tcp.rb +2 -1
- data/lib/listen/internals/logging.rb +12 -8
- data/lib/listen/listener.rb +1 -1
- data/lib/listen/version.rb +1 -1
- metadata +4 -121
- data/.gitignore +0 -28
- data/.hound.yml +0 -3
- data/.rspec +0 -2
- data/.rubocop.yml +0 -20
- data/.rubocop_todo.yml +0 -33
- data/.travis.yml +0 -15
- data/.yardopts +0 -11
- data/Gemfile +0 -48
- data/Guardfile +0 -16
- data/Rakefile +0 -151
- data/TROUBLESHOOTING.md +0 -139
- data/listen.gemspec +0 -33
- data/spec/acceptance/listen_spec.rb +0 -230
- data/spec/acceptance/tcp_spec.rb +0 -139
- data/spec/lib/listen/adapter/base_spec.rb +0 -31
- data/spec/lib/listen/adapter/bsd_spec.rb +0 -14
- data/spec/lib/listen/adapter/darwin_spec.rb +0 -145
- data/spec/lib/listen/adapter/linux_spec.rb +0 -93
- data/spec/lib/listen/adapter/polling_spec.rb +0 -48
- data/spec/lib/listen/adapter/tcp_spec.rb +0 -129
- data/spec/lib/listen/adapter/windows_spec.rb +0 -14
- data/spec/lib/listen/adapter_spec.rb +0 -75
- data/spec/lib/listen/change_spec.rb +0 -104
- data/spec/lib/listen/directory_spec.rb +0 -180
- data/spec/lib/listen/file_spec.rb +0 -252
- data/spec/lib/listen/listener_spec.rb +0 -482
- data/spec/lib/listen/record_spec.rb +0 -377
- data/spec/lib/listen/silencer_spec.rb +0 -100
- data/spec/lib/listen/tcp/broadcaster_spec.rb +0 -124
- data/spec/lib/listen/tcp/listener_spec.rb +0 -104
- data/spec/lib/listen/tcp/message_spec.rb +0 -138
- data/spec/lib/listen_spec.rb +0 -52
- data/spec/spec_helper.rb +0 -52
- data/spec/support/acceptance_helper.rb +0 -275
- data/spec/support/fixtures_helper.rb +0 -30
- data/spec/support/platform_helper.rb +0 -15
- data/vendor/hound/config/style_guides/ruby.yml +0 -259
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Listen::Adapter::Linux do
|
|
4
|
-
describe 'class' do
|
|
5
|
-
subject { described_class }
|
|
6
|
-
it { should be_local_fs }
|
|
7
|
-
|
|
8
|
-
if linux?
|
|
9
|
-
it { should be_usable }
|
|
10
|
-
else
|
|
11
|
-
it { should_not be_usable }
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
if linux?
|
|
16
|
-
let(:directories) { [] }
|
|
17
|
-
let(:mq) { instance_double(Listen::Listener) }
|
|
18
|
-
|
|
19
|
-
subject { described_class.new(mq: mq, directories: directories) }
|
|
20
|
-
|
|
21
|
-
# workaround: Celluloid ignores SystemExit exception messages
|
|
22
|
-
describe 'inotify limit message' do
|
|
23
|
-
let(:directories) { [Pathname.pwd] }
|
|
24
|
-
|
|
25
|
-
before do
|
|
26
|
-
require 'rb-inotify'
|
|
27
|
-
fake_worker = double(:fake_worker)
|
|
28
|
-
allow(fake_worker).to receive(:watch).and_raise(Errno::ENOSPC)
|
|
29
|
-
|
|
30
|
-
fake_notifier = double(:fake_notifier, new: fake_worker)
|
|
31
|
-
stub_const('INotify::Notifier', fake_notifier)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
it 'should be shown before calling abort' do
|
|
35
|
-
expected_message = described_class.const_get('INOTIFY_LIMIT_MESSAGE')
|
|
36
|
-
expect(STDERR).to receive(:puts).with(expected_message)
|
|
37
|
-
|
|
38
|
-
# Expect RuntimeError here, for the sake of unit testing (actual
|
|
39
|
-
# handling depends on Celluloid supervisor setup, which is beyond the
|
|
40
|
-
# scope of subject tests)
|
|
41
|
-
expect { subject.start }.to raise_error RuntimeError, expected_message
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
describe '_callback' do
|
|
46
|
-
let(:directories) { [Pathname.pwd] }
|
|
47
|
-
before { subject.configure }
|
|
48
|
-
let(:expect_change) do
|
|
49
|
-
lambda do |change|
|
|
50
|
-
allow(mq).to receive(:_queue_raw_change).
|
|
51
|
-
with(
|
|
52
|
-
:file,
|
|
53
|
-
Pathname.pwd,
|
|
54
|
-
'path/foo.txt',
|
|
55
|
-
change: change,
|
|
56
|
-
cookie: 123)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
let(:event_callback) do
|
|
61
|
-
lambda do |flags|
|
|
62
|
-
callbacks = subject.instance_variable_get(:'@callbacks')
|
|
63
|
-
callbacks.values.flatten.each do |callback|
|
|
64
|
-
callback.call double(
|
|
65
|
-
:inotify_event,
|
|
66
|
-
name: 'foo.txt',
|
|
67
|
-
watcher: double(:watcher, path: (Pathname.pwd + 'path').to_s),
|
|
68
|
-
flags: flags,
|
|
69
|
-
cookie: 123)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# TODO: get fsevent adapter working like INotify
|
|
75
|
-
unless /1|true/ =~ ENV['LISTEN_GEM_SIMULATE_FSEVENT']
|
|
76
|
-
it 'recognizes close_write as modify' do
|
|
77
|
-
expect_change.call(:modified)
|
|
78
|
-
event_callback.call([:close_write])
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
it 'recognizes moved_to as moved_to' do
|
|
82
|
-
expect_change.call(:moved_to)
|
|
83
|
-
event_callback.call([:moved_to])
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
it 'recognizes moved_from as moved_from' do
|
|
87
|
-
expect_change.call(:moved_from)
|
|
88
|
-
event_callback.call([:moved_from])
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
include Listen
|
|
4
|
-
|
|
5
|
-
describe Adapter::Polling do
|
|
6
|
-
describe 'class' do
|
|
7
|
-
subject { described_class }
|
|
8
|
-
it { should be_local_fs }
|
|
9
|
-
it { should be_usable }
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
subject do
|
|
13
|
-
described_class.new(options.merge(mq: mq, directories: directories))
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
let(:options) { {} }
|
|
17
|
-
let(:mq) { instance_double(Listener, options: options) }
|
|
18
|
-
|
|
19
|
-
describe '#start' do
|
|
20
|
-
let(:directories) { [Pathname.pwd] }
|
|
21
|
-
|
|
22
|
-
it 'notifies change on every listener directories path' do
|
|
23
|
-
expect(mq).to receive(:_queue_raw_change).
|
|
24
|
-
with(:dir, Pathname.pwd, '.', recursive: true)
|
|
25
|
-
|
|
26
|
-
t = Thread.new { subject.start }
|
|
27
|
-
sleep 0.25
|
|
28
|
-
t.kill
|
|
29
|
-
t.join
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
describe '#_latency' do
|
|
34
|
-
subject do
|
|
35
|
-
adapter = described_class.new(options.merge(mq: mq, directories: []))
|
|
36
|
-
adapter.options.latency
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
context 'with no overriding option' do
|
|
40
|
-
it { should eq 1.0 }
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
context 'with custom latency overriding' do
|
|
44
|
-
let(:options) { { latency: 1234 } }
|
|
45
|
-
it { should eq 1234 }
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Listen::Adapter::TCP do
|
|
4
|
-
|
|
5
|
-
let(:host) { '10.0.0.2' }
|
|
6
|
-
let(:port) { 4000 }
|
|
7
|
-
|
|
8
|
-
let(:options) { { host: host, port: port } }
|
|
9
|
-
|
|
10
|
-
subject { described_class.new(options.merge(mq: listener)) }
|
|
11
|
-
let(:registry) { instance_double(Celluloid::Registry) }
|
|
12
|
-
|
|
13
|
-
let(:listener) do
|
|
14
|
-
instance_double(
|
|
15
|
-
Listen::Listener,
|
|
16
|
-
registry: registry,
|
|
17
|
-
options: {},
|
|
18
|
-
host: host,
|
|
19
|
-
port: port)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
let(:socket) do
|
|
23
|
-
instance_double(described_class::TCPSocket, close: true, recv: nil)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
before do
|
|
27
|
-
allow(described_class::TCPSocket).to receive(:new).and_return socket
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
after do
|
|
31
|
-
subject.terminate
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
describe '.usable?' do
|
|
35
|
-
it 'always returns true' do
|
|
36
|
-
expect(described_class).to be_usable
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
describe '#start' do
|
|
41
|
-
it 'initializes and exposes a socket with listener host and port' do
|
|
42
|
-
expect(described_class::TCPSocket).
|
|
43
|
-
to receive(:new).
|
|
44
|
-
with listener.host, listener.port
|
|
45
|
-
|
|
46
|
-
subject.start
|
|
47
|
-
expect(subject.socket).to be socket
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it 'initializes and exposes a string buffer' do
|
|
51
|
-
subject.start
|
|
52
|
-
expect(subject.buffer).to eq ''
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
it 'invokes run loop' do
|
|
56
|
-
expect(subject.wrapped_object).to receive(:run)
|
|
57
|
-
subject.start
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
describe '#finalize' do
|
|
62
|
-
it 'clears buffer' do
|
|
63
|
-
subject.start
|
|
64
|
-
subject.finalize
|
|
65
|
-
expect(subject.buffer).to be_nil
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it 'closes socket' do
|
|
69
|
-
subject.start
|
|
70
|
-
expect(subject.socket).to receive(:close)
|
|
71
|
-
subject.finalize
|
|
72
|
-
expect(subject.socket).to be_nil
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
describe '#run' do
|
|
77
|
-
it 'handles data from socket' do
|
|
78
|
-
allow(socket).to receive(:recv).and_return 'foo', 'bar', nil
|
|
79
|
-
|
|
80
|
-
expect_any_instance_of(described_class).
|
|
81
|
-
to receive(:handle_data).with('foo')
|
|
82
|
-
|
|
83
|
-
expect_any_instance_of(described_class).
|
|
84
|
-
to receive(:handle_data).with('bar')
|
|
85
|
-
|
|
86
|
-
subject.start
|
|
87
|
-
|
|
88
|
-
# quick workaround because run is called asynchronously
|
|
89
|
-
sleep 0.5
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
describe '#handle_data' do
|
|
94
|
-
it 'buffers data' do
|
|
95
|
-
subject.start
|
|
96
|
-
subject.handle_data 'foo'
|
|
97
|
-
subject.handle_data 'bar'
|
|
98
|
-
expect(subject.buffer).to eq 'foobar'
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it 'handles messages accordingly' do
|
|
102
|
-
message = Listen::TCP::Message.new
|
|
103
|
-
|
|
104
|
-
allow(Listen::TCP::Message).to receive(:from_buffer).
|
|
105
|
-
and_return message, nil
|
|
106
|
-
|
|
107
|
-
expect(Listen::TCP::Message).to receive(:from_buffer).with 'foo'
|
|
108
|
-
expect(subject.wrapped_object).to receive(:handle_message).with message
|
|
109
|
-
|
|
110
|
-
subject.start
|
|
111
|
-
subject.handle_data 'foo'
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
describe '#handle_message' do
|
|
116
|
-
let(:dir) { Pathname.pwd }
|
|
117
|
-
it 'notifies listener of path changes' do
|
|
118
|
-
message = Listen::TCP::Message.new('file', 'modified', dir, 'foo', {})
|
|
119
|
-
|
|
120
|
-
expect(subject.wrapped_object).
|
|
121
|
-
to receive(:_queue_change).with :file, dir, 'foo', change: :modified
|
|
122
|
-
|
|
123
|
-
subject.handle_message message
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
specify { expect(described_class).to_not be_local_fs }
|
|
128
|
-
|
|
129
|
-
end
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Listen::Adapter do
|
|
4
|
-
|
|
5
|
-
let(:listener) { instance_double(Listen::Listener, options: {}) }
|
|
6
|
-
before do
|
|
7
|
-
allow(Listen::Adapter::BSD).to receive(:usable?) { false }
|
|
8
|
-
allow(Listen::Adapter::Darwin).to receive(:usable?) { false }
|
|
9
|
-
allow(Listen::Adapter::Linux).to receive(:usable?) { false }
|
|
10
|
-
allow(Listen::Adapter::Windows).to receive(:usable?) { false }
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
describe '.select' do
|
|
14
|
-
it 'returns TCP adapter when requested' do
|
|
15
|
-
klass = Listen::Adapter.select(force_tcp: true)
|
|
16
|
-
expect(klass).to eq Listen::Adapter::TCP
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it 'returns Polling adapter if forced' do
|
|
20
|
-
klass = Listen::Adapter.select(force_polling: true)
|
|
21
|
-
expect(klass).to eq Listen::Adapter::Polling
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'returns BSD adapter when usable' do
|
|
25
|
-
allow(Listen::Adapter::BSD).to receive(:usable?) { true }
|
|
26
|
-
klass = Listen::Adapter.select
|
|
27
|
-
expect(klass).to eq Listen::Adapter::BSD
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it 'returns Darwin adapter when usable' do
|
|
31
|
-
allow(Listen::Adapter::Darwin).to receive(:usable?) { true }
|
|
32
|
-
klass = Listen::Adapter.select
|
|
33
|
-
expect(klass).to eq Listen::Adapter::Darwin
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it 'returns Linux adapter when usable' do
|
|
37
|
-
allow(Listen::Adapter::Linux).to receive(:usable?) { true }
|
|
38
|
-
klass = Listen::Adapter.select
|
|
39
|
-
expect(klass).to eq Listen::Adapter::Linux
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it 'returns Windows adapter when usable' do
|
|
43
|
-
allow(Listen::Adapter::Windows).to receive(:usable?) { true }
|
|
44
|
-
klass = Listen::Adapter.select
|
|
45
|
-
expect(klass).to eq Listen::Adapter::Windows
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
context 'no usable adapters' do
|
|
49
|
-
before { allow(Kernel).to receive(:warn) }
|
|
50
|
-
|
|
51
|
-
it 'returns Polling adapter' do
|
|
52
|
-
klass = Listen::Adapter.select(force_polling: true)
|
|
53
|
-
expect(klass).to eq Listen::Adapter::Polling
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it 'warns polling fallback with default message' do
|
|
57
|
-
msg = described_class::POLLING_FALLBACK_MESSAGE
|
|
58
|
-
expect(Kernel).to receive(:warn).with("[Listen warning]:\n #{msg}")
|
|
59
|
-
Listen::Adapter.select
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "doesn't warn if polling_fallback_message is false" do
|
|
63
|
-
expect(Kernel).to_not receive(:warn)
|
|
64
|
-
Listen::Adapter.select(polling_fallback_message: false)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it 'warns polling fallback with custom message if set' do
|
|
68
|
-
expected_msg = "[Listen warning]:\n custom fallback message"
|
|
69
|
-
expect(Kernel).to receive(:warn).with(expected_msg)
|
|
70
|
-
msg = 'custom fallback message'
|
|
71
|
-
Listen::Adapter.select(polling_fallback_message: msg)
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Listen::Change do
|
|
4
|
-
let(:subject) { Listen::Change.new(listener) }
|
|
5
|
-
let(:listener) { instance_double(Listen::Listener, options: {}) }
|
|
6
|
-
let(:record) { instance_double(Listen::Record) }
|
|
7
|
-
let(:full_file_path) { instance_double(Pathname, to_s: '/dir/file.rb') }
|
|
8
|
-
let(:full_dir_path) { instance_double(Pathname, to_s: '/dir') }
|
|
9
|
-
let(:dir) { instance_double(Pathname) }
|
|
10
|
-
|
|
11
|
-
before do
|
|
12
|
-
allow(listener).to receive(:sync).with(:record) { record }
|
|
13
|
-
allow(listener).to receive(:async).with(:change_pool) { subject }
|
|
14
|
-
allow(dir).to receive(:+).with('file.rb') { full_file_path }
|
|
15
|
-
allow(dir).to receive(:+).with('dir1') { full_dir_path }
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
describe '#change' do
|
|
19
|
-
let(:silencer) { instance_double(Listen::Silencer, silenced?: false) }
|
|
20
|
-
before { allow(listener).to receive(:silencer) { silencer } }
|
|
21
|
-
|
|
22
|
-
context 'with build options' do
|
|
23
|
-
it 'calls still_building! on record' do
|
|
24
|
-
allow(listener).to receive(:queue)
|
|
25
|
-
allow(record).to receive(:async) { async_record }
|
|
26
|
-
allow(Listen::File).to receive(:change)
|
|
27
|
-
subject.change(:file, dir, 'file.rb', build: true)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
context 'file' do
|
|
32
|
-
context 'with known change' do
|
|
33
|
-
it 'notifies change directly to listener' do
|
|
34
|
-
expect(listener).to receive(:queue).
|
|
35
|
-
with(:file, :modified, dir, 'file.rb', {})
|
|
36
|
-
|
|
37
|
-
subject.change(:file, dir, 'file.rb', change: :modified)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it "doesn't notify to listener if path is silenced" do
|
|
41
|
-
expect(silencer).to receive(:silenced?).and_return(true)
|
|
42
|
-
expect(listener).to_not receive(:queue)
|
|
43
|
-
subject.change(:file, dir, 'file.rb', change: :modified)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
context 'with unknown change' do
|
|
48
|
-
|
|
49
|
-
it 'calls Listen::File#change' do
|
|
50
|
-
expect(Listen::File).to receive(:change).with(record, dir, 'file.rb')
|
|
51
|
-
subject.change(:file, dir, 'file.rb')
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "doesn't call Listen::File#change if path is silenced" do
|
|
55
|
-
expect(silencer).to receive(:silenced?).
|
|
56
|
-
with(Pathname('file.rb'), :file).and_return(true)
|
|
57
|
-
|
|
58
|
-
expect(Listen::File).to_not receive(:change)
|
|
59
|
-
subject.change(:file, dir, 'file.rb')
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
context 'that returns a change' do
|
|
63
|
-
before { allow(Listen::File).to receive(:change) { :modified } }
|
|
64
|
-
|
|
65
|
-
context 'listener listen' do
|
|
66
|
-
it 'notifies change to listener' do
|
|
67
|
-
expect(listener).to receive(:queue).
|
|
68
|
-
with(:file, :modified, dir, 'file.rb')
|
|
69
|
-
|
|
70
|
-
subject.change(:file, dir, 'file.rb')
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
context 'silence option' do
|
|
74
|
-
it 'notifies change to listener' do
|
|
75
|
-
expect(listener).to_not receive(:queue)
|
|
76
|
-
subject.change(:file, dir, 'file.rb', silence: true)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
context 'that returns no change' do
|
|
83
|
-
before { allow(Listen::File).to receive(:change) { nil } }
|
|
84
|
-
|
|
85
|
-
it "doesn't notifies no change" do
|
|
86
|
-
expect(listener).to_not receive(:queue)
|
|
87
|
-
subject.change(:file, dir, 'file.rb')
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
context 'directory' do
|
|
94
|
-
let(:dir_options) { { recursive: true } }
|
|
95
|
-
|
|
96
|
-
it 'calls Listen::Directory#new' do
|
|
97
|
-
expect(Listen::Directory).to receive(:scan).
|
|
98
|
-
with(subject, record, dir, 'dir1', dir_options)
|
|
99
|
-
|
|
100
|
-
subject.change(:dir, dir, 'dir1', dir_options)
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|