listen 2.7.4 → 2.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +232 -0
  3. data/.travis.yml +6 -3
  4. data/Gemfile +9 -1
  5. data/Guardfile +6 -1
  6. data/README.md +17 -4
  7. data/lib/listen.rb +9 -4
  8. data/lib/listen/adapter.rb +5 -7
  9. data/lib/listen/adapter/base.rb +8 -5
  10. data/lib/listen/adapter/bsd.rb +58 -21
  11. data/lib/listen/adapter/darwin.rb +2 -4
  12. data/lib/listen/adapter/linux.rb +20 -10
  13. data/lib/listen/adapter/polling.rb +0 -2
  14. data/lib/listen/adapter/tcp.rb +6 -5
  15. data/lib/listen/adapter/windows.rb +8 -6
  16. data/lib/listen/change.rb +1 -2
  17. data/lib/listen/cli.rb +25 -22
  18. data/lib/listen/directory.rb +8 -6
  19. data/lib/listen/listener.rb +25 -19
  20. data/lib/listen/record.rb +4 -2
  21. data/lib/listen/silencer.rb +55 -25
  22. data/lib/listen/tcp.rb +9 -0
  23. data/lib/listen/tcp/broadcaster.rb +0 -2
  24. data/lib/listen/tcp/listener.rb +13 -8
  25. data/lib/listen/tcp/message.rb +0 -2
  26. data/lib/listen/version.rb +1 -1
  27. data/listen.gemspec +4 -3
  28. data/spec/acceptance/listen_spec.rb +190 -109
  29. data/spec/acceptance/tcp_spec.rb +28 -26
  30. data/spec/lib/listen/adapter/base_spec.rb +14 -12
  31. data/spec/lib/listen/adapter/bsd_spec.rb +5 -2
  32. data/spec/lib/listen/adapter/darwin_spec.rb +5 -2
  33. data/spec/lib/listen/adapter/linux_spec.rb +40 -25
  34. data/spec/lib/listen/adapter/polling_spec.rb +29 -14
  35. data/spec/lib/listen/adapter/tcp_spec.rb +24 -6
  36. data/spec/lib/listen/adapter/windows_spec.rb +5 -2
  37. data/spec/lib/listen/adapter_spec.rb +20 -17
  38. data/spec/lib/listen/change_spec.rb +36 -26
  39. data/spec/lib/listen/directory_spec.rb +128 -71
  40. data/spec/lib/listen/file_spec.rb +67 -34
  41. data/spec/lib/listen/listener_spec.rb +135 -105
  42. data/spec/lib/listen/record_spec.rb +32 -29
  43. data/spec/lib/listen/silencer_spec.rb +78 -56
  44. data/spec/lib/listen/tcp/broadcaster_spec.rb +3 -2
  45. data/spec/lib/listen/tcp/listener_spec.rb +17 -11
  46. data/spec/lib/listen/tcp/message_spec.rb +1 -1
  47. data/spec/lib/listen_spec.rb +18 -6
  48. data/spec/spec_helper.rb +5 -1
  49. data/spec/support/acceptance_helper.rb +3 -3
  50. data/spec/support/fixtures_helper.rb +10 -9
  51. metadata +17 -15
@@ -15,7 +15,9 @@ module Listen
15
15
  when 'File'
16
16
  _async_change(entry_path, options.merge(type: 'File'))
17
17
  when 'Dir'
18
- _async_change(entry_path, options.merge(type: 'Dir')) if _recursive_scan?(entry_path)
18
+ if _recursive_scan?(entry_path)
19
+ _async_change(entry_path, options.merge(type: 'Dir'))
20
+ end
19
21
  end
20
22
  end
21
23
  end
@@ -23,8 +25,8 @@ module Listen
23
25
  private
24
26
 
25
27
  def _update_record
26
- if ::Dir.exists?(path)
27
- _record.async.set_path(path, { type: 'Dir'})
28
+ if ::Dir.exist?(path)
29
+ _record.async.set_path(path, type: 'Dir')
28
30
  else
29
31
  _record.async.unset_path(path)
30
32
  end
@@ -35,9 +37,9 @@ module Listen
35
37
  end
36
38
 
37
39
  def _entries
38
- return {} unless ::Dir.exists?(path)
40
+ return {} unless ::Dir.exist?(path)
39
41
 
40
- entries = ::Dir.entries(path) - %w[. ..]
42
+ entries = ::Dir.entries(path) - %w(. ..)
41
43
  entries = entries.map { |entry| [entry, type: _entry_type(entry)] }
42
44
  Hash[*entries.flatten]
43
45
  end
@@ -65,7 +67,7 @@ module Listen
65
67
  end
66
68
 
67
69
  def _recursive_scan?(path)
68
- !::Dir.exists?(path) || options[:recursive]
70
+ !::Dir.exist?(path) || options[:recursive]
69
71
  end
70
72
 
71
73
  def _async_change(entry_path, options)
@@ -3,14 +3,13 @@ require 'listen/adapter'
3
3
  require 'listen/change'
4
4
  require 'listen/record'
5
5
  require 'listen/silencer'
6
+ require 'English'
6
7
 
7
8
  module Listen
8
9
  class Listener
9
10
  attr_accessor :options, :directories, :paused, :changes, :block, :stopping
10
11
  attr_accessor :registry, :supervisor
11
12
 
12
- RELATIVE_PATHS_WITH_MULTIPLE_DIRECTORIES_WARNING_MESSAGE = "The relative_paths option doesn't work when listening to multiple diretories."
13
-
14
13
  # Initializes the directories listener.
15
14
  #
16
15
  # @param [String] directory the directories to listen to
@@ -78,7 +77,10 @@ module Listen
78
77
  @paused == false && @stopping == false
79
78
  end
80
79
 
81
- # Adds ignore patterns to the existing one (See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer)
80
+ # Adds ignore patterns to the existing one
81
+ #
82
+ # @see DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in
83
+ # Listen::Silencer)
82
84
  #
83
85
  # @param [Regexp, Array<Regexp>] new ignoring patterns.
84
86
  #
@@ -87,7 +89,10 @@ module Listen
87
89
  registry[:silencer] = Silencer.new(self)
88
90
  end
89
91
 
90
- # Overwrites ignore patterns (See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer)
92
+ # Overwrites ignore patterns
93
+ #
94
+ # @see DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in
95
+ # Listen::Silencer)
91
96
  #
92
97
  # @param [Regexp, Array<Regexp>] new ignoring patterns.
93
98
  #
@@ -118,7 +123,12 @@ module Listen
118
123
 
119
124
  def _init_debug
120
125
  if options[:debug] || ENV['LISTEN_GEM_DEBUGGING'] =~ /true|1/i
121
- Celluloid.logger.level = Logger::INFO
126
+ if RbConfig::CONFIG['host_os'] =~ /bsd|dragonfly/
127
+ Celluloid.logger.level = Logger::INFO
128
+ else
129
+ # BSDs silently fail ;;(
130
+ Celluloid.logger.level = Logger::DEBUG
131
+ end
122
132
  else
123
133
  Celluloid.logger.level = Logger::FATAL
124
134
  end
@@ -161,21 +171,16 @@ module Listen
161
171
  end
162
172
 
163
173
  def _smoosh_changes(changes)
164
- if _local_fs?
174
+ if registry[:adapter].class.local_fs?
165
175
  cookies = changes.group_by { |x| x[:cookie] }
166
176
  _squash_changes(_reinterpret_related_changes(cookies))
167
177
  else
168
178
  smooshed = { modified: [], added: [], removed: [] }
169
- changes.each { |h| type = h.keys.first; smooshed[type] << h[type].to_s }
170
- smooshed.each { |_, v| v.uniq! }
171
- smooshed
179
+ changes.map(&:first).each { |type, path| smooshed[type] << path.to_s }
180
+ smooshed.tap { |s| s.each { |_, v| v.uniq! } }
172
181
  end
173
182
  end
174
183
 
175
- def _local_fs?
176
- !registry[:adapter].is_a?(Adapter::TCP)
177
- end
178
-
179
184
  def _squash_changes(changes)
180
185
  actions = changes.group_by(&:last).map do |path, action_list|
181
186
  [_logical_action_for(path, action_list.map(&:first)), path.to_s]
@@ -194,7 +199,7 @@ module Listen
194
199
  actions << :added if actions.delete(:moved_to)
195
200
  actions << :removed if actions.delete(:moved_from)
196
201
 
197
- modified = actions.find { |x| x == :modified }
202
+ modified = actions.detect { |x| x == :modified }
198
203
  _calculate_add_remove_difference(actions, path, modified)
199
204
  end
200
205
 
@@ -220,14 +225,15 @@ module Listen
220
225
  # editor rename() call (e.g. Kate and Sublime)
221
226
  def _reinterpret_related_changes(cookies)
222
227
  table = { moved_to: :added, moved_from: :removed }
223
- cookies.map do |cookie, changes|
228
+ cookies.map do |_, changes|
224
229
  file = _detect_possible_editor_save(changes)
225
230
  if file
226
231
  [[:modified, file]]
227
232
  else
228
- changes.map(&:first).reject do |type, path|
233
+ not_silenced = changes.map(&:first).reject do |_, path|
229
234
  _silenced?(path)
230
- end.map { |type, path| [table.fetch(type, type), path] }
235
+ end
236
+ not_silenced.map { |type, path| [table.fetch(type, type), path] }
231
237
  end
232
238
  end.flatten(1)
233
239
  end
@@ -235,9 +241,9 @@ module Listen
235
241
  def _detect_possible_editor_save(changes)
236
242
  return unless changes.size == 2
237
243
 
238
- from, to = changes.sort { |x,y| x.keys.first <=> y.keys.first }
244
+ from, to = changes.sort { |x, y| x.keys.first <=> y.keys.first }
239
245
  from, to = from[:moved_from], to[:moved_to]
240
- return unless from and to
246
+ return unless from && to
241
247
 
242
248
  # Expect an ignored moved_from and non-ignored moved_to
243
249
  # to qualify as an "editor modify"
data/lib/listen/record.rb CHANGED
@@ -10,7 +10,8 @@ module Listen
10
10
  end
11
11
 
12
12
  def set_path(path, data)
13
- @paths[::File.dirname(path)][::File.basename(path)] = file_data(path).merge(data)
13
+ new_data = file_data(path).merge(data)
14
+ @paths[::File.dirname(path)][::File.basename(path)] = new_data
14
15
  end
15
16
 
16
17
  def unset_path(path)
@@ -28,7 +29,8 @@ module Listen
28
29
  def build
29
30
  @paths = _init_paths
30
31
  listener.directories.each do |path|
31
- listener.registry[:change_pool].change(path, type: 'Dir', recursive: true, silence: true)
32
+ options = { type: 'Dir', recursive: true, silence: true }
33
+ listener.registry[:change_pool].change(path, options)
32
34
  end
33
35
  end
34
36
 
@@ -3,11 +3,33 @@ module Listen
3
3
  include Celluloid
4
4
 
5
5
  # The default list of directories that get ignored.
6
- DEFAULT_IGNORED_DIRECTORIES = %w[.bundle .git .hg .rbx .svn bundle log tmp vendor/ruby vendor/bundle]
6
+ DEFAULT_IGNORED_DIRECTORIES = %r{^(?:
7
+ \.git
8
+ | \.svn
9
+ | \.hg
10
+ | \.rbx
11
+ | \.bundle
12
+ | bundle
13
+ | vendor/bundle
14
+ | log
15
+ | tmp
16
+ |vendor/ruby
17
+ )(/|$)}x
7
18
 
8
19
  # The default list of files that get ignored.
9
- KATE_TEMP_FILES = /\..*[a-z]\d+\.new/
10
- DEFAULT_IGNORED_EXTENSIONS = %w(.DS_Store .tmp ~) + [KATE_TEMP_FILES]
20
+ DEFAULT_IGNORED_EXTENSIONS = %r{(?:
21
+ # Kate's tmp/swp files
22
+ \..*\d+\.new
23
+ | \.kate-swp
24
+
25
+ # Gedit tmp files
26
+ | \.goutputstream-.{6}
27
+
28
+ # other files
29
+ | \.DS_Store
30
+ | \.tmp
31
+ | ~
32
+ )$}x
11
33
 
12
34
  attr_accessor :listener, :only_patterns, :ignore_patterns
13
35
 
@@ -20,11 +42,18 @@ module Listen
20
42
  def silenced?(path, type = 'Unknown')
21
43
  silenced = false
22
44
 
45
+ relative_path = _relative_path(path)
46
+
23
47
  if only_patterns && type == 'File'
24
- silenced = !only_patterns.any? { |pattern| _relative_path(path) =~ pattern }
48
+ silenced = !only_patterns.any? { |pattern| relative_path =~ pattern }
25
49
  end
26
50
 
27
- silenced ||= ignore_patterns.any? { |pattern| _relative_path(path) =~ pattern }
51
+ silenced || ignore_patterns.any? { |pattern| relative_path =~ pattern }
52
+ end
53
+
54
+ def match(args)
55
+ path, type = args.first
56
+ silenced?(path, type)
28
57
  end
29
58
 
30
59
  private
@@ -36,33 +65,34 @@ module Listen
36
65
  end
37
66
 
38
67
  def _init_ignore_patterns
39
- @ignore_patterns = []
40
- @ignore_patterns << _default_ignore_patterns unless listener.options[:ignore!]
41
- @ignore_patterns << listener.options[:ignore] << listener.options[:ignore!]
42
- @ignore_patterns.compact!
43
- @ignore_patterns.flatten!
44
- end
68
+ options = listener.options
45
69
 
46
- def _default_ignore_patterns
47
- [_default_ignored_directories_patterns, _default_ignored_extensions_patterns]
48
- end
70
+ patterns = []
71
+ unless options[:ignore!]
72
+ patterns << DEFAULT_IGNORED_DIRECTORIES
73
+ patterns << DEFAULT_IGNORED_EXTENSIONS
74
+ end
49
75
 
50
- def _default_ignored_directories_patterns
51
- ignored_directories = DEFAULT_IGNORED_DIRECTORIES.map { |d| Regexp.escape(d) }
52
- %r{^(?:#{ignored_directories.join('|')})(/|$)}
53
- end
76
+ patterns << options[:ignore]
77
+ patterns << options[:ignore!]
54
78
 
55
- def _default_ignored_extensions_patterns
56
- ignored_extensions = DEFAULT_IGNORED_EXTENSIONS.map do
57
- |e| e.is_a?(Regexp) ? e : Regexp.escape(e)
58
- end
79
+ patterns.compact!
80
+ patterns.flatten!
59
81
 
60
- %r{(?:#{ignored_extensions.join('|')})$}
82
+ @ignore_patterns = patterns
61
83
  end
62
84
 
63
85
  def _relative_path(path)
64
- relative_paths = listener.directories.map { |dir| path.relative_path_from(dir).to_s }
65
- relative_paths.detect { |path| !path.start_with?('../') }
86
+ relative_paths = listener.directories.map do |dir|
87
+ begin
88
+ path.relative_path_from(dir).to_s
89
+ rescue ArgumentError
90
+ # Windows raises errors across drives, e.g. when 'C:/' and 'E:/dir'
91
+ # So, here's a Dirty hack to fool the detect() below..
92
+ '../'
93
+ end
94
+ end
95
+ relative_paths.detect { |rel_path| !rel_path.start_with?('../') }
66
96
  end
67
97
  end
68
98
  end
data/lib/listen/tcp.rb ADDED
@@ -0,0 +1,9 @@
1
+ begin
2
+ require 'celluloid/io'
3
+ rescue LoadError
4
+ Kernel.fail 'TCP forwarding requires Celluloid::IO to be present. ' \
5
+ "Please install or add as a dependency: gem 'celluloid-io'"
6
+ end
7
+
8
+ require 'listen/adapter/tcp'
9
+ require 'listen/tcp/listener'
@@ -65,8 +65,6 @@ module Listen
65
65
  def handle_connection(socket)
66
66
  @sockets << socket
67
67
  end
68
-
69
68
  end
70
-
71
69
  end
72
70
  end
@@ -4,7 +4,6 @@ require 'listen/tcp/message'
4
4
  module Listen
5
5
  module TCP
6
6
  class Listener < Listen::Listener
7
-
8
7
  DEFAULT_HOST = 'localhost'
9
8
 
10
9
  attr_reader :host, :mode, :port
@@ -43,18 +42,24 @@ module Listen
43
42
  # Hook to broadcast changes over TCP
44
43
  def block
45
44
  if broadcaster?
46
- Proc.new { |modified, added, removed|
45
+ proc do |modified, added, removed|
47
46
 
48
47
  # Honour paused and stopped states
49
48
  next if @paused || @stopping
50
49
 
51
- # Broadcast changes as a hash (see Listen::Adapter::TCP#handle_message)
52
- message = Message.new(modified: modified, added: added, removed: removed)
50
+ # Broadcast changes as a hash
51
+ #
52
+ # @see Listen::Adapter::TCP#handle_message
53
+ message = Message.new(
54
+ modified: modified,
55
+ added: added,
56
+ removed: removed)
57
+
53
58
  registry[:broadcaster].async.broadcast(message.payload)
54
59
 
55
60
  # Invoke the original callback block
56
61
  @block.call(modified, added, removed) if @block
57
- }
62
+ end
58
63
  else
59
64
  super
60
65
  end
@@ -74,7 +79,8 @@ module Listen
74
79
  #
75
80
  def mode=(mode)
76
81
  unless [:broadcaster, :recipient].include? mode
77
- raise ArgumentError, 'TCP::Listener requires mode to be either :broadcaster or :recipient'
82
+ fail ArgumentError, 'TCP::Listener requires mode to be either'\
83
+ ' :broadcaster or :recipient'
78
84
  end
79
85
  @mode = mode
80
86
  end
@@ -85,7 +91,7 @@ module Listen
85
91
  #
86
92
  def target=(target)
87
93
  unless target
88
- raise ArgumentError, 'TCP::Listener requires target to be given'
94
+ fail ArgumentError, 'TCP::Listener requires target to be given'
89
95
  end
90
96
 
91
97
  @host = DEFAULT_HOST if recipient?
@@ -97,7 +103,6 @@ module Listen
97
103
  @port = @port.to_i
98
104
  end
99
105
  end
100
-
101
106
  end
102
107
  end
103
108
  end
@@ -3,7 +3,6 @@ require 'json'
3
3
  module Listen
4
4
  module TCP
5
5
  class Message
6
-
7
6
  attr_reader :body, :object, :payload, :size
8
7
 
9
8
  HEADER_SIZE = 4
@@ -46,7 +45,6 @@ module Listen
46
45
  end
47
46
  end
48
47
  end
49
-
50
48
  end
51
49
  end
52
50
  end
@@ -1,3 +1,3 @@
1
1
  module Listen
2
- VERSION = '2.7.4'
2
+ VERSION = '2.7.5'
3
3
  end
data/listen.gemspec CHANGED
@@ -11,21 +11,22 @@ Gem::Specification.new do |s|
11
11
  s.email = 'thibaud@thibaud.gg'
12
12
  s.homepage = 'https://github.com/guard/listen'
13
13
  s.summary = 'Listen to file modifications'
14
- s.description = 'The Listen gem listens to file modifications and notifies you about the changes. Works everywhere!'
14
+ s.description = 'The Listen gem listens to file modifications and '\
15
+ 'notifies you about the changes. Works everywhere!'
15
16
 
16
17
  s.files = `git ls-files`.split($/)
17
18
  s.test_files = s.files.grep(%r{^spec/})
18
19
  s.executable = 'listen'
19
20
  s.require_path = 'lib'
20
21
 
21
- s.required_ruby_version = ">= 1.9.3"
22
+ s.required_ruby_version = '>= 1.9.3'
22
23
 
23
24
  s.add_dependency 'celluloid', '>= 0.15.2'
24
- s.add_dependency 'celluloid-io', '>= 0.15.0'
25
25
  s.add_dependency 'rb-fsevent', '>= 0.9.3'
26
26
  s.add_dependency 'rb-inotify', '>= 0.9'
27
27
 
28
28
  s.add_development_dependency 'bundler', '>= 1.3.5'
29
+ s.add_development_dependency 'celluloid-io', '>= 0.15.0'
29
30
  s.add_development_dependency 'rake'
30
31
  s.add_development_dependency 'rspec', '~> 2.14'
31
32
  s.add_development_dependency 'rspec-retry'
@@ -1,29 +1,35 @@
1
1
  # encoding: UTF-8
2
2
  require 'spec_helper'
3
3
 
4
- describe "Listen" do
5
- let(:options) { { } }
6
- let(:callback) { ->(modified, added, removed) {
7
- add_changes(:modified, modified)
8
- add_changes(:added, added)
9
- add_changes(:removed, removed)
10
- } }
4
+ describe 'Listen' do
5
+ let(:options) { {} }
6
+
7
+ let(:callback) do
8
+ lambda do |modified, added, removed|
9
+ add_changes(:modified, modified)
10
+ add_changes(:added, added)
11
+ add_changes(:removed, removed)
12
+ end
13
+ end
14
+
11
15
  let(:listener) { @listener }
12
- before {
16
+ before do
13
17
  @listener = setup_listener(options, callback)
14
18
  @listener.start
15
- }
19
+ end
20
+
16
21
  after { listener.stop }
17
22
 
18
- context "with one listen dir" do
23
+ context 'with one listen dir' do
19
24
  let(:paths) { Pathname.new(Dir.pwd) }
20
- around { |example| fixtures { |path| example.run } }
25
+ around { |example| fixtures { example.run } }
21
26
 
22
- context "with change block raising" do
23
- let(:callback) { ->(x,y,z) { raise 'foo' } }
27
+ context 'with change block raising' do
28
+ let(:callback) { ->(_, _, _) { fail 'foo' } }
24
29
 
25
- it "warns the backtrace" do
26
- expect(Kernel).to receive(:warn).with("[Listen warning]: Change block raised an exception: foo")
30
+ it 'warns the backtrace' do
31
+ expect(Kernel).to receive(:warn).
32
+ with('[Listen warning]: Change block raised an exception: foo')
27
33
  expect(Kernel).to receive(:warn).with(/^Backtrace:.*/)
28
34
  listen { touch 'file.rb' }
29
35
  end
@@ -33,203 +39,278 @@ describe "Listen" do
33
39
  context "force_polling option to #{polling}" do
34
40
  let(:options) { { force_polling: polling, latency: 0.1 } }
35
41
 
36
- context "nothing in listen dir" do
37
- it "listens to file addition" do
38
- expect(listen {
42
+ context 'nothing in listen dir' do
43
+ it 'listens to file addition' do
44
+ expect(listen do
39
45
  touch 'file.rb'
40
- }).to eq({ modified: [], added: ['file.rb'], removed: [] })
46
+ end).to eq(modified: [], added: ['file.rb'], removed: [])
41
47
  end
42
48
 
43
- it "listens to multiple files addition" do
44
- expect(listen {
49
+ it 'listens to multiple files addition' do
50
+ result = listen do
45
51
  touch 'file1.rb'
46
52
  touch 'file2.rb'
47
- }).to eq({ modified: [], added: ['file1.rb', 'file2.rb'], removed: [] })
53
+ end
54
+
55
+ expect(result).to eq(modified: [],
56
+ added: %w(file1.rb file2.rb),
57
+ removed: [])
48
58
  end
49
59
 
50
- it "listens to file moved inside" do
60
+ it 'listens to file moved inside' do
51
61
  touch '../file.rb'
52
- expect(listen {
62
+ expect(listen do
53
63
  mv '../file.rb', 'file.rb'
54
- }).to eq({ modified: [], added: ['file.rb'], removed: [] })
64
+ end).to eq(modified: [], added: ['file.rb'], removed: [])
55
65
  end
56
66
  end
57
67
 
58
- context "file in listen dir" do
59
- around { |example| touch 'file.rb'; example.run }
68
+ context 'file in listen dir' do
69
+ around do |example|
70
+ touch 'file.rb'
71
+ example.run
72
+ end
60
73
 
61
- it "listens to file touch" do
62
- expect(listen {
74
+ it 'listens to file touch' do
75
+ expect(listen do
63
76
  touch 'file.rb'
64
- }).to eq({ modified: ['file.rb'], added: [], removed: [] })
77
+ end).to eq(modified: ['file.rb'], added: [], removed: [])
65
78
  end
66
79
 
67
- it "listens to file modification" do
68
- expect(listen {
80
+ it 'listens to file modification' do
81
+ expect(listen do
69
82
  open('file.rb', 'w') { |f| f.write('foo') }
70
- }).to eq({ modified: ['file.rb'], added: [], removed: [] })
83
+ end).to eq(modified: ['file.rb'], added: [], removed: [])
71
84
  end
72
85
 
73
- it "listens to file modification and wait" do
74
- expect(listen {
86
+ it 'listens to file modification and wait' do
87
+ expect(listen do
75
88
  open('file.rb', 'w') { |f| f.write('foo') }
76
89
  sleep 0.5
77
- }).to eq({ modified: ['file.rb'], added: [], removed: [] })
90
+ end).to eq(modified: ['file.rb'], added: [], removed: [])
78
91
  end
79
92
 
80
- it "listens to file echo" do
81
- expect(listen {
93
+ it 'listens to file echo' do
94
+ expect(listen do
82
95
  `echo foo > #{Dir.pwd}/file.rb`
83
- }).to eq({ modified: ['file.rb'], added: [], removed: [] })
96
+ end).to eq(modified: ['file.rb'], added: [], removed: [])
84
97
  end
85
98
 
86
- it "listens to file removal" do
87
- expect(listen {
99
+ it 'listens to file removal' do
100
+ expect(listen do
88
101
  rm 'file.rb'
89
- }).to eq({ modified: [], added: [], removed: ['file.rb'] })
102
+ end).to eq(modified: [], added: [], removed: ['file.rb'])
90
103
  end
91
104
 
92
- it "listens to file moved out" do
93
- expect(listen {
105
+ it 'listens to file moved out' do
106
+ expect(listen do
94
107
  mv 'file.rb', '../file.rb'
95
- }).to eq({ modified: [], added: [], removed: ['file.rb'] })
108
+ end).to eq(modified: [], added: [], removed: ['file.rb'])
96
109
  end
97
110
 
98
- it "listens to file mode change" do
99
- expect(listen {
111
+ it 'listens to file mode change' do
112
+ expect(listen do
100
113
  chmod 0777, 'file.rb'
101
- }).to eq({ modified: ['file.rb'], added: [], removed: [] })
114
+ end).to eq(modified: ['file.rb'], added: [], removed: [])
102
115
  end
103
116
  end
104
117
 
105
- context "hidden file in listen dir" do
106
- around { |example| touch '.hidden'; example.run }
118
+ context 'hidden file in listen dir' do
119
+ around do |example|
120
+ touch '.hidden'
121
+ example.run
122
+ end
107
123
 
108
- it "listens to file touch" do
109
- expect(listen {
124
+ it 'listens to file touch' do
125
+ expect(listen do
110
126
  touch '.hidden'
111
- }).to eq({ modified: ['.hidden'], added: [], removed: [] })
127
+ end).to eq(modified: ['.hidden'], added: [], removed: [])
112
128
  end
113
129
  end
114
130
 
115
- context "dir in listen dir" do
116
- around { |example| mkdir_p 'dir'; example.run }
131
+ context 'dir in listen dir' do
132
+ around do |example|
133
+ mkdir_p 'dir'
134
+ example.run
135
+ end
117
136
 
118
- it "listens to file touch" do
119
- expect(listen {
137
+ it 'listens to file touch' do
138
+ expect(listen do
120
139
  touch 'dir/file.rb'
121
- }).to eq({ modified: [], added: ['dir/file.rb'], removed: [] })
140
+ end).to eq(modified: [], added: ['dir/file.rb'], removed: [])
122
141
  end
123
142
  end
124
143
 
125
- context "dir with file in listen dir" do
126
- around { |example| mkdir_p 'dir'; touch 'dir/file.rb'; example.run }
144
+ context 'dir with file in listen dir' do
145
+ around do |example|
146
+ mkdir_p 'dir'
147
+ touch 'dir/file.rb'
148
+ example.run
149
+ end
150
+
151
+ it 'listens to file move' do
152
+ expected = { modified: [],
153
+ added: %w(file.rb),
154
+ removed: %w(dir/file.rb)
155
+ }
127
156
 
128
- it "listens to file move" do
129
- expect(listen {
157
+ expect(listen do
130
158
  mv 'dir/file.rb', 'file.rb'
131
- }).to eq({ modified: [], added: ['file.rb'], removed: ['dir/file.rb'] })
159
+ end).to eq expected
132
160
  end
133
161
  end
134
162
 
135
- context "two dirs with files in listen dir" do
136
- around { |example|
137
- mkdir_p 'dir1'; touch 'dir1/file1.rb'
138
- mkdir_p 'dir2'; touch 'dir2/file2.rb'
139
- example.run }
163
+ context 'two dirs with files in listen dir' do
164
+ around do |example|
165
+ mkdir_p 'dir1'
166
+ touch 'dir1/file1.rb'
167
+ mkdir_p 'dir2'
168
+ touch 'dir2/file2.rb'
169
+ example.run
170
+ end
171
+
172
+ it 'listens to multiple file moves' do
173
+ expected = {
174
+ modified: [],
175
+ added: ['dir1/file2.rb', 'dir2/file1.rb'],
176
+ removed: ['dir1/file1.rb', 'dir2/file2.rb']
177
+ }
140
178
 
141
- it "listens to multiple file moves" do
142
- expect(listen {
179
+ expect(listen do
143
180
  mv 'dir1/file1.rb', 'dir2/file1.rb'
144
181
  mv 'dir2/file2.rb', 'dir1/file2.rb'
145
- }).to eq({ modified: [], added: ['dir1/file2.rb', 'dir2/file1.rb'], removed: ['dir1/file1.rb', 'dir2/file2.rb'] })
182
+ end).to eq expected
146
183
  end
147
184
 
148
- it "listens to dir move" do
149
- expect(listen {
185
+ it 'listens to dir move' do
186
+ expected = { modified: [],
187
+ added: ['dir2/dir1/file1.rb'],
188
+ removed: ['dir1/file1.rb'] }
189
+
190
+ expect(listen do
150
191
  mv 'dir1', 'dir2/'
151
- }).to eq({ modified: [], added: ['dir2/dir1/file1.rb'], removed: ['dir1/file1.rb'] })
192
+ end).to eq expected
152
193
  end
153
194
  end
154
195
 
155
- context "default ignored dir with file in listen dir" do
156
- around { |example| mkdir_p '.bundle'; touch '.bundle/file.rb'; example.run }
196
+ context 'default ignored dir with file in listen dir' do
197
+ around do |example|
198
+ mkdir_p '.bundle'
199
+ touch '.bundle/file.rb'
200
+ example.run
201
+ end
202
+
157
203
  let(:options) { { force_polling: polling, latency: 0.1 } }
158
204
 
159
205
  it "doesn't listen to file touch" do
160
- expect(listen {
206
+ expect(listen do
161
207
  touch '.bundle/file.rb'
162
- }).to eq({ modified: [], added: [], removed: [] })
208
+ end).to eq(modified: [], added: [], removed: [])
163
209
  end
164
210
  end
165
211
 
166
- context "ignored dir with file in listen dir" do
167
- around { |example| mkdir_p 'ignored_dir'; touch 'ignored_dir/file.rb'; example.run }
168
- let(:options) { { force_polling: polling, latency: 0.1, ignore: /ignored_dir/ } }
212
+ context 'ignored dir with file in listen dir' do
213
+ around do |example|
214
+ mkdir_p 'ignored_dir'
215
+ touch 'ignored_dir/file.rb'
216
+ example.run
217
+ end
218
+
219
+ let(:options) do
220
+ { force_polling: polling,
221
+ latency: 0.1,
222
+ ignore: /ignored_dir/ }
223
+ end
169
224
 
170
225
  it "doesn't listen to file touch" do
171
- expect(listen {
226
+ expect(listen do
172
227
  touch 'ignored_dir/file.rb'
173
- }).to eq({ modified: [], added: [], removed: [] })
228
+ end).to eq(modified: [], added: [], removed: [])
174
229
  end
175
230
  end
176
231
 
177
- context "with ignored file in listen dir" do
178
- around { |example| touch 'file.rb'; example.run }
179
- let(:options) { { force_polling: polling, latency: 0.1, ignore: /\.rb$/ } }
232
+ context 'with ignored file in listen dir' do
233
+ around do |example|
234
+ touch 'file.rb'
235
+ example.run
236
+ end
237
+ let(:options) do
238
+ { force_polling: polling,
239
+ latency: 0.1,
240
+ ignore: /\.rb$/ }
241
+ end
180
242
 
181
243
  it "doesn't listen to file touch" do
182
- expect(listen {
244
+ expect(listen do
183
245
  touch 'file.rb'
184
- }).to eq({ modified: [], added: [], removed: [] })
246
+ end).to eq(modified: [], added: [], removed: [])
185
247
  end
186
248
  end
187
249
 
188
- context "with only option" do
189
- let(:options) { { force_polling: polling, latency: 0.1, only: /\.rb$/ } }
250
+ context 'with only option' do
251
+ let(:options) do
252
+ { force_polling: polling,
253
+ latency: 0.1,
254
+ only: /\.rb$/ }
255
+ end
190
256
 
191
- it "listens only to file touch matching with only patterns" do
192
- expect(listen {
257
+ it 'listens only to file touch matching with only patterns' do
258
+ expect(listen do
193
259
  touch 'file.rb'
194
260
  touch 'file.txt'
195
- }).to eq({ modified: [], added: ['file.rb'], removed: [] })
261
+ end).to eq(modified: [], added: ['file.rb'], removed: [])
196
262
  end
197
263
  end
198
264
 
199
- context "with ignore and only option" do
200
- let(:options) { { force_polling: polling, latency: 0.1, ignore: /bar\.rb$/, only: /\.rb$/ } }
265
+ context 'with ignore and only option' do
266
+ let(:options) do
267
+ { force_polling: polling,
268
+ latency: 0.1,
269
+ ignore: /bar\.rb$/, only: /\.rb$/ }
270
+ end
201
271
 
202
- it "listens only to file touch matching with only patterns" do
203
- expect(listen {
272
+ it 'listens only to file touch matching with only patterns' do
273
+ expect(listen do
204
274
  touch 'file.rb'
205
275
  touch 'bar.rb'
206
276
  touch 'file.txt'
207
- }).to eq({ modified: [], added: ['file.rb'], removed: [] })
277
+ end).to eq(modified: [], added: ['file.rb'], removed: [])
208
278
  end
209
279
  end
210
280
 
211
- describe "#ignore" do
212
- around { |example| touch 'file.rb'; example.run }
213
- let(:options) { { force_polling: polling, latency: 0.1, ignore: /\.rb$/ } }
281
+ describe '#ignore' do
282
+ around do |example|
283
+ touch 'file.rb'
284
+ example.run
285
+ end
286
+ let(:options) do
287
+ { force_polling: polling,
288
+ latency: 0.1,
289
+ ignore: /\.rb$/ }
290
+ end
214
291
 
215
- it "overwrites existing patterns" do
216
- expect(listen {
292
+ it 'overwrites existing patterns' do
293
+ expect(listen do
217
294
  listener.ignore(/\.txt/)
218
295
  touch 'file.rb'
219
296
  touch 'file.txt'
220
- }).to eq({ modified: [], added: [], removed: [] })
297
+ end).to eq(modified: [], added: [], removed: [])
221
298
  end
222
299
  end
223
300
 
224
- describe "#ignore!" do
225
- let(:options) { { force_polling: polling, latency: 0.1, ignore: /\.rb$/ } }
301
+ describe '#ignore!' do
302
+ let(:options) do
303
+ { force_polling: polling,
304
+ latency: 0.1,
305
+ ignore: /\.rb$/ }
306
+ end
226
307
 
227
- it "overwrites existing patterns" do
228
- expect(listen {
308
+ it 'overwrites existing patterns' do
309
+ expect(listen do
229
310
  listener.ignore!(/\.txt/)
230
311
  touch 'file.rb'
231
312
  touch 'file.txt'
232
- }).to eq({ modified: [], added: ['file.rb'], removed: [] })
313
+ end).to eq(modified: [], added: ['file.rb'], removed: [])
233
314
  end
234
315
  end
235
316
  end