filewatcher 0.5.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Filewatcher
4
+ # Module for all cycles in `Filewatcher#watch`
5
+ module Cycles
6
+ private
7
+
8
+ def main_cycle
9
+ while @keep_watching
10
+ @end_snapshot = mtime_snapshot if @pausing
11
+
12
+ pausing_cycle
13
+
14
+ watching_cycle
15
+
16
+ # test and clear @changes to prevent yielding the last
17
+ # changes twice if @keep_watching has just been set to false
18
+ trigger_changes
19
+ end
20
+ end
21
+
22
+ def pausing_cycle
23
+ while @keep_watching && @pausing
24
+ update_spinner('Pausing')
25
+ sleep @interval
26
+ end
27
+ end
28
+
29
+ def watching_cycle
30
+ while @keep_watching && !filesystem_updated? && !@pausing
31
+ update_spinner('Watching')
32
+ sleep @interval
33
+ end
34
+ end
35
+
36
+ def trigger_changes(on_update = @on_update)
37
+ thread = Thread.new do
38
+ changes = @every ? @changes : @changes.first(1)
39
+ changes.each do |filename, event|
40
+ on_update.call(filename, event)
41
+ end
42
+ @changes.clear
43
+ end
44
+ thread.join
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ require_relative '../filewatcher'
5
+
6
+ class Filewatcher
7
+ # Class for building ENV variables for executable
8
+ class Env
9
+ def initialize(filename, event)
10
+ @filename = filename
11
+ @event = event
12
+ @path = Pathname.new(@filename)
13
+ @realpath = @path.realpath
14
+ @current_dir = Pathname.new(Dir.pwd)
15
+ end
16
+
17
+ def to_h
18
+ {
19
+ 'FILEPATH' => (@realpath.to_s if @event != :deleted),
20
+ 'FILENAME' => @filename,
21
+ 'BASENAME' => @path.basename.to_s,
22
+ 'EVENT' => @event.to_s,
23
+ 'DIRNAME' => @path.parent.realpath.to_s,
24
+ 'ABSOLUTE_FILENAME' => @realpath.to_s,
25
+ 'RELATIVE_FILENAME' => @realpath.relative_path_from(@current_dir).to_s
26
+ }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Filewatcher
4
+ ## Get runner command by filename
5
+ class Runner
6
+ ## Define runners for `--exec` option
7
+ RUNNERS = {
8
+ python: %w[py],
9
+ node: %w[js],
10
+ ruby: %w[rb],
11
+ perl: %w[pl],
12
+ awk: %w[awk],
13
+ php: %w[php phtml php4 php3 php5 phps]
14
+ }.freeze
15
+
16
+ def initialize(filename)
17
+ @filename = filename
18
+ @ext = File.extname(filename).delete('.')
19
+ end
20
+
21
+ def command
22
+ "env #{runner} #{@filename}" if runner
23
+ end
24
+
25
+ private
26
+
27
+ def runner
28
+ return @runner if defined?(@runner)
29
+ @runner, _exts = RUNNERS.find { |_cmd, exts| exts.include? @ext }
30
+ @runner
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../filewatcher'
4
+
5
+ class Filewatcher
6
+ VERSION = '1.0.0'.freeze
7
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../helper'
4
+
5
+ dump_to_env_file(
6
+ %w[
7
+ FILENAME BASENAME EVENT DIRNAME ABSOLUTE_FILENAME
8
+ RELATIVE_FILENAME
9
+ ].map { |var| ENV[var] }.join(', ')
10
+ )
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../helper'
4
+
5
+ dump_to_env_file 'watched'
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../lib/filewatcher/env'
4
+
5
+ describe Filewatcher::Env do
6
+ describe '#initialize' do
7
+ it 'should recieve filename and event' do
8
+ -> { Filewatcher::Env.new(__FILE__, :updated) }
9
+ .should.not.raise ArgumentError
10
+ end
11
+ end
12
+
13
+ describe '#to_h' do
14
+ before do
15
+ @init = proc do |file: __FILE__, event: :updated|
16
+ Filewatcher::Env.new(file, event).to_h
17
+ end
18
+ @env = @init.call
19
+ end
20
+
21
+ it 'should return Hash' do
22
+ @env.should.be.kind_of Hash
23
+ end
24
+
25
+ it 'should return Hash with FILEPATH key for created event' do
26
+ @init.call(event: :created)['FILEPATH']
27
+ .should.equal File.join(Dir.pwd, __FILE__)
28
+ end
29
+
30
+ it 'should return Hash with FILEPATH key for updated event' do
31
+ @init.call(event: :updated)['FILEPATH']
32
+ .should.equal File.join(Dir.pwd, __FILE__)
33
+ end
34
+
35
+ it 'should return Hash without FILEPATH key for deleted event' do
36
+ @init.call(event: :deleted)['FILEPATH']
37
+ .should.equal nil
38
+ end
39
+
40
+ it 'should return Hash with FILENAME key' do
41
+ @init.call(file: __FILE__)['FILENAME']
42
+ .should.equal __FILE__
43
+ end
44
+
45
+ it 'should return Hash with BASENAME key' do
46
+ @init.call(file: __FILE__)['BASENAME']
47
+ .should.equal File.basename(__FILE__)
48
+ end
49
+
50
+ it 'should return Hash with EVENT key' do
51
+ @init.call(event: :updated)['EVENT']
52
+ .should.equal 'updated'
53
+ end
54
+
55
+ it 'should return Hash with DIRNAME key' do
56
+ @init.call(file: __FILE__)['DIRNAME']
57
+ .should.equal File.dirname(File.join(Dir.pwd, __FILE__))
58
+ end
59
+
60
+ it 'should return Hash with ABSOLUTE_FILENAME key' do
61
+ @init.call(file: __FILE__)['ABSOLUTE_FILENAME']
62
+ .should.equal File.join(Dir.pwd, __FILE__)
63
+ end
64
+
65
+ it 'should return Hash with RELATIVE_FILENAME key' do
66
+ @init.call(file: __FILE__)['RELATIVE_FILENAME']
67
+ .should.equal __FILE__
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,75 @@
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
@@ -0,0 +1,13 @@
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
@@ -0,0 +1,134 @@
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,181 +1,305 @@
1
- require 'rubygems'
2
- require 'bacon'
1
+ # frozen_string_literal: true
2
+
3
3
  require 'fileutils'
4
- require File.expand_path("../lib/filewatcher.rb",File.dirname(__FILE__))
4
+ require_relative '../lib/filewatcher'
5
5
 
6
+ describe Filewatcher do
7
+ before do
8
+ FileUtils.mkdir_p WatchRun::TMP_DIR
9
+ end
6
10
 
11
+ after do
12
+ FileUtils.rm_r WatchRun::TMP_DIR
13
+ end
7
14
 
8
- describe FileWatcher do
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
+ )
9
23
 
10
- fixtures =
11
- %w(test/fixtures/file4.rb
12
- test/fixtures/subdir/file6.rb
13
- test/fixtures/subdir/file5.rb
14
- test/fixtures/file2.txt
15
- test/fixtures/file1.txt
16
- test/fixtures/file3.rb)
24
+ wr.run
17
25
 
18
- explicit_relative_fixtures = fixtures.map { |it| "./#{it}" }
26
+ wr.processed.should.be.empty
27
+ end
19
28
 
20
- subfolder = 'test/fixtures/new_sub_folder'
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
+ )
21
35
 
22
- after do
23
- FileUtils.rm_rf subfolder
24
- end
36
+ wr.run
25
37
 
26
- def includes_all(elements)
27
- lambda { |it| elements.all? { |element| it.include? element }}
28
- end
38
+ wr.processed.should.equal(
39
+ [[wr.filename, :updated]]
40
+ )
41
+ end
29
42
 
30
- it "should exclude selected file patterns" do
31
- filewatcher = FileWatcher.new(File.expand_path('test/fixtures/**/*'), :exclude => [File.expand_path("test/fixtures/**/*.txt")])
32
- filtered_fixtures =
33
- %w(test/fixtures/file4.rb
34
- test/fixtures/subdir/file6.rb
35
- test/fixtures/subdir/file5.rb
36
- test/fixtures/file3.rb)
37
- filewatcher.filenames.should.satisfy &includes_all(filtered_fixtures.map { |it| File.expand_path(it) })
38
- end
39
-
40
- it "should handle absolute paths with globs" do
41
- filewatcher = FileWatcher.new(File.expand_path('test/fixtures/**/*'))
43
+ it 'should handle globs' do
44
+ wr = WatchRun.new(
45
+ filewatcher: Filewatcher.new('test/tmp/**/*')
46
+ )
42
47
 
43
- filewatcher.filenames.should.satisfy &includes_all(fixtures.map { |it| File.expand_path(it) })
44
- end
45
-
46
- it "should handle globs" do
47
- filewatcher = FileWatcher.new('test/fixtures/**/*')
48
+ wr.run
48
49
 
49
- filewatcher.filenames.should.satisfy &includes_all(fixtures)
50
- end
50
+ wr.processed.should.equal(
51
+ [[wr.filename, :updated]]
52
+ )
53
+ end
51
54
 
55
+ it 'should handle explicit relative paths with globs' do
56
+ wr = WatchRun.new(
57
+ filewatcher: Filewatcher.new('./test/tmp/**/*')
58
+ )
52
59
 
53
- it "should handle explicit relative paths with globs" do
54
- filewatcher = FileWatcher.new('./test/fixtures/**/*')
60
+ wr.run
55
61
 
56
- filewatcher.filenames.should.satisfy &includes_all(explicit_relative_fixtures)
57
- end
62
+ wr.processed.should.equal(
63
+ [[wr.filename, :updated]]
64
+ )
65
+ end
58
66
 
59
- it "should handle explicit relative paths" do
60
- filewatcher = FileWatcher.new('./test/fixtures')
67
+ it 'should handle explicit relative paths' do
68
+ wr = WatchRun.new(
69
+ filewatcher: Filewatcher.new('./test/tmp')
70
+ )
61
71
 
62
- filewatcher.filenames.should.satisfy &includes_all(explicit_relative_fixtures)
63
- end
72
+ wr.run
73
+
74
+ wr.processed.should.equal(
75
+ [[wr.filename, :updated]]
76
+ )
77
+ end
64
78
 
65
- it "should handle tilde expansion" do
66
- filename = File.expand_path('~/file_watcher_1.txt')
67
- open(filename, 'w') { |f| f.puts 'content1' }
79
+ it 'should handle tilde expansion' do
80
+ filename = File.expand_path('~/file_watcher_1.txt')
68
81
 
69
- filewatcher = FileWatcher.new('~/file_watcher_1.txt')
82
+ wr = WatchRun.new(
83
+ filename: filename,
84
+ filewatcher: Filewatcher.new('~/file_watcher_1.txt')
85
+ )
70
86
 
71
- begin
72
- filewatcher.filenames.should == [filename]
73
- ensure
74
- FileUtils.rm(filename)
87
+ wr.run
88
+
89
+ wr.processed.should.equal(
90
+ [[filename, :updated]]
91
+ )
75
92
  end
76
- end
77
93
 
78
- it "should detect file deletions" do
79
- filename = "test/fixtures/file1.txt"
80
- open(filename,"w") { |f| f.puts "content1" }
81
- filewatcher = FileWatcher.new(["test/fixtures"])
82
- filewatcher.filesystem_updated?.should.be.false
83
- FileUtils.rm(filename)
84
- filewatcher.filesystem_updated?.should.be.true
85
- end
94
+ it 'should immediately run with corresponding option' do
95
+ wr = WatchRun.new(
96
+ filewatcher: Filewatcher.new('**/*', immediate: true)
97
+ )
86
98
 
87
- it "should detect file additions" do
88
- filename = "test/fixtures/file1.txt"
89
- FileUtils.rm(filename) if File.exists?(filename)
90
- filewatcher = FileWatcher.new(["test/fixtures"])
91
- filewatcher.filesystem_updated?.should.be.false
92
- open(filename,"w") { |f| f.puts "content1" }
93
- filewatcher.filesystem_updated?.should.be.true
94
- end
99
+ wr.start
100
+ wr.stop
95
101
 
96
- it "should detect file updates" do
97
- filename = "test/fixtures/file1.txt"
98
- open(filename,"w") { |f| f.puts "content1" }
99
- filewatcher = FileWatcher.new(["test/fixtures"])
100
- filewatcher.filesystem_updated?.should.be.false
101
- sleep 1
102
- open(filename,"w") { |f| f.puts "content2" }
103
- filewatcher.filesystem_updated?.should.be.true
104
- end
102
+ wr.processed.should.equal [['', '']]
103
+ wr.watched.should.be > 0
104
+ end
105
105
 
106
- it "should detect new files in subfolders" do
107
- FileUtils::mkdir_p subfolder
106
+ it 'should not be executed without immediate option and changes' do
107
+ wr = WatchRun.new(
108
+ filewatcher: Filewatcher.new('**/*', immediate: false)
109
+ )
108
110
 
109
- filewatcher = FileWatcher.new(["./test/fixtures"])
110
- filewatcher.filesystem_updated?.should.be.false
111
+ wr.start
112
+ wr.stop
111
113
 
112
- open(subfolder + "/file.txt","w") { |f| f.puts "xyz" }
113
- filewatcher.filesystem_updated?.should.be.true
114
+ wr.processed.should.be.empty
115
+ wr.watched.should.equal 0
116
+ end
114
117
  end
115
118
 
116
- it "should detect new subfolders" do
117
- filewatcher = FileWatcher.new(["test/fixtures"])
118
- filewatcher.filesystem_updated?.should.be.false
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
119
166
 
120
- FileUtils::mkdir_p subfolder
121
- filewatcher.filesystem_updated?.should.be.true
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
122
182
  end
123
183
 
124
- it "should be stoppable" do
125
- filewatcher = FileWatcher.new(["test/fixtures"])
126
- thread = Thread.new(filewatcher){filewatcher.watch(0.1)}
127
- sleep 0.2 # thread needs a chance to start
128
- filewatcher.stop
129
- thread.join.should.equal thread # Proves thread successfully joined
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
130
195
  end
131
196
 
132
- it "should be pauseable/resumable" do
133
- filewatcher = FileWatcher.new(["test/fixtures"])
134
- filewatcher.filesystem_updated?.should.be.false
135
- processed = []
136
- thread = Thread.new(filewatcher,processed) do
137
- filewatcher.watch(0.1){|f,e| processed << f }
138
- end
139
- sleep 0.2 # thread needs a chance to start
140
- filewatcher.pause
141
- (1..4).each do |n|
142
- open("test/fixtures/file#{n}.txt","w") { |f| f.puts "content#{n}" }
143
- end
144
- sleep 0.2 # Give filewatcher time to respond
145
- processed.should.equal [] #update block should not have been called
146
- filewatcher.resume
147
- sleep 0.2 # Give filewatcher time to respond
148
- processed.should.equal [] #update block still should not have been called
149
- added_files = []
150
- (5..7).each do |n|
151
- added_files << "test/fixtures/file#{n}.txt"
152
- open(added_files.last,"w") { |f| f.puts "content#{n}" }
153
- end
154
- sleep 0.2 # Give filewatcher time to respond
155
- filewatcher.stop
156
- processed.should.satisfy &includes_all(added_files)
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
157
229
  end
158
230
 
159
- it "should process all remaining changes at finalize" do
160
- filewatcher = FileWatcher.new(["test/fixtures"])
161
- filewatcher.filesystem_updated?.should.be.false
162
- processed = []
163
- thread = Thread.new(filewatcher,processed) do
164
- filewatcher.watch(0.1){|f,e| processed << f }
165
- end
166
- sleep 0.2 # thread needs a chance to start
167
- filewatcher.stop
168
- thread.join
169
- added_files = []
170
- (1..4).each do |n|
171
- added_files << "test/fixtures/file#{n}.txt"
172
- open(added_files.last,"w") { |f| f.puts "content#{n}" }
173
- end
174
- filewatcher.finalize
175
- puts "What is wrong with finalize:"
176
- puts "Expect: #{added_files.inspect}"
177
- puts "Actual: #{processed.inspect}"
178
- # processed.should.satisfy &includes_all(added_files)
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
179
249
  end
180
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
181
305
  end