mynyml-watchr 0.3.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/specs.watchr CHANGED
@@ -2,6 +2,9 @@
2
2
  #
3
3
  # $ watchr specs.watchr
4
4
 
5
+ # --------------------------------------------------
6
+ # Convenience Methods
7
+ # --------------------------------------------------
5
8
  def all_test_files
6
9
  Dir['test/**/test_*.rb'] - ['test/test_helper.rb']
7
10
  end
@@ -12,24 +15,30 @@ def run(cmd)
12
15
  end
13
16
 
14
17
  def run_all_tests
15
- cmd = "ruby -rubygems -I.:lib:test -e'%w( #{all_test_files.join(' ')} ).each {|file| require file }'"
18
+ cmd = "ruby -rubygems -Ilib -e'%w( #{all_test_files.join(' ')} ).each {|file| require file }'"
16
19
  run(cmd)
17
20
  end
18
21
 
19
- watch( 'test/test_.*\.rb' ) {|md| run("ruby -rubygems #{md[0]}") }
20
- watch( 'lib/(.*)\.rb' ) {|md| run("ruby -rubygems test/test_#{md[1]}.rb") }
21
- watch( 'test/test_helper\.rb' ) { run_all_tests }
22
-
23
- # Ctrl-C
24
- Signal.trap('INT') do
25
- puts " RERUNING ALL TESTS (Ctrl-\\ to quit)\n\n"
22
+ # --------------------------------------------------
23
+ # Watchr Rules
24
+ # --------------------------------------------------
25
+ watch( '^test.*/test_.*\.rb' ) { |m| run( "ruby -rubygems %s" % m[0] ) }
26
+ watch( '^lib/(.*)\.rb' ) { |m| run( "ruby -rubygems test/test_%s.rb" % m[1] ) }
27
+ watch( '^lib/watchr/(.*)\.rb' ) { |m| run( "ruby -rubygems test/test_%s.rb" % m[1] ) }
28
+ watch( '^lib/watchr/event_handlers/(.*)\.rb' ) { |m| run( "ruby -rubygems test/event_handlers/test_%s.rb" % m[1] ) }
29
+ watch( '^test/test_helper\.rb' ) { run_all_tests }
30
+
31
+ # --------------------------------------------------
32
+ # Signal Handling
33
+ # --------------------------------------------------
34
+ # Ctrl-\
35
+ Signal.trap('QUIT') do
36
+ puts " --- Running all tests ---\n\n"
26
37
  run_all_tests
27
38
  end
28
39
 
29
- # Ctrl-\
30
- Signal.trap('QUIT') { abort("\n") }
31
-
32
-
40
+ # Ctrl-C
41
+ Signal.trap('INT') { abort("\n") }
33
42
 
34
43
 
35
44
  # vim:ft=ruby
@@ -0,0 +1,24 @@
1
+ require 'test/test_helper'
2
+
3
+ class BaseEventHandlerTest < Test::Unit::TestCase
4
+
5
+ class Handler
6
+ include Watchr::EventHandler::Base
7
+ end
8
+
9
+ def setup
10
+ @handler = Handler.new
11
+ end
12
+
13
+ test "api" do
14
+ @handler.should respond_to(:notify)
15
+ @handler.should respond_to(:listen)
16
+ @handler.should respond_to(:refresh)
17
+ @handler.class.ancestors.should include(Observable)
18
+ end
19
+
20
+ test "notifies observers" do
21
+ @handler.expects(:notify_observers).with('foo/bar', nil)
22
+ @handler.notify('foo/bar', nil)
23
+ end
24
+ end
@@ -0,0 +1,58 @@
1
+ require 'test/test_helper'
2
+
3
+ class UnixEventHandlerTest < Test::Unit::TestCase
4
+ include Watchr
5
+
6
+ def setup
7
+ @handler = EventHandler::Portable.new
8
+ @handler.stubs(:loop)
9
+
10
+ @foo = Pathname('foo').expand_path
11
+ @bar = Pathname('bar').expand_path
12
+ @baz = Pathname('baz').expand_path
13
+ @bax = Pathname('bax').expand_path
14
+
15
+ @foo.stubs(:mtime).returns(Time.now - 100)
16
+ @bar.stubs(:mtime).returns(Time.now - 100)
17
+ @baz.stubs(:mtime).returns(Time.now - 100)
18
+ @bax.stubs(:mtime).returns(Time.now - 100)
19
+ end
20
+
21
+ test "triggers listening state" do
22
+ @handler.expects(:loop)
23
+ @handler.listen([])
24
+ end
25
+
26
+ ## monitoring file events
27
+
28
+ test "listens for events on monitored files" do
29
+ @handler.listen [ @foo, @bar ]
30
+ @handler.monitored_paths.should include(@foo)
31
+ @handler.monitored_paths.should include(@bar)
32
+ end
33
+
34
+ test "notifies observers on file event" do
35
+ @foo.stubs(:mtime).returns(Time.now + 100) # fake event
36
+
37
+ @handler.listen [ @foo, @bar ]
38
+ @handler.expects(:notify).with(@foo, :changed)
39
+ @handler.trigger
40
+ end
41
+
42
+ test "doesn't trigger on start" do
43
+ end
44
+
45
+ ## on the fly updates of monitored files list
46
+
47
+ test "reattaches to new monitored files" do
48
+ @handler.listen [ @foo, @bar ]
49
+ @handler.monitored_paths.should include(@foo)
50
+ @handler.monitored_paths.should include(@bar)
51
+
52
+ @handler.refresh [ @baz, @bax ]
53
+ @handler.monitored_paths.should include(@baz)
54
+ @handler.monitored_paths.should include(@bax)
55
+ @handler.monitored_paths.should exclude(@foo)
56
+ @handler.monitored_paths.should exclude(@bar)
57
+ end
58
+ end
@@ -0,0 +1,56 @@
1
+ require 'test/test_helper'
2
+
3
+ class UnixEventHandlerTest < Test::Unit::TestCase
4
+ include Watchr
5
+
6
+ SingleFileWatcher = EventHandler::Unix::SingleFileWatcher
7
+
8
+ def setup
9
+ @loop = Rev::Loop.default
10
+ @handler = EventHandler::Unix.new
11
+ @loop.stubs(:run)
12
+ end
13
+
14
+ def teardown
15
+ SingleFileWatcher.handler = nil
16
+ Rev::Loop.default.watchers.every.detach
17
+ end
18
+
19
+ test "triggers listening state" do
20
+ @loop.expects(:run)
21
+ @handler.listen([])
22
+ end
23
+
24
+ ## monitoring file events
25
+
26
+ test "listens for events on monitored files" do
27
+ @handler.listen %w( foo bar )
28
+ @loop.watchers.size.should be(2)
29
+ @loop.watchers.every.path.should include('foo', 'bar')
30
+ @loop.watchers.every.class.uniq.should be([SingleFileWatcher])
31
+ end
32
+
33
+ test "notifies observers on file event" do
34
+ watcher = SingleFileWatcher.new('foo/bar')
35
+ watcher.stubs(:path).returns('foo/bar')
36
+
37
+ @handler.expects(:notify).with('foo/bar', :changed)
38
+ watcher.on_change
39
+ end
40
+
41
+ ## on the fly updates of monitored files list
42
+
43
+ test "reattaches to new monitored files" do
44
+ @handler.listen %w( foo bar )
45
+ @loop.watchers.size.should be(2)
46
+ @loop.watchers.every.path.should include('foo')
47
+ @loop.watchers.every.path.should include('bar')
48
+
49
+ @handler.refresh %w( baz bax )
50
+ @loop.watchers.size.should be(2)
51
+ @loop.watchers.every.path.should include('baz')
52
+ @loop.watchers.every.path.should include('bax')
53
+ @loop.watchers.every.path.should exclude('foo')
54
+ @loop.watchers.every.path.should exclude('bar')
55
+ end
56
+ end
@@ -0,0 +1,104 @@
1
+ require 'test/test_helper'
2
+ require 'observer'
3
+
4
+ class MockHandler
5
+ include Observable
6
+ def listen(paths) end
7
+ def refresh(paths) end
8
+ end
9
+
10
+ class TestController < Test::Unit::TestCase
11
+ include Watchr
12
+
13
+ def to_p(str)
14
+ Pathname(str).expand_path
15
+ end
16
+
17
+ def setup
18
+ @script = Script.new
19
+ @handler = MockHandler.new
20
+ @controller = Controller.new(@script, @handler)
21
+ end
22
+
23
+ test "triggers listening state on run" do
24
+ @controller.stubs(:monitored_paths).returns %w( foo bar )
25
+ @handler.expects(:listen).with %w( foo bar )
26
+ @controller.run
27
+ end
28
+
29
+ test "adds itself as handler observer" do
30
+ @handler.count_observers.should be(1)
31
+ @handler.delete_observer(@controller)
32
+ @handler.count_observers.should be(0)
33
+ end
34
+
35
+ ## monitored paths list
36
+
37
+ test "fetches monitored paths" do
38
+ Dir.expects(:[]).at_least_once.with('**/*').returns(%w(
39
+ a
40
+ b/x.z
41
+ b/c
42
+ b/c/y.z
43
+ ))
44
+ script = Script.new
45
+ script.watch('.\.z') { :x }
46
+
47
+ contrl = Controller.new(script, MockHandler.new)
48
+ contrl.monitored_paths.should include(to_p('b/x.z'))
49
+ contrl.monitored_paths.should include(to_p('b/c/y.z'))
50
+ end
51
+
52
+ test "doesn't fetch unmonitored paths" do
53
+ Dir.expects(:[]).at_least_once.with('**/*').returns(%w(
54
+ a
55
+ b/x.z
56
+ b/c
57
+ b/c/y.z
58
+ ))
59
+ script = Script.new
60
+ script.watch('.\.z') { :x }
61
+
62
+ contrl = Controller.new(script, MockHandler.new)
63
+ contrl.monitored_paths.should exclude(to_p('a'))
64
+ contrl.monitored_paths.should exclude(to_p('b/c'))
65
+ contrl.monitored_paths.should exclude(to_p('p/q.z'))
66
+ end
67
+
68
+ test "monitored paths include script" do
69
+ Dir.expects(:[]).at_least_once.with('**/*').returns(%w( a ))
70
+ Script.any_instance.stubs(:parse!)
71
+
72
+ path = to_p('some/file')
73
+ script = Script.new(path)
74
+ contrl = Controller.new(script, MockHandler.new)
75
+ contrl.monitored_paths.should include(path)
76
+ end
77
+
78
+ ## on update
79
+
80
+ test "calls action for path" do
81
+ path = to_p('abc')
82
+ @script.expects(:action_for).with(path).returns(lambda {})
83
+
84
+ @controller.update('abc')
85
+ end
86
+
87
+ test "parses script on script file update" do
88
+ path = to_p('abc')
89
+ @script.stubs(:path).returns(path)
90
+ @script.expects(:parse!)
91
+
92
+ @controller.update('abc')
93
+ end
94
+
95
+ test "refreshes handler on script file update" do
96
+ path = to_p('abc')
97
+ @script.stubs(:path).returns(path)
98
+ @controller.stubs(:monitored_paths).returns %w( foo bar )
99
+
100
+ @handler.expects(:refresh).with %w( foo bar )
101
+ @controller.update('abc')
102
+ end
103
+ end
104
+
data/test/test_helper.rb CHANGED
@@ -6,13 +6,13 @@ require 'every'
6
6
  require 'pending'
7
7
  begin
8
8
  require 'ruby-debug'
9
- require 'phocus'
10
9
  require 'redgreen'
10
+ require 'phocus'
11
11
  rescue LoadError, RuntimeError
12
12
  end
13
13
 
14
- ROOT = Pathname(__FILE__).dirname.parent
15
- $:.unshift(ROOT.join('lib'))
14
+ root = Pathname(__FILE__).dirname.parent.expand_path
15
+ $:.unshift(root.join('lib').to_s).uniq!
16
16
 
17
17
  require 'watchr'
18
18
 
@@ -23,45 +23,28 @@ class Test::Unit::TestCase
23
23
  define_method(name, &block)
24
24
  end
25
25
  alias :should :test
26
- end
27
- end
28
26
 
29
- class Pathname
30
- def rel
31
- self.relative_path_from(ROOT).to_s
32
- end
33
- def pattern
34
- Regexp.escape(self.rel)
35
- end
36
- def touch(time = Time.now)
37
- `touch -mt #{time.strftime('%Y%m%d%H%M.%S')} #{self.expand_path.to_s}`
38
- self
39
- end
40
- def mtime=(t)
41
- self.touch(t).mtime
27
+ # noop
28
+ def xtest(*args) end
42
29
  end
43
30
  end
44
31
 
45
- class Fixture
46
- DIR = Pathname(__FILE__).dirname.join('fixtures')
32
+ # taken from minitest/unit.rb
33
+ # (with modifications)
34
+ def capture_io
35
+ require 'stringio'
47
36
 
48
- class << self
49
- attr_accessor :files
37
+ orig_stdout, orig_stderr = $stdout, $stderr
38
+ captured_stdout, captured_stderr = StringIO.new, StringIO.new
39
+ $stdout, $stderr = captured_stdout, captured_stderr
50
40
 
51
- def create(name=nil, content=nil)
52
- name ||= 'a.rb'
53
- file = DIR.join(name)
54
- self.files ||= []
55
- self.files << file
56
- file.open('w+') {|f| f << (content || "fixture\n") }
57
- file
58
- end
41
+ yield
59
42
 
60
- def delete_all
61
- DIR.entries.each do |fixture|
62
- next if %w( .. . ).include?(fixture.to_s)
63
- DIR.join(fixture.to_s).expand_path.delete
64
- end
65
- end
66
- end
43
+ return Struct.new(:stdout, :stderr).new(
44
+ captured_stdout.string,
45
+ captured_stderr.string
46
+ )
47
+ ensure
48
+ $stdout = orig_stdout
49
+ $stderr = orig_stderr
67
50
  end
@@ -0,0 +1,88 @@
1
+ require 'test/test_helper'
2
+
3
+ class TestScript < Test::Unit::TestCase
4
+ include Watchr
5
+
6
+ ## external api
7
+
8
+ test "watch" do
9
+ Script.new.watch('pattern')
10
+ Script.new.watch('pattern') { nil }
11
+ end
12
+
13
+ test "default action" do
14
+ Script.new.default_action { nil }
15
+ end
16
+
17
+ ## functionality
18
+
19
+ test "rule object" do
20
+ rule = Script.new.watch('pattern') { nil }
21
+ rule.pattern.should be('pattern')
22
+ rule.action.call.should be(nil)
23
+ end
24
+
25
+ test "finds action for path" do
26
+ script = Script.new
27
+ script.watch('abc') { :x }
28
+ script.watch('def') { :y }
29
+ script.action_for('abc').call.should be(:x)
30
+ end
31
+
32
+ test "collects patterns" do
33
+ script = Script.new
34
+ script.watch('abc')
35
+ script.watch('def')
36
+ script.patterns.should include('abc')
37
+ script.patterns.should include('def')
38
+ end
39
+
40
+ test "parses script file" do
41
+ file = StringIO.new(<<-STR)
42
+ watch( 'abc' ) { :x }
43
+ STR
44
+ script = Script.new(file)
45
+ script.action_for('abc').call.should be(:x)
46
+ end
47
+
48
+ test "actions receive a MatchData object" do
49
+ script = Script.new
50
+ script.watch('de(.)') {|m| [m[0], m[1]] }
51
+ script.action_for('def').call.should be(%w( def f ))
52
+ end
53
+
54
+ test "rule's default action" do
55
+ script = Script.new
56
+
57
+ script.watch('abc')
58
+ script.action_for('abc').call.should be(nil)
59
+ script.default_action { :x }
60
+
61
+ script.watch('def')
62
+ script.action_for('def').call.should be(:x)
63
+ end
64
+
65
+ test "file path" do
66
+ Script.any_instance.stubs(:parse!)
67
+ path = Pathname('some/file').expand_path
68
+ script = Script.new(path)
69
+ script.path.should be(path)
70
+ end
71
+
72
+ test "later rules take precedence" do
73
+ script = Script.new
74
+
75
+ script.watch('a/(.*)\.x') { :x }
76
+ script.watch('a/b/(.*)\.x') { :y }
77
+
78
+ script.action_for('a/b/c.x').call.should be(:y)
79
+ end
80
+
81
+ test "rule patterns match against paths relative to pwd" do
82
+ script = Script.new
83
+
84
+ script.watch('^abc') { :x }
85
+ path = Pathname(Dir.pwd) + 'abc'
86
+ script.action_for(path).call.should be(:x)
87
+ end
88
+ end