filewatcher 1.0.0 → 2.0.0.beta2

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.
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../lib/filewatcher/runner'
4
-
5
- describe Filewatcher::Runner do
6
- before do
7
- @init = proc do |filename|
8
- Filewatcher::Runner.new(filename)
9
- end
10
- end
11
-
12
- describe '#initialize' do
13
- it 'should recieve filename' do
14
- -> { @init.call('file.txt') }
15
- .should.not.raise ArgumentError
16
- end
17
- end
18
-
19
- describe '#command' do
20
- it 'should return correct command for file with .py extension' do
21
- @init.call('file.py').command
22
- .should.equal 'env python file.py'
23
- end
24
-
25
- it 'should return correct command for file with .js extension' do
26
- @init.call('file.js').command
27
- .should.equal 'env node file.js'
28
- end
29
-
30
- it 'should return correct command for file with .rb extension' do
31
- @init.call('file.rb').command
32
- .should.equal 'env ruby file.rb'
33
- end
34
-
35
- it 'should return correct command for file with .pl extension' do
36
- @init.call('file.pl').command
37
- .should.equal 'env perl file.pl'
38
- end
39
-
40
- it 'should return correct command for file with .awk extension' do
41
- @init.call('file.awk').command
42
- .should.equal 'env awk file.awk'
43
- end
44
-
45
- it 'should return correct command for file with .php extension' do
46
- @init.call('file.php').command
47
- .should.equal 'env php file.php'
48
- end
49
-
50
- it 'should return correct command for file with .phtml extension' do
51
- @init.call('file.phtml').command
52
- .should.equal 'env php file.phtml'
53
- end
54
-
55
- it 'should return correct command for file with .php4 extension' do
56
- @init.call('file.php4').command
57
- .should.equal 'env php file.php4'
58
- end
59
-
60
- it 'should return correct command for file with .php3 extension' do
61
- @init.call('file.php3').command
62
- .should.equal 'env php file.php3'
63
- end
64
-
65
- it 'should return correct command for file with .php5 extension' do
66
- @init.call('file.php5').command
67
- .should.equal 'env php file.php5'
68
- end
69
-
70
- it 'should return correct command for file with .phps extension' do
71
- @init.call('file.phps').command
72
- .should.equal 'env php file.phps'
73
- end
74
- end
75
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../lib/filewatcher/version'
4
-
5
- describe Filewatcher::VERSION do
6
- it 'should exist as constant' do
7
- Filewatcher.const_defined?(:VERSION).should.be.true
8
- end
9
-
10
- it 'should be an instance of String' do
11
- Filewatcher::VERSION.class.should.equal String
12
- end
13
- end
@@ -1,134 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bacon'
4
- require 'bacon/custom_matchers_messages'
5
-
6
- begin
7
- require 'pry-byebug'
8
- rescue LoadError
9
- nil
10
- end
11
-
12
- class WatchRun
13
- TMP_DIR = File.join(__dir__, 'tmp')
14
-
15
- attr_reader :filename, :filewatcher, :thread, :watched, :processed
16
-
17
- def initialize(
18
- filename: 'tmp_file.txt',
19
- directory: false,
20
- every: false,
21
- filewatcher: Filewatcher.new(
22
- File.join(TMP_DIR, '**', '*'), interval: 0.1, every: every
23
- ),
24
- action: :update
25
- )
26
- @filename =
27
- filename.start_with?('/', '~') ? filename : File.join(TMP_DIR, filename)
28
- @directory = directory
29
- @filewatcher = filewatcher
30
- @action = action
31
- end
32
-
33
- def start
34
- File.write(@filename, 'content1') unless @action == :create
35
-
36
- @thread = thread_initialize
37
- sleep 3 # thread needs a chance to start
38
- end
39
-
40
- def run
41
- start
42
-
43
- make_changes
44
- # Some OS, filesystems and Ruby interpretators
45
- # doesn't catch milliseconds of `File.mtime`
46
- sleep 3
47
-
48
- stop
49
- end
50
-
51
- def stop
52
- FileUtils.rm_r(@filename) if File.exist?(@filename)
53
- @thread.exit
54
- sleep 3
55
- end
56
-
57
- private
58
-
59
- def thread_initialize
60
- @watched ||= 0
61
- Thread.new(
62
- @filewatcher, @processed = []
63
- ) do |filewatcher, processed|
64
- filewatcher.watch do |filename, event|
65
- increment_watched
66
- processed.push([filename, event])
67
- end
68
- end
69
- end
70
-
71
- def increment_watched
72
- @watched += 1
73
- end
74
-
75
- def make_changes
76
- return FileUtils.remove(@filename) if @action == :delete
77
- return FileUtils.mkdir_p(@filename) if @directory
78
- File.write(@filename, 'content2')
79
- end
80
- end
81
-
82
- class ShellWatchRun
83
- EXECUTABLE = "#{'ruby ' if Gem.win_platform?}" \
84
- "#{File.realpath File.join(__dir__, '..', 'bin', 'filewatcher')}".freeze
85
-
86
- attr_reader :output
87
-
88
- def initialize(
89
- options: '',
90
- dumper: :watched,
91
- output: File.join(WatchRun::TMP_DIR, 'env')
92
- )
93
- @options = options
94
- @dumper = dumper
95
- @output = output
96
- end
97
-
98
- def start
99
- @pid = spawn(
100
- "#{EXECUTABLE} #{@options} \"#{WatchRun::TMP_DIR}/foo*\"" \
101
- " \"ruby #{File.join(__dir__, 'dumpers', "#{@dumper}_dumper.rb")}\""
102
- )
103
- Process.detach(@pid)
104
- sleep 12
105
- end
106
-
107
- def run
108
- start
109
-
110
- make_changes
111
-
112
- stop
113
- end
114
-
115
- def stop
116
- Process.kill('KILL', @pid)
117
- sleep 6
118
- end
119
-
120
- private
121
-
122
- def make_changes
123
- FileUtils.touch "#{WatchRun::TMP_DIR}/foo.txt"
124
- sleep 12
125
- end
126
- end
127
-
128
- custom_matcher :include_all_files do |obj, elements|
129
- elements.all? { |element| obj.include? File.expand_path(element) }
130
- end
131
-
132
- def dump_to_env_file(content)
133
- File.write File.join(WatchRun::TMP_DIR, 'env'), content
134
- end
@@ -1,305 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'fileutils'
4
- require_relative '../lib/filewatcher'
5
-
6
- describe Filewatcher do
7
- before do
8
- FileUtils.mkdir_p WatchRun::TMP_DIR
9
- end
10
-
11
- after do
12
- FileUtils.rm_r WatchRun::TMP_DIR
13
- end
14
-
15
- describe '#initialize' do
16
- it 'should exclude selected file patterns' do
17
- wr = WatchRun.new(
18
- filewatcher: Filewatcher.new(
19
- File.expand_path('test/tmp/**/*'),
20
- exclude: File.expand_path('test/tmp/**/*.txt')
21
- )
22
- )
23
-
24
- wr.run
25
-
26
- wr.processed.should.be.empty
27
- end
28
-
29
- it 'should handle absolute paths with globs' do
30
- wr = WatchRun.new(
31
- filewatcher: Filewatcher.new(
32
- File.expand_path('test/tmp/**/*')
33
- )
34
- )
35
-
36
- wr.run
37
-
38
- wr.processed.should.equal(
39
- [[wr.filename, :updated]]
40
- )
41
- end
42
-
43
- it 'should handle globs' do
44
- wr = WatchRun.new(
45
- filewatcher: Filewatcher.new('test/tmp/**/*')
46
- )
47
-
48
- wr.run
49
-
50
- wr.processed.should.equal(
51
- [[wr.filename, :updated]]
52
- )
53
- end
54
-
55
- it 'should handle explicit relative paths with globs' do
56
- wr = WatchRun.new(
57
- filewatcher: Filewatcher.new('./test/tmp/**/*')
58
- )
59
-
60
- wr.run
61
-
62
- wr.processed.should.equal(
63
- [[wr.filename, :updated]]
64
- )
65
- end
66
-
67
- it 'should handle explicit relative paths' do
68
- wr = WatchRun.new(
69
- filewatcher: Filewatcher.new('./test/tmp')
70
- )
71
-
72
- wr.run
73
-
74
- wr.processed.should.equal(
75
- [[wr.filename, :updated]]
76
- )
77
- end
78
-
79
- it 'should handle tilde expansion' do
80
- filename = File.expand_path('~/file_watcher_1.txt')
81
-
82
- wr = WatchRun.new(
83
- filename: filename,
84
- filewatcher: Filewatcher.new('~/file_watcher_1.txt')
85
- )
86
-
87
- wr.run
88
-
89
- wr.processed.should.equal(
90
- [[filename, :updated]]
91
- )
92
- end
93
-
94
- it 'should immediately run with corresponding option' do
95
- wr = WatchRun.new(
96
- filewatcher: Filewatcher.new('**/*', immediate: true)
97
- )
98
-
99
- wr.start
100
- wr.stop
101
-
102
- wr.processed.should.equal [['', '']]
103
- wr.watched.should.be > 0
104
- end
105
-
106
- it 'should not be executed without immediate option and changes' do
107
- wr = WatchRun.new(
108
- filewatcher: Filewatcher.new('**/*', immediate: false)
109
- )
110
-
111
- wr.start
112
- wr.stop
113
-
114
- wr.processed.should.be.empty
115
- wr.watched.should.equal 0
116
- end
117
- end
118
-
119
- describe '#watch' do
120
- it 'should detect file deletions' do
121
- wr = WatchRun.new(action: :delete)
122
-
123
- wr.run
124
-
125
- wr.processed.should.equal(
126
- [[wr.filename, :deleted]]
127
- )
128
- end
129
-
130
- it 'should detect file additions' do
131
- wr = WatchRun.new(action: :create)
132
-
133
- wr.run
134
-
135
- wr.processed.should.equal(
136
- [[wr.filename, :created]]
137
- )
138
- end
139
-
140
- it 'should detect file updates' do
141
- wr = WatchRun.new(action: :update)
142
-
143
- wr.run
144
-
145
- wr.processed.should.equal(
146
- [[wr.filename, :updated]]
147
- )
148
- end
149
-
150
- it 'should detect new files in subfolders' do
151
- FileUtils.mkdir_p subfolder = File.expand_path('test/tmp/new_sub_folder')
152
-
153
- wr = WatchRun.new(
154
- filename: File.join(subfolder, 'file.txt'),
155
- action: :create,
156
- every: true
157
- )
158
- wr.run
159
- wr.processed.should.equal(
160
- [
161
- [subfolder, :updated],
162
- [wr.filename, :created]
163
- ]
164
- )
165
- end
166
-
167
- it 'should detect new subfolders' do
168
- subfolder = 'new_sub_folder'
169
-
170
- wr = WatchRun.new(
171
- filename: subfolder,
172
- directory: true,
173
- action: :create
174
- )
175
-
176
- wr.run
177
-
178
- wr.processed.should.equal(
179
- [[wr.filename, :created]]
180
- )
181
- end
182
- end
183
-
184
- describe '#stop' do
185
- it 'should work' do
186
- wr = WatchRun.new
187
-
188
- wr.start
189
-
190
- wr.filewatcher.stop
191
-
192
- # Proves thread successfully joined
193
- wr.thread.join.should.equal wr.thread
194
- end
195
- end
196
-
197
- describe '#pause, #resume' do
198
- it 'should work' do
199
- wr = WatchRun.new(action: :create, every: true)
200
-
201
- wr.start
202
-
203
- wr.filewatcher.pause
204
-
205
- (1..4).each do |n|
206
- File.write("test/tmp/file#{n}.txt", "content#{n}")
207
- end
208
- sleep 0.2 # Give filewatcher time to respond
209
-
210
- # update block should not have been called
211
- wr.processed.should.be.empty
212
-
213
- wr.filewatcher.resume
214
- sleep 0.2 # Give filewatcher time to respond
215
-
216
- # update block still should not have been called
217
- wr.processed.should.be.empty
218
-
219
- added_files = (5..7).to_a.map do |n|
220
- File.write(file = "test/tmp/file#{n}.txt", "content#{n}")
221
- file
222
- end
223
- sleep 0.2 # Give filewatcher time to respond
224
-
225
- wr.filewatcher.stop
226
- wr.stop
227
- wr.processed.map(&:first).should include_all_files(added_files)
228
- end
229
- end
230
-
231
- describe '#finalize' do
232
- it 'should process all remaining changes' do
233
- wr = WatchRun.new(action: :create, every: true)
234
-
235
- wr.start
236
-
237
- wr.filewatcher.stop
238
- wr.thread.join
239
-
240
- added_files = (1..4).to_a.map do |n|
241
- File.write(file = "test/tmp/file#{n}.txt", "content#{n}")
242
- file
243
- end
244
-
245
- wr.filewatcher.finalize
246
-
247
- wr.processed.map(&:first).should include_all_files(added_files)
248
- end
249
- end
250
-
251
- describe 'executable' do
252
- tmp_dir = WatchRun::TMP_DIR
253
-
254
- it 'should run' do
255
- null_output = Gem.win_platform? ? 'NUL' : '/dev/null'
256
- system("#{ShellWatchRun::EXECUTABLE} > #{null_output}")
257
- .should.be.true
258
- end
259
-
260
- it 'should set correct ENV variables' do
261
- swr = ShellWatchRun.new(
262
- dumper: :env
263
- )
264
-
265
- swr.run
266
-
267
- File.read(swr.output)
268
- .should.equal(
269
- %W[
270
- #{tmp_dir}/foo.txt
271
- foo.txt
272
- created
273
- #{tmp_dir}
274
- #{tmp_dir}/foo.txt
275
- test/tmp/foo.txt
276
- ].join(', ')
277
- )
278
- end
279
-
280
- it 'should be executed immediately with corresponding option' do
281
- swr = ShellWatchRun.new(
282
- options: '--immediate',
283
- dumper: :watched
284
- )
285
-
286
- swr.start
287
- swr.stop
288
-
289
- File.exist?(swr.output).should.be.true
290
- File.read(swr.output).should.equal 'watched'
291
- end
292
-
293
- it 'should not be executed without immediate option and changes' do
294
- swr = ShellWatchRun.new(
295
- options: '',
296
- dumper: :watched
297
- )
298
-
299
- swr.start
300
- swr.stop
301
-
302
- File.exist?(swr.output).should.be.false
303
- end
304
- end
305
- end