watchr 0.5.7 → 0.5.8
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.
- data/.gitignore +1 -0
- data/Manifest +1 -1
- data/Rakefile +32 -27
- data/bin/watchr +3 -21
- data/lib/watchr.rb +1 -1
- data/lib/watchr/controller.rb +6 -2
- data/lib/watchr/event_handlers/portable.rb +17 -11
- data/lib/watchr/event_handlers/unix.rb +4 -0
- data/lib/watchr/script.rb +70 -26
- data/specs.watchr +5 -5
- data/test/event_handlers/test_portable.rb +91 -7
- data/test/test_controller.rb +10 -0
- data/test/test_helper.rb +1 -4
- data/test/test_script.rb +55 -15
- data/watchr.gemspec +16 -51
- metadata +5 -11
data/.gitignore
CHANGED
data/Manifest
CHANGED
data/Rakefile
CHANGED
@@ -1,40 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
desc "Generate rdoc documentation."
|
8
|
-
Rake::RDocTask.new(:rdoc => 'rdoc', :clobber_rdoc => 'rdoc:clean', :rerdoc => 'rdoc:force') { |rdoc|
|
9
|
-
rdoc.rdoc_dir = 'doc/rdoc'
|
10
|
-
rdoc.title = "Watchr"
|
11
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
12
|
-
rdoc.options << '--charset' << 'utf-8'
|
13
|
-
rdoc.main = 'README.rdoc'
|
14
|
-
rdoc.rdoc_files.include('README.rdoc')
|
15
|
-
rdoc.rdoc_files.include('TODO.txt')
|
16
|
-
rdoc.rdoc_files.include('LICENSE')
|
17
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
18
|
-
}
|
19
|
-
|
20
|
-
if defined? YARD
|
21
|
-
YARD::Rake::YardocTask.new do |t|
|
22
|
-
t.files = %w( lib/**/*.rb )
|
23
|
-
t.options = %w( -o doc/yard --readme README.rdoc --files LICENSE,TODO.txt )
|
24
|
-
end
|
25
|
-
end
|
1
|
+
# --------------------------------------------------
|
2
|
+
# Tests
|
3
|
+
# --------------------------------------------------
|
4
|
+
task(:default => "test:all")
|
26
5
|
|
27
6
|
namespace(:test) do
|
28
7
|
|
29
8
|
desc "Run all tests"
|
30
9
|
task(:all) do
|
31
10
|
tests = Dir['test/**/test_*.rb'] - ['test/test_helper.rb']
|
32
|
-
cmd = "ruby -rubygems -
|
11
|
+
cmd = "ruby -rubygems -I.:lib -e'%w( #{tests.join(' ')} ).each {|file| require file }'"
|
33
12
|
puts cmd if ENV['VERBOSE']
|
34
13
|
system cmd
|
35
14
|
end
|
36
15
|
|
37
|
-
desc "Run all tests on multiple ruby versions (requires rvm
|
16
|
+
desc "Run all tests on multiple ruby versions (requires rvm)"
|
38
17
|
task(:portability) do
|
39
18
|
versions = %w( 1.8.6 1.8.7 )
|
40
19
|
versions.each do |version|
|
@@ -47,3 +26,29 @@ namespace(:test) do
|
|
47
26
|
end
|
48
27
|
end
|
49
28
|
end
|
29
|
+
|
30
|
+
# --------------------------------------------------
|
31
|
+
# Docs
|
32
|
+
# --------------------------------------------------
|
33
|
+
require 'rake/rdoctask'
|
34
|
+
desc "Generate rdoc documentation."
|
35
|
+
Rake::RDocTask.new(:rdoc => 'rdoc', :clobber_rdoc => 'rdoc:clean', :rerdoc => 'rdoc:force') do |rdoc|
|
36
|
+
rdoc.rdoc_dir = 'doc/rdoc'
|
37
|
+
rdoc.title = "Watchr"
|
38
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
39
|
+
rdoc.options << '--charset' << 'utf-8'
|
40
|
+
rdoc.main = 'README.rdoc'
|
41
|
+
rdoc.rdoc_files.include('README.rdoc')
|
42
|
+
rdoc.rdoc_files.include('TODO.txt')
|
43
|
+
rdoc.rdoc_files.include('LICENSE')
|
44
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Generate YARD Documentation"
|
48
|
+
task(:yardoc) do
|
49
|
+
require 'yard'
|
50
|
+
files = %w( lib/**/*.rb )
|
51
|
+
options = %w( -o doc/yard --readme README.rdoc --files LICENSE )
|
52
|
+
YARD::CLI::Yardoc.run *(options + files)
|
53
|
+
end
|
54
|
+
|
data/bin/watchr
CHANGED
@@ -26,30 +26,12 @@ module Watchr
|
|
26
26
|
# ===== Returns
|
27
27
|
# <Pathname>::
|
28
28
|
# absolute path of first occurence of partial path in load path, or nil if not found
|
29
|
-
|
29
|
+
#--
|
30
|
+
# Adds '.' for ruby1.9.2
|
30
31
|
def find_in_load_path(path)
|
31
|
-
dir =
|
32
|
-
$LOAD_PATH.detect {|p| Pathname(p).join(path).exist? }
|
33
|
-
end
|
32
|
+
dir = (['.'] + $LOAD_PATH).uniq.detect {|p| Pathname(p).join(path).exist? }
|
34
33
|
dir ? path.expand_path(dir) : nil
|
35
34
|
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
# If the block returns nil, requires gem <tt>name</tt> and tries running the
|
40
|
-
# block again. If all fails, returns nil
|
41
|
-
#
|
42
|
-
# ===== Params
|
43
|
-
# name<Pathname,String>:: name of gem to require
|
44
|
-
#
|
45
|
-
# ===== Returns
|
46
|
-
# block's value or nil if gem <tt>name</tt> doesn't exist
|
47
|
-
#
|
48
|
-
def potentially_with_gem(name)
|
49
|
-
yield || (require(name) && yield)
|
50
|
-
rescue LoadError
|
51
|
-
nil
|
52
|
-
end
|
53
35
|
end
|
54
36
|
end
|
55
37
|
|
data/lib/watchr.rb
CHANGED
data/lib/watchr/controller.rb
CHANGED
@@ -21,10 +21,12 @@ module Watchr
|
|
21
21
|
#
|
22
22
|
# ===== Parameters
|
23
23
|
# script<Script>:: The script object
|
24
|
+
# handler<EventHanlder::Base>:: The filesystem event handler
|
24
25
|
#
|
25
26
|
def initialize(script, handler)
|
26
27
|
@script = script
|
27
28
|
@handler = handler
|
29
|
+
|
28
30
|
@handler.add_observer(self)
|
29
31
|
|
30
32
|
Watchr.debug "using %s handler" % handler.class.name
|
@@ -35,18 +37,20 @@ module Watchr
|
|
35
37
|
# Will block control flow until application is explicitly stopped/killed.
|
36
38
|
#
|
37
39
|
def run
|
40
|
+
@script.parse!
|
38
41
|
@handler.listen(monitored_paths)
|
42
|
+
rescue Interrupt
|
39
43
|
end
|
40
44
|
|
41
45
|
# Callback for file events.
|
42
46
|
#
|
43
|
-
# Called while control flow
|
47
|
+
# Called while control flow is in listening loop. It will execute the
|
44
48
|
# file's corresponding action as defined in the script. If the file is the
|
45
49
|
# script itself, it will refresh its state to account for potential changes.
|
46
50
|
#
|
47
51
|
# ===== Parameters
|
48
52
|
# path<Pathname, String>:: path that triggered event
|
49
|
-
#
|
53
|
+
# event_type<Symbol>:: event type
|
50
54
|
#
|
51
55
|
def update(path, event_type = nil)
|
52
56
|
path = Pathname(path).expand_path
|
@@ -3,11 +3,8 @@ module Watchr
|
|
3
3
|
class Portable
|
4
4
|
include Base
|
5
5
|
|
6
|
-
attr_accessor :monitored_paths
|
7
|
-
attr_accessor :reference_mtime
|
8
|
-
|
9
6
|
def initialize
|
10
|
-
@reference_mtime = Time.now
|
7
|
+
@reference_mtime = @reference_atime = @reference_ctime = Time.now
|
11
8
|
end
|
12
9
|
|
13
10
|
# Enters listening loop.
|
@@ -40,15 +37,24 @@ module Watchr
|
|
40
37
|
# ===== Returns
|
41
38
|
# path and type of event if event occured, nil otherwise
|
42
39
|
#
|
40
|
+
#--
|
41
|
+
# OPTIMIZE, REFACTOR
|
42
|
+
# TODO fix/figure out ENOENT error
|
43
43
|
def detect_event
|
44
|
-
|
45
|
-
|
46
|
-
if path.mtime > @reference_mtime
|
47
|
-
@reference_mtime = path.mtime
|
48
|
-
[path, :modified]
|
49
|
-
else
|
50
|
-
nil
|
44
|
+
@monitored_paths.each do |path|
|
45
|
+
return [path, :deleted] unless path.exist?
|
51
46
|
end
|
47
|
+
|
48
|
+
mtime_path = @monitored_paths.max {|a,b| a.mtime <=> b.mtime }
|
49
|
+
atime_path = @monitored_paths.max {|a,b| a.atime <=> b.atime }
|
50
|
+
ctime_path = @monitored_paths.max {|a,b| a.ctime <=> b.ctime }
|
51
|
+
|
52
|
+
if mtime_path.mtime > @reference_mtime then @reference_mtime = mtime_path.mtime; [mtime_path, :modified]
|
53
|
+
elsif atime_path.atime > @reference_atime then @reference_atime = atime_path.atime; [atime_path, :accessed]
|
54
|
+
elsif ctime_path.ctime > @reference_ctime then @reference_ctime = ctime_path.ctime; [ctime_path, :changed ]
|
55
|
+
else; nil; end
|
56
|
+
rescue Errno::ENOENT
|
57
|
+
retry
|
52
58
|
end
|
53
59
|
end
|
54
60
|
end
|
@@ -31,10 +31,14 @@ module Watchr
|
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
|
+
#--
|
35
|
+
# TODO fix/figure out ENOENT error
|
34
36
|
def update_reference_times
|
35
37
|
@reference_atime = pathname.atime
|
36
38
|
@reference_mtime = pathname.mtime
|
37
39
|
@reference_ctime = pathname.ctime
|
40
|
+
rescue Errno::ENOENT
|
41
|
+
retry
|
38
42
|
end
|
39
43
|
|
40
44
|
# Type of latest event.
|
data/lib/watchr/script.rb
CHANGED
@@ -20,23 +20,65 @@ module Watchr
|
|
20
20
|
#
|
21
21
|
Rule = Struct.new(:pattern, :event_type, :action)
|
22
22
|
|
23
|
-
#
|
24
|
-
|
23
|
+
# Script file evaluation context
|
24
|
+
#
|
25
|
+
# Script files are evaluated in the context of an instance of this class so
|
26
|
+
# that they get a clearly defined set of methods to work with. In other
|
27
|
+
# words, it is the user script's API.
|
28
|
+
#
|
29
|
+
class EvalContext #:nodoc:
|
30
|
+
|
31
|
+
def initialize(script)
|
32
|
+
@__script = script
|
33
|
+
end
|
34
|
+
|
35
|
+
# Delegated to Script
|
36
|
+
def default_action(&action)
|
37
|
+
@__script.default_action(&action)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Delegated to Script
|
41
|
+
def watch(*args, &block)
|
42
|
+
@__script.watch(*args, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def reload
|
46
|
+
@__script.parse!
|
47
|
+
end
|
25
48
|
end
|
26
49
|
|
27
|
-
#
|
50
|
+
# EvalContext instance
|
51
|
+
#
|
52
|
+
# ===== Examples
|
53
|
+
# script.ec.watch('pattern') { }
|
54
|
+
# script.ec.rules
|
55
|
+
#
|
56
|
+
attr_reader :ec
|
57
|
+
|
58
|
+
# Defined rules
|
59
|
+
#
|
60
|
+
# ===== Returns
|
61
|
+
# Array[Rule]:: rules defined with #watch calls
|
62
|
+
#
|
63
|
+
attr_reader :rules
|
64
|
+
|
65
|
+
# Default action
|
28
66
|
#
|
29
|
-
#
|
30
|
-
#
|
67
|
+
# ===== Returns
|
68
|
+
# Proc:: action defined with #default_action call
|
69
|
+
#
|
70
|
+
attr_reader :default_action
|
71
|
+
|
72
|
+
# Create a script object for <tt>path</tt>.
|
31
73
|
#
|
32
74
|
# ===== Parameters
|
33
75
|
# path<Pathname>:: the path to the script
|
34
76
|
#
|
35
|
-
def initialize(path)
|
36
|
-
@path
|
77
|
+
def initialize(path = nil)
|
78
|
+
@path = path
|
37
79
|
@rules = []
|
38
80
|
@default_action = lambda {}
|
39
|
-
|
81
|
+
@ec = EvalContext.new(self)
|
40
82
|
end
|
41
83
|
|
42
84
|
# Main script API method. Builds a new rule, binding a pattern to an action.
|
@@ -106,24 +148,32 @@ module Watchr
|
|
106
148
|
# watch( 'TODO.txt' ) { system('rake --silent rdoc') }
|
107
149
|
# watch( 'LICENSE' ) { system('rake --silent rdoc') }
|
108
150
|
#
|
151
|
+
# ===== Returns
|
152
|
+
# Proc:: default action
|
153
|
+
#
|
109
154
|
def default_action(&action)
|
110
|
-
@default_action = action
|
155
|
+
@default_action = action if action
|
156
|
+
@default_action
|
157
|
+
end
|
158
|
+
|
159
|
+
# Reset script state
|
160
|
+
def reset
|
161
|
+
@rules = []
|
162
|
+
@default_action = lambda {}
|
111
163
|
end
|
112
164
|
|
113
165
|
# Eval content of script file.
|
114
166
|
#--
|
115
|
-
# TODO fix
|
167
|
+
# TODO fix/figure out ENOENT error
|
116
168
|
def parse!
|
117
|
-
|
118
|
-
|
169
|
+
return unless @path
|
119
170
|
reset
|
120
|
-
instance_eval(@path.read)
|
121
|
-
|
171
|
+
@ec.instance_eval(@path.read, @path.to_s)
|
122
172
|
rescue Errno::ENOENT
|
123
|
-
# TODO figure out why this is happening. still can't reproduce
|
124
|
-
Watchr.debug('script file "not found". wth')
|
125
173
|
sleep(0.3) #enough?
|
126
|
-
|
174
|
+
retry
|
175
|
+
ensure
|
176
|
+
Watchr.debug('loaded script file %s' % @path.to_s.inspect)
|
127
177
|
end
|
128
178
|
|
129
179
|
# Find an action corresponding to a path and event type. The returned
|
@@ -131,7 +181,7 @@ module Watchr
|
|
131
181
|
# match_data prepopulated.
|
132
182
|
#
|
133
183
|
# ===== Params
|
134
|
-
# path<Pathnane,String>:: Find action that
|
184
|
+
# path<Pathnane,String>:: Find action that corresponds to this path.
|
135
185
|
# event_type<Symbol>:: Find action only if rule's event if of this type.
|
136
186
|
#
|
137
187
|
# ===== Examples
|
@@ -163,10 +213,10 @@ module Watchr
|
|
163
213
|
# Path to the script file
|
164
214
|
#
|
165
215
|
# ===== Returns
|
166
|
-
# path<Pathname>:: path to script file
|
216
|
+
# path<Pathname>:: absolute path to script file
|
167
217
|
#
|
168
218
|
def path
|
169
|
-
Pathname(@path.respond_to?(:to_path) ? @path.to_path : @path.to_s).expand_path
|
219
|
+
@path && Pathname(@path.respond_to?(:to_path) ? @path.to_path : @path.to_s).expand_path
|
170
220
|
end
|
171
221
|
|
172
222
|
private
|
@@ -195,11 +245,5 @@ module Watchr
|
|
195
245
|
def rel_path(path)
|
196
246
|
Pathname(path).expand_path.relative_path_from(Pathname(Dir.pwd))
|
197
247
|
end
|
198
|
-
|
199
|
-
# Reset script state
|
200
|
-
def reset
|
201
|
-
@default_action = lambda {}
|
202
|
-
@rules.clear
|
203
|
-
end
|
204
248
|
end
|
205
249
|
end
|
data/specs.watchr
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# $ watchr specs.watchr
|
4
4
|
|
5
5
|
# --------------------------------------------------
|
6
|
-
#
|
6
|
+
# Helpers
|
7
7
|
# --------------------------------------------------
|
8
8
|
def run(cmd)
|
9
9
|
puts(cmd)
|
@@ -18,10 +18,10 @@ end
|
|
18
18
|
# --------------------------------------------------
|
19
19
|
# Watchr Rules
|
20
20
|
# --------------------------------------------------
|
21
|
-
watch( '^test.*/test_.*\.rb' ) { |m| run( "ruby -rubygems %s" % m[0] ) }
|
22
|
-
watch( '^lib/(.*)\.rb' ) { |m| run( "ruby -rubygems test/test_%s.rb" % m[1] ) }
|
23
|
-
watch( '^lib/watchr/(.*)\.rb' ) { |m| run( "ruby -rubygems test/test_%s.rb" % m[1] ) }
|
24
|
-
watch( '^lib/watchr/event_handlers/(.*)\.rb' ) { |m| run( "ruby -rubygems test/event_handlers/test_%s.rb" % m[1] ) }
|
21
|
+
watch( '^test.*/test_.*\.rb' ) { |m| run( "ruby -rubygems -I.:lib %s" % m[0] ) }
|
22
|
+
watch( '^lib/(.*)\.rb' ) { |m| run( "ruby -rubygems -I.:lib test/test_%s.rb" % m[1] ) }
|
23
|
+
watch( '^lib/watchr/(.*)\.rb' ) { |m| run( "ruby -rubygems -I.:lib test/test_%s.rb" % m[1] ) }
|
24
|
+
watch( '^lib/watchr/event_handlers/(.*)\.rb' ) { |m| run( "ruby -rubygems -I.:lib test/event_handlers/test_%s.rb" % m[1] ) }
|
25
25
|
watch( '^test/test_helper\.rb' ) { run_all_tests }
|
26
26
|
|
27
27
|
# --------------------------------------------------
|
@@ -1,5 +1,9 @@
|
|
1
1
|
require 'test/test_helper'
|
2
2
|
|
3
|
+
class Watchr::EventHandler::Portable
|
4
|
+
attr_accessor :monitored_paths
|
5
|
+
end
|
6
|
+
|
3
7
|
class PortableEventHandlerTest < Test::Unit::TestCase
|
4
8
|
include Watchr
|
5
9
|
|
@@ -12,10 +16,13 @@ class PortableEventHandlerTest < Test::Unit::TestCase
|
|
12
16
|
@baz = Pathname('baz').expand_path
|
13
17
|
@bax = Pathname('bax').expand_path
|
14
18
|
|
15
|
-
@
|
16
|
-
@bar.
|
17
|
-
|
18
|
-
|
19
|
+
@now = Time.now
|
20
|
+
[@foo, @bar, @baz, @bax].each do |path|
|
21
|
+
path.stubs(:mtime ).returns(@now - 100)
|
22
|
+
path.stubs(:atime ).returns(@now - 100)
|
23
|
+
path.stubs(:ctime ).returns(@now - 100)
|
24
|
+
path.stubs(:exist?).returns(true)
|
25
|
+
end
|
19
26
|
end
|
20
27
|
|
21
28
|
test "triggers listening state" do
|
@@ -31,15 +38,80 @@ class PortableEventHandlerTest < Test::Unit::TestCase
|
|
31
38
|
@handler.monitored_paths.should include(@bar)
|
32
39
|
end
|
33
40
|
|
34
|
-
test "
|
35
|
-
|
41
|
+
test "doesn't trigger on start" do
|
42
|
+
end
|
43
|
+
|
44
|
+
## event types
|
45
|
+
|
46
|
+
test "deleted file event" do
|
47
|
+
@foo.stubs(:exist?).returns(false)
|
48
|
+
|
49
|
+
@handler.listen [ @foo, @bar ]
|
50
|
+
@handler.expects(:notify).with(@foo, :deleted)
|
51
|
+
@handler.trigger
|
52
|
+
end
|
53
|
+
|
54
|
+
test "modified file event" do
|
55
|
+
@foo.stubs(:mtime).returns(@now + 100)
|
36
56
|
|
37
57
|
@handler.listen [ @foo, @bar ]
|
38
58
|
@handler.expects(:notify).with(@foo, :modified)
|
39
59
|
@handler.trigger
|
40
60
|
end
|
41
61
|
|
42
|
-
test "
|
62
|
+
test "accessed file event" do
|
63
|
+
@foo.stubs(:atime).returns(@now + 100)
|
64
|
+
|
65
|
+
@handler.listen [ @foo, @bar ]
|
66
|
+
@handler.expects(:notify).with(@foo, :accessed)
|
67
|
+
@handler.trigger
|
68
|
+
end
|
69
|
+
|
70
|
+
test "changed file event" do
|
71
|
+
@foo.stubs(:ctime).returns(@now + 100)
|
72
|
+
|
73
|
+
@handler.listen [ @foo, @bar ]
|
74
|
+
@handler.expects(:notify).with(@foo, :changed)
|
75
|
+
@handler.trigger
|
76
|
+
end
|
77
|
+
|
78
|
+
## event type priorities
|
79
|
+
|
80
|
+
test "mtime > atime" do
|
81
|
+
@foo.stubs(:mtime).returns(@now + 100)
|
82
|
+
@foo.stubs(:atime).returns(@now + 100)
|
83
|
+
@foo.stubs(:ctime).returns(@now + 100)
|
84
|
+
|
85
|
+
@handler.listen [ @foo, @bar ]
|
86
|
+
@handler.expects(:notify).with(@foo, :modified)
|
87
|
+
@handler.trigger
|
88
|
+
end
|
89
|
+
|
90
|
+
test "mtime > ctime" do
|
91
|
+
@foo.stubs(:mtime).returns(@now + 100)
|
92
|
+
@foo.stubs(:ctime).returns(@now + 100)
|
93
|
+
|
94
|
+
@handler.listen [ @foo, @bar ]
|
95
|
+
@handler.expects(:notify).with(@foo, :modified)
|
96
|
+
@handler.trigger
|
97
|
+
end
|
98
|
+
|
99
|
+
test "atime > ctime" do
|
100
|
+
@foo.stubs(:atime).returns(@now + 100)
|
101
|
+
@foo.stubs(:ctime).returns(@now + 100)
|
102
|
+
|
103
|
+
@handler.listen [ @foo, @bar ]
|
104
|
+
@handler.expects(:notify).with(@foo, :accessed)
|
105
|
+
@handler.trigger
|
106
|
+
end
|
107
|
+
|
108
|
+
test "deleted > mtime" do
|
109
|
+
@foo.stubs(:exist?).returns(false)
|
110
|
+
@foo.stubs(:mtime ).returns(@now + 100)
|
111
|
+
|
112
|
+
@handler.listen [ @foo, @bar ]
|
113
|
+
@handler.expects(:notify).with(@foo, :deleted)
|
114
|
+
@handler.trigger
|
43
115
|
end
|
44
116
|
|
45
117
|
## on the fly updates of monitored files list
|
@@ -55,4 +127,16 @@ class PortableEventHandlerTest < Test::Unit::TestCase
|
|
55
127
|
@handler.monitored_paths.should exclude(@foo)
|
56
128
|
@handler.monitored_paths.should exclude(@bar)
|
57
129
|
end
|
130
|
+
|
131
|
+
test "retries on ENOENT errors" do
|
132
|
+
@oops = Pathname('oops').expand_path
|
133
|
+
@oops.stubs(:exist?).returns(true)
|
134
|
+
@oops.stubs(:mtime).raises(Errno::ENOENT).
|
135
|
+
then.returns(Time.now + 100)
|
136
|
+
|
137
|
+
@handler.listen [ @oops ]
|
138
|
+
|
139
|
+
@handler.expects(:notify).with(@oops, :modified)
|
140
|
+
@handler.trigger
|
141
|
+
end
|
58
142
|
end
|
data/test/test_controller.rb
CHANGED
@@ -27,6 +27,11 @@ class TestController < Test::Unit::TestCase
|
|
27
27
|
@controller.run
|
28
28
|
end
|
29
29
|
|
30
|
+
test "parses the script on #run" do
|
31
|
+
@script.expects(:parse!)
|
32
|
+
@controller.run
|
33
|
+
end
|
34
|
+
|
30
35
|
test "adds itself as handler observer" do
|
31
36
|
@handler.count_observers.should be(1)
|
32
37
|
@handler.delete_observer(@controller)
|
@@ -99,5 +104,10 @@ class TestController < Test::Unit::TestCase
|
|
99
104
|
@handler.expects(:refresh).with %w( foo bar )
|
100
105
|
@controller.update(path)
|
101
106
|
end
|
107
|
+
|
108
|
+
test "exits gracefully when Interrupted" do
|
109
|
+
@handler.stubs(:listen).raises(Interrupt)
|
110
|
+
@controller.run
|
111
|
+
end
|
102
112
|
end
|
103
113
|
|
data/test/test_helper.rb
CHANGED
data/test/test_script.rb
CHANGED
@@ -4,20 +4,33 @@ class TestScript < Test::Unit::TestCase
|
|
4
4
|
include Watchr
|
5
5
|
|
6
6
|
def setup
|
7
|
-
|
8
|
-
@script = Script.new( Pathname.new( tmpfile.path ) )
|
7
|
+
@script = Script.new
|
9
8
|
end
|
10
9
|
|
11
10
|
## external api
|
12
11
|
|
13
12
|
test "watch" do
|
14
|
-
@script.watch('pattern')
|
15
|
-
@script.watch('pattern', :event_type)
|
16
|
-
@script.watch('pattern') { nil }
|
13
|
+
@script.ec.watch('pattern')
|
14
|
+
@script.ec.watch('pattern', :event_type)
|
15
|
+
@script.ec.watch('pattern') { nil }
|
17
16
|
end
|
18
17
|
|
19
18
|
test "default action" do
|
20
|
-
@script.default_action { nil }
|
19
|
+
@script.ec.default_action { nil }
|
20
|
+
end
|
21
|
+
|
22
|
+
test "reload" do
|
23
|
+
@script.ec.reload
|
24
|
+
end
|
25
|
+
|
26
|
+
test "eval context delegates methods to script" do
|
27
|
+
@script.ec.watch('pattern')
|
28
|
+
@script.ec.watch('pattern', :event_type)
|
29
|
+
@script.ec.watch('pattern') { nil }
|
30
|
+
@script.ec.default_action { :foo }
|
31
|
+
|
32
|
+
@script.rules.size.should be(3)
|
33
|
+
@script.default_action.call.should be(:foo)
|
21
34
|
end
|
22
35
|
|
23
36
|
## functionality
|
@@ -65,26 +78,48 @@ class TestScript < Test::Unit::TestCase
|
|
65
78
|
end
|
66
79
|
|
67
80
|
test "parses script file" do
|
68
|
-
|
69
|
-
|
81
|
+
path = Pathname( Tempfile.open('bar').path )
|
82
|
+
path.open('w') {|f| f.write <<-STR }
|
70
83
|
watch( 'abc' ) { :x }
|
71
84
|
STR
|
72
|
-
script = Script.new(
|
85
|
+
script = Script.new(path)
|
86
|
+
script.parse!
|
73
87
|
script.action_for('abc').call.should be(:x)
|
74
88
|
end
|
75
89
|
|
90
|
+
test "__FILE__ is set properly in script file" do
|
91
|
+
path = Pathname( Tempfile.open('bar').path )
|
92
|
+
path.open('w') {|f| f.write <<-STR }
|
93
|
+
throw __FILE__.to_sym
|
94
|
+
STR
|
95
|
+
script = Script.new(path)
|
96
|
+
lambda { script.parse! }.should throw_symbol(path.to_s.to_sym)
|
97
|
+
end
|
98
|
+
|
99
|
+
test "reloads script file" do
|
100
|
+
@script.expects(:parse!)
|
101
|
+
@script.ec.reload
|
102
|
+
end
|
103
|
+
|
104
|
+
test "skips parsing on nil script file" do
|
105
|
+
script = Script.new
|
106
|
+
script.ec.stubs(:instance_eval).raises(Exception) #negative expectation hack
|
107
|
+
script.parse!
|
108
|
+
end
|
109
|
+
|
76
110
|
test "resets state" do
|
77
111
|
@script.default_action { 'x' }
|
78
112
|
@script.watch('foo') { 'bar' }
|
79
|
-
@script.
|
80
|
-
@script.
|
81
|
-
@script.
|
113
|
+
@script.reset
|
114
|
+
@script.default_action.call.should be(nil)
|
115
|
+
@script.rules.should be([])
|
82
116
|
end
|
83
117
|
|
84
118
|
test "resets state on parse" do
|
85
|
-
|
86
|
-
|
87
|
-
|
119
|
+
script = Script.new( Pathname( Tempfile.new('foo').path ) )
|
120
|
+
script.stubs(:instance_eval)
|
121
|
+
script.expects(:reset)
|
122
|
+
script.parse!
|
88
123
|
end
|
89
124
|
|
90
125
|
test "actions receive a MatchData object" do
|
@@ -108,6 +143,11 @@ class TestScript < Test::Unit::TestCase
|
|
108
143
|
script.path.should be(path)
|
109
144
|
end
|
110
145
|
|
146
|
+
test "nil file path" do
|
147
|
+
script = Script.new
|
148
|
+
script.path.should be(nil)
|
149
|
+
end
|
150
|
+
|
111
151
|
test "later rules take precedence" do
|
112
152
|
@script.watch('a/(.*)\.x') { :x }
|
113
153
|
@script.watch('a/b/(.*)\.x') { :y }
|
data/watchr.gemspec
CHANGED
@@ -1,56 +1,21 @@
|
|
1
|
+
require 'lib/watchr'
|
1
2
|
|
2
3
|
Gem::Specification.new do |s|
|
3
|
-
s.name
|
4
|
-
s.
|
5
|
-
s.
|
6
|
-
s.
|
7
|
-
s.
|
8
|
-
s.
|
9
|
-
s.
|
10
|
-
s.has_rdoc
|
11
|
-
s.rdoc_options
|
12
|
-
s.extra_rdoc_files
|
13
|
-
s.require_path
|
14
|
-
s.bindir
|
15
|
-
s.executables
|
16
|
-
s.
|
17
|
-
|
18
|
-
History.txt
|
19
|
-
LICENSE
|
20
|
-
Manifest
|
21
|
-
README.rdoc
|
22
|
-
Rakefile
|
23
|
-
TODO.txt
|
24
|
-
bin/watchr
|
25
|
-
docs.watchr
|
26
|
-
gem.watchr
|
27
|
-
lib/watchr.rb
|
28
|
-
lib/watchr/controller.rb
|
29
|
-
lib/watchr/event_handlers/base.rb
|
30
|
-
lib/watchr/event_handlers/portable.rb
|
31
|
-
lib/watchr/event_handlers/unix.rb
|
32
|
-
lib/watchr/script.rb
|
33
|
-
manifest.watchr
|
34
|
-
specs.watchr
|
35
|
-
test/README
|
36
|
-
test/event_handlers/test_base.rb
|
37
|
-
test/event_handlers/test_portable.rb
|
38
|
-
test/event_handlers/test_unix.rb
|
39
|
-
test/test_controller.rb
|
40
|
-
test/test_helper.rb
|
41
|
-
test/test_script.rb
|
42
|
-
test/test_watchr.rb
|
43
|
-
watchr.gemspec
|
44
|
-
]
|
45
|
-
s.test_files = %w[
|
46
|
-
test/test_helper.rb
|
47
|
-
test/test_watchr.rb
|
48
|
-
test/test_script.rb
|
49
|
-
test/test_controller.rb
|
50
|
-
test/event_handlers/test_base.rb
|
51
|
-
test/event_handlers/test_unix.rb
|
52
|
-
test/event_handlers/test_portable.rb
|
53
|
-
]
|
4
|
+
s.name = "watchr"
|
5
|
+
s.summary = "Modern continious testing (flexible alternative to autotest)"
|
6
|
+
s.description = "Modern continious testing (flexible alternative to autotest)."
|
7
|
+
s.author = "mynyml"
|
8
|
+
s.email = "mynyml@gmail.com"
|
9
|
+
s.homepage = "http://mynyml.com/ruby/flexible-continuous-testing"
|
10
|
+
s.rubyforge_project = "watchr"
|
11
|
+
s.has_rdoc = true
|
12
|
+
s.rdoc_options = %w( --main README.rdoc )
|
13
|
+
s.extra_rdoc_files = %w( README.rdoc )
|
14
|
+
s.require_path = "lib"
|
15
|
+
s.bindir = "bin"
|
16
|
+
s.executables = "watchr"
|
17
|
+
s.version = Watchr::VERSION
|
18
|
+
s.files = File.read("Manifest").strip.split("\n")
|
54
19
|
|
55
20
|
s.add_development_dependency 'mocha'
|
56
21
|
s.add_development_dependency 'jeremymcanally-matchy'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: watchr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mynyml
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-12 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -122,16 +122,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
122
|
version:
|
123
123
|
requirements: []
|
124
124
|
|
125
|
-
rubyforge_project:
|
125
|
+
rubyforge_project: watchr
|
126
126
|
rubygems_version: 1.3.5
|
127
127
|
signing_key:
|
128
128
|
specification_version: 3
|
129
129
|
summary: Modern continious testing (flexible alternative to autotest)
|
130
|
-
test_files:
|
131
|
-
|
132
|
-
- test/test_watchr.rb
|
133
|
-
- test/test_script.rb
|
134
|
-
- test/test_controller.rb
|
135
|
-
- test/event_handlers/test_base.rb
|
136
|
-
- test/event_handlers/test_unix.rb
|
137
|
-
- test/event_handlers/test_portable.rb
|
130
|
+
test_files: []
|
131
|
+
|