filewatcher 1.0.0 → 2.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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