mynyml-watchr 0.3.0 → 0.5.2

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/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