unobservable 0.8.0 → 0.10.1

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.0
1
+ 0.10.1
data/lib/unobservable.rb CHANGED
@@ -53,22 +53,33 @@ module Unobservable
53
53
  private
54
54
 
55
55
 
56
- # This helper method is similar to attr_reader and attr_accessor. It allows
57
- # for instance events to be declared inside the body of the class.
58
- def attr_event(*names)
59
- @unobservable_instance_events ||= Set.new
56
+ def define_event(name, args = {})
57
+ args = {:create_method => true}.merge(args)
58
+ name = name.to_sym
60
59
 
61
- names.each do |n|
62
- define_method n do
63
- return event(n)
60
+ if args[:create_method]
61
+ define_method name do
62
+ return event(name)
64
63
  end
65
- @unobservable_instance_events.add(n.to_sym)
66
64
  end
67
65
 
68
- return @unobservable_instance_events.to_a
66
+ @unobservable_instance_events ||= Set.new
67
+ if @unobservable_instance_events.include? name
68
+ return false
69
+ else
70
+ @unobservable_instance_events.add name
71
+ return true
72
+ end
69
73
  end
70
74
 
71
- alias :define_event :attr_event
75
+
76
+ # This helper method is similar to attr_reader and attr_accessor. It allows
77
+ # for instance events to be declared inside the body of the class.
78
+ def attr_event(*names)
79
+ args = (names[-1].is_a? Hash) ? names.pop : {}
80
+ names.each {|n| define_event(n, args) }
81
+ return nil
82
+ end
72
83
 
73
84
  end
74
85
 
@@ -105,8 +116,8 @@ module Unobservable
105
116
  end
106
117
 
107
118
  # Defines an event directly on the object.
108
- def define_singleton_event(*name)
109
- self.singleton_class.send(:attr_event, *name)
119
+ def define_singleton_event(name, args = {})
120
+ self.singleton_class.send(:define_event, name, args)
110
121
  end
111
122
 
112
123
  # Obtains the names of the events that are supported by this object. If
@@ -185,6 +196,8 @@ module Unobservable
185
196
  @handlers << h
186
197
  return h
187
198
  end
199
+
200
+ alias :add :register
188
201
 
189
202
 
190
203
  # Removes a single instance of the specified event handler
@@ -203,6 +216,8 @@ module Unobservable
203
216
  end
204
217
 
205
218
 
219
+ alias :delete :unregister
220
+
206
221
 
207
222
  # Pass the specific arguments / block to all of the
208
223
  # event handlers. Return true if there was at least
@@ -0,0 +1,130 @@
1
+ require 'spec_helper'
2
+
3
+ include Unobservable::SpecHelper
4
+
5
+
6
+ shared_examples_for "instance event container" do
7
+
8
+ context "Unobservable::Support is not included" do
9
+ it "does not have any instance events" do
10
+ c = described_class.new
11
+ Unobservable::instance_events_for(c, true).should be_empty
12
+ Unobservable::instance_events_for(c, false).should be_empty
13
+ end
14
+ end
15
+
16
+
17
+ context "Unobservable::Support is included" do
18
+
19
+ let(:mixin_module) do
20
+ module_with_instance_events :one, :two
21
+ end
22
+
23
+ let(:instance_event_container) do
24
+ m = mixin_module
25
+ described_class.new do
26
+ include Unobservable::Support
27
+ include m
28
+
29
+ attr_event :three, :four
30
+ end
31
+ end
32
+
33
+ let(:c){ described_class.new{ include Unobservable::Support } }
34
+
35
+ it "does not have any events by default" do
36
+ c = described_class.new { include Unobservable::Support }
37
+ Unobservable::instance_events_for(c, true).should be_empty
38
+ Unobservable::instance_events_for(c, false).should be_empty
39
+ end
40
+
41
+ it "knows which events have been defined explicitly" do
42
+ events = Unobservable::instance_events_for(instance_event_container, false)
43
+ events.size.should == 2
44
+ events.should include(:three)
45
+ events.should include(:four)
46
+ end
47
+
48
+ it "inherits instance events defined by included Modules" do
49
+ events = Unobservable::instance_events_for(instance_event_container, true)
50
+ events.size.should == 4
51
+ events.should include(:one)
52
+ events.should include(:two)
53
+ events.should include(:three)
54
+ events.should include(:four)
55
+ end
56
+
57
+
58
+ describe "#define_event" do
59
+
60
+ it "returns true if the specified event did not already exist" do
61
+ c.send(:define_event, :quux).should be_true
62
+ end
63
+
64
+ it "returns false if the specified event already existed" do
65
+ c.send(:define_event, :quux)
66
+ c.send(:define_event, :quux).should be_false
67
+ end
68
+
69
+
70
+ it "defines an instance event" do
71
+ c.instance_events.should_not include(:quux)
72
+ c.send(:define_event, :quux)
73
+ c.instance_events.should include(:quux)
74
+ end
75
+
76
+ it "creates a corresponding instance method when :create_method => true" do
77
+ c.instance_methods.should_not include(:quux)
78
+ c.send(:define_event, :quux, :create_method => true)
79
+ c.instance_methods.should include(:quux)
80
+ end
81
+
82
+ it "does not create a corresponding instance method when :create_method => false" do
83
+ c.instance_methods.should_not include(:quux)
84
+ c.send(:define_event, :quux, :create_method => false)
85
+ c.instance_methods.should_not include(:quux)
86
+ end
87
+
88
+ it "creates corresponding instance method by default" do
89
+ c.instance_methods.should_not include(:quux)
90
+ c.send(:define_event, :quux)
91
+ c.instance_methods.should include(:quux)
92
+ end
93
+
94
+ end
95
+
96
+
97
+ describe "#attr_event" do
98
+
99
+ it "defines several events at once" do
100
+ c.instance_events.should_not include(:one, :two, :three)
101
+ c.send(:attr_event, :one, :two, :three)
102
+ c.instance_events.should include(:one, :two, :three)
103
+ end
104
+
105
+ it "creates corresponding instance methods when :create_method => true" do
106
+ c.instance_methods.should_not include(:one, :two, :three)
107
+ c.send(:attr_event, :one, :two, :three, :create_method => true)
108
+ c.instance_methods.should include(:one, :two, :three)
109
+ end
110
+
111
+ it "does not create corresponding instance methods when :create_method => false" do
112
+ c.instance_methods.should_not include(:one, :two, :three)
113
+ c.send(:attr_event, :one, :two, :three, :create_method => false)
114
+ c.instance_methods.should_not include(:one, :two, :three)
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+
123
+
124
+ describe Module do
125
+ it_behaves_like "instance event container"
126
+ end
127
+
128
+ describe Class do
129
+ it_behaves_like "instance event container"
130
+ end
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ include Unobservable::SpecHelper
4
+
5
+ module Unobservable
6
+ describe Support do
7
+ let(:my_class) { class_with_instance_events(:foo, :bar) }
8
+ let(:obj) { my_class.new }
9
+
10
+ context "when included by a module" do
11
+ it "causes the module to extend Unobservable::ModuleSupport" do
12
+ m = Module.new{ include Unobservable::Support }
13
+
14
+ m.should include(Unobservable::Support)
15
+ m.singleton_class.should include(Unobservable::ModuleSupport)
16
+ end
17
+ end
18
+
19
+
20
+ context "when extended by an Object" do
21
+ it "causes the object's singleton class to extend Unobservable::ModuleSupport" do
22
+ x = Object.new
23
+ x.extend Unobservable::Support
24
+
25
+ x.singleton_class.should include(Unobservable::Support)
26
+ x.singleton_class.singleton_class.should include(Unobservable::ModuleSupport)
27
+ end
28
+ end
29
+
30
+
31
+ describe "#define_singleton_event" do
32
+
33
+ it "defines a new singleton event directly on the object" do
34
+ the_singleton_event = :quux
35
+
36
+ obj.class.instance_events.should_not include(the_singleton_event)
37
+ obj.singleton_events(false).should_not include(the_singleton_event)
38
+ expect{ obj.event(the_singleton_event) }.to raise_error
39
+
40
+ expect{ obj.define_singleton_event the_singleton_event }.to change{ obj.singleton_events(false).size }.by(1)
41
+
42
+ obj.class.instance_events.should_not include(the_singleton_event)
43
+ obj.singleton_events(false).should include(the_singleton_event)
44
+ expect{ obj.event(the_singleton_event) }.to_not raise_error
45
+ end
46
+
47
+ it "returns True if the object did not already define the event as a singleton event" do
48
+ obj.define_singleton_event(:foo).should be_true
49
+ end
50
+
51
+ it "returns False if the object already defined the event as a singleton event" do
52
+ obj.define_singleton_event(:foo)
53
+ obj.define_singleton_event(:foo).should be_false
54
+ end
55
+
56
+
57
+ it "creates a corresponding instance method when :create_method => true" do
58
+ obj.methods.should_not include(:quux)
59
+ obj.define_singleton_event :quux, :create_method => true
60
+ obj.methods.should include(:quux)
61
+ end
62
+
63
+ it "does not create a corresponding instance method when :create_method => false" do
64
+ obj.methods.should_not include(:quux)
65
+ obj.define_singleton_event :quux, :create_method => false
66
+ obj.methods.should_not include(:quux)
67
+ end
68
+
69
+ it "creates a corresponding instance method by default" do
70
+ obj.methods.should_not include(:quux)
71
+ obj.define_singleton_event :quux
72
+ obj.methods.should include(:quux)
73
+ end
74
+
75
+ end
76
+
77
+
78
+ describe "#event" do
79
+ it "raises a NameError when the specified event is not defined" do
80
+ expect{ obj.event(:not_exist) }.to raise_error(NameError)
81
+ end
82
+
83
+ it "maps different names to different Event instances" do
84
+ obj.event(:foo).should_not === obj.event(:bar)
85
+ end
86
+
87
+ it "maps the same name to the same Event instance" do
88
+ obj.event(:foo).should === obj.event(:foo)
89
+ obj.event(:bar).should === obj.event(:bar)
90
+ end
91
+
92
+ it "maintains separate Events for each object" do
93
+ x = my_class.new
94
+ y = my_class.new
95
+
96
+ x.event(:foo).should_not === y.event(:foo)
97
+ end
98
+ end
99
+
100
+
101
+ describe "#raise_event" do
102
+
103
+ it "raises a NameError when the specified event is not defined" do
104
+ expect{ obj.send :raise_event, :not_exist }.to raise_error(NameError)
105
+ expect{ obj.send :raise_event, :not_exist, 1, 2, 3 }.to raise_error(NameError)
106
+ end
107
+
108
+ it "calls the specified event" do
109
+ args = [1, 2, 3]
110
+ obj.event(:foo).should_receive(:call).with(*args)
111
+ obj.send :raise_event, :foo, *args
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+ end
118
+
@@ -3,69 +3,6 @@ require 'spec_helper'
3
3
  include Unobservable::SpecHelper
4
4
 
5
5
 
6
- shared_examples_for "instance event container" do
7
-
8
- context "Unobservable::Support is not included" do
9
- it "does not have any instance events" do
10
- c = described_class.new
11
- Unobservable::instance_events_for(c, true).should be_empty
12
- Unobservable::instance_events_for(c, false).should be_empty
13
- end
14
- end
15
-
16
-
17
- context "Unobservable::Support is included" do
18
-
19
- let(:mixin_module) do
20
- module_with_instance_events :one, :two
21
- end
22
-
23
- let(:instance_event_container) do
24
- m = mixin_module
25
- described_class.new do
26
- include Unobservable::Support
27
- include m
28
-
29
- attr_event :three, :four
30
- end
31
- end
32
-
33
- it "does not have any events by default" do
34
- c = described_class.new { include Unobservable::Support }
35
- Unobservable::instance_events_for(c, true).should be_empty
36
- Unobservable::instance_events_for(c, false).should be_empty
37
- end
38
-
39
- it "knows which events have been defined explicitly" do
40
- events = Unobservable::instance_events_for(instance_event_container, false)
41
- events.size.should == 2
42
- events.should include(:three)
43
- events.should include(:four)
44
- end
45
-
46
- it "inherits instance events defined by included Modules" do
47
- events = Unobservable::instance_events_for(instance_event_container, true)
48
- events.size.should == 4
49
- events.should include(:one)
50
- events.should include(:two)
51
- events.should include(:three)
52
- events.should include(:four)
53
- end
54
-
55
- end
56
-
57
- end
58
-
59
-
60
- describe Module do
61
- it_behaves_like "instance event container"
62
- end
63
-
64
- describe Class do
65
- it_behaves_like "instance event container"
66
- end
67
-
68
-
69
6
 
70
7
  describe Unobservable do
71
8
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unobservable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.10.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-10 00:00:00.000000000 Z
12
+ date: 2012-12-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: shoulda
@@ -108,7 +108,9 @@ files:
108
108
  - VERSION
109
109
  - lib/unobservable.rb
110
110
  - spec/event_spec.rb
111
+ - spec/instance_event_container_spec.rb
111
112
  - spec/spec_helper.rb
113
+ - spec/support_spec.rb
112
114
  - spec/unobservable_spec.rb
113
115
  - test/helper.rb
114
116
  - test/test_unobservable.rb
@@ -127,7 +129,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
127
129
  version: '0'
128
130
  segments:
129
131
  - 0
130
- hash: 2686370053034444533
132
+ hash: -1060921785598011427
131
133
  required_rubygems_version: !ruby/object:Gem::Requirement
132
134
  none: false
133
135
  requirements: