observables 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/test/test_base.rb CHANGED
@@ -1,127 +1,127 @@
1
- require 'test_helper'
2
-
3
- class TestBase < Test::Unit::TestCase
4
-
5
- context "An instance of a class that include Observables:Base" do
6
- setup do
7
- @obs = Class.new{include Observables::Base}.new
8
- end
9
-
10
- should "have a notifier" do
11
- assert @obs.notifier.is_a?(ActiveSupport::Notifications::Fanout)
12
- end
13
-
14
- should "allow subscriptions with just a block" do
15
- assert @obs.subscribe{}.is_a?(ActiveSupport::Notifications::Fanout::Subscriber)
16
- end
17
-
18
- should "allow subscriptions with a pattern and a block" do
19
- assert @obs.subscribe(/whatever/){}.is_a?(ActiveSupport::Notifications::Fanout::Subscriber)
20
- end
21
-
22
- should "allow unsubscribing" do
23
- sub = @obs.subscribe(/hi/){}
24
- assert @obs.notifier.listening?("hi")
25
- @obs.unsubscribe(sub)
26
- assert_equal false, @obs.notifier.listening?("hi")
27
- end
28
-
29
- should "publish a before notification prior to executing a change" do
30
- vals = []
31
- x = 0
32
- @obs.subscribe(/before/){|c,a|vals << c << a << x}
33
- @obs.send(:changing,:a_change,:this=>:that){x+=1}
34
- assert_equal :before_a_change, vals[0]
35
- assert_equal @obs.send(:create_event_args,:a_change,:this=>:that),vals[1]
36
- assert_equal 0, vals[2]
37
- assert_equal 1, x
38
- end
39
-
40
- should "publish an after notification after executing a change" do
41
- vals = []
42
- x = 0
43
- @obs.subscribe(/after/){|c,a|vals << c << a << x}
44
- @obs.send(:changing,:a_change,:this=>:that){x+=1}
45
- assert_equal :after_a_change, vals[0]
46
- assert_equal @obs.send(:create_event_args,:a_change,:this=>:that),vals[1]
47
- assert_equal 1, vals[2]
48
- assert_equal 1, x
49
- end
50
-
51
- should "execute a proc passed in as changes to the event args" do
52
- vals = []
53
- @obs.subscribe(/after/){|_,a|vals << a.changes}
54
- @obs.send(:changing, :a_change, :changes=>lambda {[1,2,3]}){1==1}
55
- assert_equal [1,2,3], vals[0]
56
- end
57
-
58
- should "provide method level access to change args" do
59
- vals = []
60
- @obs.subscribe(/after/){|_,a|vals << a.haha}
61
- @obs.send(:changing, :a_change, :haha=>"hoho"){1==1}
62
- assert_equal "hoho", vals[0]
63
- end
64
-
65
- context "Taking ownership of an observable collection" do
66
- setup do
67
- @owner = Class.new do
68
- def child_changed(*args)
69
- @changed_args = args
70
- end
71
- def another_child_changed(*args)
72
- @changed_args = args
73
- end
74
- def changed_args; @changed_args; end
75
- end
76
- @parent = @owner.new
77
- end
78
- should "notify the parent via standard callback method" do
79
- @obs.set_observer @parent
80
- @obs.send(:changing, :a_change){1==1}
81
- assert_equal @obs, @parent.changed_args[0]
82
- end
83
- should "notify the parent via custom callback method when specified" do
84
- @obs.set_observer @parent, :callback_method=>:another_child_changed
85
- @obs.send(:changing, :a_change) {1==1}
86
- assert_equal @obs, @parent.changed_args[0]
87
- end
88
- should "notify the parent via a block if provided" do
89
- changed_args = []
90
- @obs.set_observer(@parent) { |obs,*_| changed_args << obs }
91
- @obs.send(:changing, :a_change) {1==1}
92
- assert_equal @obs, changed_args.pop
93
- end
94
- should "respect a subscription pattern when notifying the parent" do
95
- events = []
96
- @obs.set_observer(@parent, :pattern=>/before/){|_,evt,*_| events << evt}
97
- @obs.send(:changing,:a_change){1==1}
98
- assert_equal 1, events.length
99
- assert_equal :before_a_change, events.pop
100
- end
101
- should "notify the parent via argless block" do
102
- events = []
103
- @obs.set_observer(@parent, :pattern=>/before/){events << 1}
104
- @obs.send(:changing, :a_change){1==1}
105
- assert_equal 1, events.length
106
- end
107
- should "notify via block when no owner is given" do
108
- events = []
109
- my_ary = [1,2,3]
110
- my_ary.make_observable
111
- my_ary.set_observer(:pattern=>/before/){events << 1}
112
- my_ary << 1
113
- assert_equal 1, events.length
114
- end
115
- should "stop notifying the parent after clear_observer is called" do
116
- events = []
117
- @obs.set_observer(@parent){|*args|events << args}
118
- @obs.send(:changing,:a_change){1==1}
119
- assert_equal 2, events.length
120
- @obs.clear_observer
121
- @obs.send(:changing,:a_change){1==1}
122
- assert_equal 2, events.length
123
- end
124
-
125
- end
126
- end
1
+ require 'test_helper'
2
+
3
+ class TestBase < Test::Unit::TestCase
4
+
5
+ context "An instance of a class that include Observables:Base" do
6
+ setup do
7
+ @obs = Class.new{include Observables::Base}.new
8
+ end
9
+
10
+ should "have a notifier" do
11
+ assert @obs.notifier.is_a?(ActiveSupport::Notifications::Fanout)
12
+ end
13
+
14
+ should "allow subscriptions with just a block" do
15
+ assert @obs.subscribe{}.is_a?(ActiveSupport::Notifications::Fanout::Subscriber)
16
+ end
17
+
18
+ should "allow subscriptions with a pattern and a block" do
19
+ assert @obs.subscribe(/whatever/){}.is_a?(ActiveSupport::Notifications::Fanout::Subscriber)
20
+ end
21
+
22
+ should "allow unsubscribing" do
23
+ sub = @obs.subscribe(/hi/){}
24
+ assert @obs.notifier.listening?("hi")
25
+ @obs.unsubscribe(sub)
26
+ assert_equal false, @obs.notifier.listening?("hi")
27
+ end
28
+
29
+ should "publish a before notification prior to executing a change" do
30
+ vals = []
31
+ x = 0
32
+ @obs.subscribe(/before/){|c,a|vals << c << a << x}
33
+ @obs.send(:changing,:a_change,:this=>:that){x+=1}
34
+ assert_equal :before_a_change, vals[0]
35
+ assert_equal @obs.send(:create_event_args,:a_change,:this=>:that),vals[1]
36
+ assert_equal 0, vals[2]
37
+ assert_equal 1, x
38
+ end
39
+
40
+ should "publish an after notification after executing a change" do
41
+ vals = []
42
+ x = 0
43
+ @obs.subscribe(/after/){|c,a|vals << c << a << x}
44
+ @obs.send(:changing,:a_change,:this=>:that){x+=1}
45
+ assert_equal :after_a_change, vals[0]
46
+ assert_equal @obs.send(:create_event_args,:a_change,:this=>:that),vals[1]
47
+ assert_equal 1, vals[2]
48
+ assert_equal 1, x
49
+ end
50
+
51
+ should "execute a proc passed in as changes to the event args" do
52
+ vals = []
53
+ @obs.subscribe(/after/){|_,a|vals << a.changes}
54
+ @obs.send(:changing, :a_change, :changes=>lambda {[1,2,3]}){1==1}
55
+ assert_equal [1,2,3], vals[0]
56
+ end
57
+
58
+ should "provide method level access to change args" do
59
+ vals = []
60
+ @obs.subscribe(/after/){|_,a|vals << a.haha}
61
+ @obs.send(:changing, :a_change, :haha=>"hoho"){1==1}
62
+ assert_equal "hoho", vals[0]
63
+ end
64
+
65
+ context "Taking ownership of an observable collection" do
66
+ setup do
67
+ @owner = Class.new do
68
+ def child_changed(*args)
69
+ @changed_args = args
70
+ end
71
+ def another_child_changed(*args)
72
+ @changed_args = args
73
+ end
74
+ def changed_args; @changed_args; end
75
+ end
76
+ @parent = @owner.new
77
+ end
78
+ should "notify the parent via standard callback method" do
79
+ @obs.set_observer @parent
80
+ @obs.send(:changing, :a_change){1==1}
81
+ assert_equal @obs, @parent.changed_args[0]
82
+ end
83
+ should "notify the parent via custom callback method when specified" do
84
+ @obs.set_observer @parent, :callback_method=>:another_child_changed
85
+ @obs.send(:changing, :a_change) {1==1}
86
+ assert_equal @obs, @parent.changed_args[0]
87
+ end
88
+ should "notify the parent via a block if provided" do
89
+ changed_args = []
90
+ @obs.set_observer(@parent) { |obs,*_| changed_args << obs }
91
+ @obs.send(:changing, :a_change) {1==1}
92
+ assert_equal @obs, changed_args.pop
93
+ end
94
+ should "respect a subscription pattern when notifying the parent" do
95
+ events = []
96
+ @obs.set_observer(@parent, :pattern=>/before/){|_,evt,*_| events << evt}
97
+ @obs.send(:changing,:a_change){1==1}
98
+ assert_equal 1, events.length
99
+ assert_equal :before_a_change, events.pop
100
+ end
101
+ should "notify the parent via argless block" do
102
+ events = []
103
+ @obs.set_observer(@parent, :pattern=>/before/){events << 1}
104
+ @obs.send(:changing, :a_change){1==1}
105
+ assert_equal 1, events.length
106
+ end
107
+ should "notify via block when no owner is given" do
108
+ events = []
109
+ my_ary = [1,2,3]
110
+ my_ary.make_observable
111
+ my_ary.set_observer(:pattern=>/before/){events << 1}
112
+ my_ary << 1
113
+ assert_equal 1, events.length
114
+ end
115
+ should "stop notifying the parent after clear_observer is called" do
116
+ events = []
117
+ @obs.set_observer(@parent){|*args|events << args}
118
+ @obs.send(:changing,:a_change){1==1}
119
+ assert_equal 2, events.length
120
+ @obs.clear_observer
121
+ @obs.send(:changing,:a_change){1==1}
122
+ assert_equal 2, events.length
123
+ end
124
+
125
+ end
126
+ end
127
127
  end
@@ -1,88 +1,88 @@
1
- require "test_helper"
2
-
3
- class TestHashWatcher < Test::Unit::TestCase
4
- context "A hash which has included Observables::HashWatcher" do
5
- setup do
6
- @hash = {:a=>1,:b=>2,:c=>"3"}.tap do |h|
7
- class << h
8
- include Observables::HashWatcher
9
- end
10
- end
11
- end
12
-
13
- should "notify observers of any change that modifies elements" do
14
- before_methods, after_methods = [],[]
15
- method_list = Observables::HashWatcher::MODIFIER_METHODS
16
- @hash.subscribe(/before_modified/){|_,args|before_methods<<args[:trigger]}
17
- @hash.subscribe(/after_modified/) {|_,args|after_methods<<args[:trigger]}
18
- method_list.each do |method|
19
- args = args_for(method)
20
- args ? @hash.send(method,args) : @hash.send(method)
21
- end
22
- assert_equal method_list, before_methods
23
- assert_equal method_list, after_methods
24
- end
25
-
26
- should "notify observers of any change that removes elements" do
27
- before_methods, after_methods = [],[]
28
- method_list = Observables::HashWatcher::REMOVE_METHODS
29
- @hash.subscribe(/before_removed/){|_,args|before_methods<<args[:trigger]}
30
- @hash.subscribe(/after_removed/) {|_,args|after_methods<<args[:trigger]}
31
- method_list.each do |method|
32
- args = args_for(method)
33
- args ? @hash.send(method,*args) : @hash.send(method)
34
- end
35
- assert_equal method_list, before_methods
36
- assert_equal method_list, after_methods
37
- end
38
-
39
- context "Calling #changes on the event args" do
40
- should "calculate changes for #[]= as an addition" do
41
- assert_equal [[:f,9]],get_changes(@hash){ @hash[:f] = 9}[:added]
42
- end
43
- should "calculate changes for #[]= as a modification" do
44
- assert_equal({:removed=>[[:a,1]],:added=>[[:a,9]]}, get_changes(@hash){@hash[:a]=9})
45
- end
46
- should "calculate changes for #replace" do
47
- assert_equal({:removed=>@hash.dup.to_a,:added=>{:t=>9,:u=>10}.to_a},get_changes(@hash){@hash.replace(:t=>9,:u=>10)})
48
- end
49
- should "calculate changes for #merge!, #update" do
50
- [:merge!, :update].each do |method|
51
- hash = @hash.dup
52
- assert_equal({:removed=>{:c=>"3"}.to_a, :added=>{:c=>"4",:d=>5}.to_a},get_changes(hash){hash.send(method,{:c=>"4",:d=>5})})
53
- end
54
- end
55
- should "calculate changes for #clear" do
56
- assert_equal @hash.to_a, get_changes(@hash){@hash.clear}[:removed]
57
- end
58
- should "calculate changes for #delete" do
59
- assert_equal({:a=>1}.to_a, get_changes(@hash){@hash.delete(:a)}[:removed])
60
- end
61
- should "calculate changes for #delete_if, #reject!" do
62
- [:delete_if,:reject!].each do |method|
63
- hash = @hash.dup
64
- assert_equal({:a=>1,:c=>"3"}.to_a,get_changes(hash){hash.send(method){|k,v|[:a,:c].include?(k)}}[:removed])
65
- end
66
- end
67
- should "calculate changes for #shift" do
68
- assert_equal(@hash.dup.shift,get_changes(@hash){@hash.shift}[:removed])
69
- end
70
- end
71
- end
72
-
73
- def args_for(method)
74
- case method
75
- when :replace, :merge!, :update then {:e=>5}
76
- when :delete then :a
77
- else nil
78
- end
79
- end
80
-
81
- def get_changes(hash)
82
- changes = []
83
- sub = hash.subscribe(/after/){|_,args|changes << args.changes}
84
- yield
85
- hash.unsubscribe(sub)
86
- changes.pop
87
- end
88
- end
1
+ require "test_helper"
2
+
3
+ class TestHashWatcher < Test::Unit::TestCase
4
+ context "A hash which has included Observables::HashWatcher" do
5
+ setup do
6
+ @hash = {:a=>1,:b=>2,:c=>"3"}.tap do |h|
7
+ class << h
8
+ include Observables::HashWatcher
9
+ end
10
+ end
11
+ end
12
+
13
+ should "notify observers of any change that modifies elements" do
14
+ before_methods, after_methods = [],[]
15
+ method_list = Observables::HashWatcher::MODIFIER_METHODS
16
+ @hash.subscribe(/before_modified/){|_,args|before_methods<<args[:trigger]}
17
+ @hash.subscribe(/after_modified/){|_,args|after_methods<<args[:trigger]}
18
+ method_list.each do |method|
19
+ args = args_for(method)
20
+ args ? @hash.send(method,args) : @hash.send(method)
21
+ end
22
+ assert_equal method_list, before_methods
23
+ assert_equal method_list, after_methods
24
+ end
25
+
26
+ should "notify observers of any change that removes elements" do
27
+ before_methods, after_methods = [],[]
28
+ method_list = Observables::HashWatcher::REMOVE_METHODS
29
+ @hash.subscribe(/before_removed/){|_,args|before_methods<<args[:trigger]}
30
+ @hash.subscribe(/after_removed/) {|_,args|after_methods<<args[:trigger]}
31
+ method_list.each do |method|
32
+ args = args_for(method)
33
+ args ? @hash.send(method,*args) : @hash.send(method)
34
+ end
35
+ assert_equal method_list, before_methods
36
+ assert_equal method_list, after_methods
37
+ end
38
+
39
+ context "Calling #changes on the event args" do
40
+ should "calculate changes for #[]= as an addition" do
41
+ assert_equal [[:f,9]],get_changes(@hash){ @hash[:f] = 9}[:added]
42
+ end
43
+ should "calculate changes for #[]= as a modification" do
44
+ assert_equal({:removed=>[[:a,1]],:added=>[[:a,9]]}, get_changes(@hash){@hash[:a]=9})
45
+ end
46
+ should "calculate changes for #replace" do
47
+ assert_equal({:removed=>@hash.dup.to_a,:added=>{:t=>9,:u=>10}.to_a},get_changes(@hash){@hash.replace(:t=>9,:u=>10)})
48
+ end
49
+ should "calculate changes for #merge!, #update" do
50
+ [:merge!, :update].each do |method|
51
+ hash = @hash.dup
52
+ assert_equal({:removed=>{:c=>"3"}.to_a, :added=>{:c=>"4",:d=>5}.to_a},get_changes(hash){hash.send(method,{:c=>"4",:d=>5})})
53
+ end
54
+ end
55
+ should "calculate changes for #clear" do
56
+ assert_equal [], @hash.to_a - get_changes(@hash){@hash.clear}[:removed]
57
+ end
58
+ should "calculate changes for #delete" do
59
+ assert_equal({:a=>1}.to_a, get_changes(@hash){@hash.delete(:a)}[:removed])
60
+ end
61
+ should "calculate changes for #delete_if, #reject!" do
62
+ [:delete_if,:reject!].each do |method|
63
+ hash = @hash.dup
64
+ assert_equal({:a=>1,:c=>"3"}.to_a,get_changes(hash){hash.send(method){|k,v|[:a,:c].include?(k)}}[:removed])
65
+ end
66
+ end
67
+ should "calculate changes for #shift" do
68
+ assert_equal(@hash.dup.shift,get_changes(@hash){@hash.shift}[:removed])
69
+ end
70
+ end
71
+ end
72
+
73
+ def args_for(method)
74
+ case method
75
+ when :replace, :merge!, :update then {:e=>5}
76
+ when :delete then :a
77
+ else nil
78
+ end
79
+ end
80
+
81
+ def get_changes(hash)
82
+ changes = []
83
+ sub = hash.subscribe(/after/){|_,args|changes << args.changes}
84
+ yield
85
+ hash.unsubscribe(sub)
86
+ changes.pop
87
+ end
88
+ end
data/test/test_helper.rb CHANGED
@@ -1,13 +1,13 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
-
4
- $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
5
-
6
- require 'observables'
7
-
8
- require 'shoulda'
9
-
10
- class Test::Unit::TestCase
11
-
12
- end
13
-
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
5
+
6
+ require 'observables'
7
+
8
+ require 'shoulda'
9
+
10
+ class Test::Unit::TestCase
11
+
12
+ end
13
+