hallon 0.11.0 → 0.12.0
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/.yardopts +1 -0
- data/{CHANGELOG → CHANGELOG.md} +82 -27
- data/Gemfile +1 -0
- data/README.markdown +1 -1
- data/Rakefile +8 -6
- data/examples/adding_tracks_to_playlist.rb +3 -0
- data/examples/logging_in.rb +3 -0
- data/examples/playing_audio.rb +130 -0
- data/examples/printing_link_information.rb +3 -0
- data/examples/show_published_playlists_of_user.rb +5 -13
- data/hallon.gemspec +2 -2
- data/lib/hallon.rb +15 -0
- data/lib/hallon/album.rb +1 -1
- data/lib/hallon/album_browse.rb +4 -3
- data/lib/hallon/artist.rb +1 -1
- data/lib/hallon/artist_browse.rb +5 -4
- data/lib/hallon/base.rb +7 -2
- data/lib/hallon/error.rb +1 -1
- data/lib/hallon/ext/spotify.rb +26 -42
- data/lib/hallon/image.rb +7 -8
- data/lib/hallon/observable.rb +134 -62
- data/lib/hallon/observable/album_browse.rb +30 -0
- data/lib/hallon/observable/artist_browse.rb +31 -0
- data/lib/hallon/observable/image.rb +31 -0
- data/lib/hallon/observable/player.rb +13 -0
- data/lib/hallon/observable/playlist.rb +194 -0
- data/lib/hallon/observable/playlist_container.rb +74 -0
- data/lib/hallon/observable/post.rb +30 -0
- data/lib/hallon/observable/search.rb +29 -0
- data/lib/hallon/observable/session.rb +236 -0
- data/lib/hallon/observable/toplist.rb +30 -0
- data/lib/hallon/player.rb +8 -17
- data/lib/hallon/playlist.rb +11 -7
- data/lib/hallon/playlist_container.rb +11 -4
- data/lib/hallon/queue.rb +71 -0
- data/lib/hallon/search.rb +10 -7
- data/lib/hallon/session.rb +18 -21
- data/lib/hallon/toplist.rb +4 -3
- data/lib/hallon/user.rb +5 -5
- data/lib/hallon/version.rb +1 -1
- data/spec/hallon/album_browse_spec.rb +4 -0
- data/spec/hallon/artist_browse_spec.rb +4 -0
- data/spec/hallon/base_spec.rb +26 -9
- data/spec/hallon/hallon_spec.rb +0 -18
- data/spec/hallon/image_spec.rb +0 -1
- data/spec/hallon/link_spec.rb +14 -0
- data/spec/hallon/observable/album_browse_spec.rb +7 -0
- data/spec/hallon/observable/artist_browse_spec.rb +7 -0
- data/spec/hallon/observable/image_spec.rb +8 -0
- data/spec/hallon/observable/playlist_container_spec.rb +21 -0
- data/spec/hallon/observable/playlist_spec.rb +85 -0
- data/spec/hallon/observable/post_spec.rb +8 -0
- data/spec/hallon/observable/search_spec.rb +7 -0
- data/spec/hallon/observable/session_spec.rb +143 -0
- data/spec/hallon/observable/toplist_spec.rb +7 -0
- data/spec/hallon/observable_spec.rb +134 -65
- data/spec/hallon/playlist_container_spec.rb +24 -18
- data/spec/hallon/playlist_spec.rb +2 -0
- data/spec/hallon/queue_spec.rb +35 -0
- data/spec/hallon/session_spec.rb +4 -4
- data/spec/hallon/spotify_spec.rb +35 -9
- data/spec/mockspotify.rb +2 -3
- data/spec/spec_helper.rb +0 -1
- data/spec/support/common_objects.rb +27 -15
- data/spec/support/enumerable_comparison.rb +9 -0
- data/spec/support/shared_for_callbacks.rb +60 -0
- data/spec/support/shared_for_linkable_objects.rb +1 -1
- metadata +56 -20
data/spec/hallon/hallon_spec.rb
CHANGED
@@ -18,22 +18,4 @@ describe Hallon do
|
|
18
18
|
it { should match uri }
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
|
-
describe "object callbacks" do
|
23
|
-
pending <<-REASON
|
24
|
-
|
25
|
-
Once callbacks are implemented in libmockspotify, we should also
|
26
|
-
test them on the following objects:
|
27
|
-
|
28
|
-
- Session
|
29
|
-
- Image
|
30
|
-
- AlbumBrowse
|
31
|
-
- ArtistBrowse
|
32
|
-
- Search
|
33
|
-
- Playlist
|
34
|
-
- PlaylistContainer
|
35
|
-
- Toplist
|
36
|
-
- Inbox
|
37
|
-
REASON
|
38
|
-
end
|
39
21
|
end
|
data/spec/hallon/image_spec.rb
CHANGED
data/spec/hallon/link_spec.rb
CHANGED
@@ -101,4 +101,18 @@ describe Hallon::Link do
|
|
101
101
|
subject.should eq object
|
102
102
|
end
|
103
103
|
end
|
104
|
+
|
105
|
+
describe "#pointer" do
|
106
|
+
it "should raise an error if the expected type is not the same as requested" do
|
107
|
+
expect { Hallon::Link.new("spotify:user:burgestrand:starred").pointer(:profile) }.to raise_error(ArgumentError)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should not raise an error if the expected type is :playlist but real type is starred" do
|
111
|
+
expect { Hallon::Link.new("spotify:user:burgestrand:starred").pointer(:playlist) }.to_not raise_error
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should not raise an error if the expected type and type matches" do
|
115
|
+
expect { Hallon::Link.new("spotify:user:burgestrand").pointer(:profile) }.to_not raise_error
|
116
|
+
end
|
117
|
+
end
|
104
118
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe Hallon::Observable::PlaylistContainer do
|
2
|
+
specification_for_callback "playlist_added" do
|
3
|
+
let(:input) { [a_pointer, mock_playlist_raw, 3, :userdata] }
|
4
|
+
let(:output) { [Hallon::Playlist.new(mock_playlist), 3, subject] }
|
5
|
+
end
|
6
|
+
|
7
|
+
specification_for_callback "playlist_removed" do
|
8
|
+
let(:input) { [a_pointer, mock_playlist_raw, 3, :userdata] }
|
9
|
+
let(:output) { [Hallon::Playlist.new(mock_playlist), 3, subject] }
|
10
|
+
end
|
11
|
+
|
12
|
+
specification_for_callback "playlist_moved" do
|
13
|
+
let(:input) { [a_pointer, mock_playlist_raw, 3, 8, :userdata] }
|
14
|
+
let(:output) { [Hallon::Playlist.new(mock_playlist), 3, 8, subject] }
|
15
|
+
end
|
16
|
+
|
17
|
+
specification_for_callback "container_loaded" do
|
18
|
+
let(:input) { [a_pointer, :userdata] }
|
19
|
+
let(:output) { [subject] }
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
describe Hallon::Observable::Playlist do
|
2
|
+
let(:trackpointers_size) { 2 }
|
3
|
+
let(:trackpointers) do
|
4
|
+
tracks = FFI::MemoryPointer.new(:pointer, 2)
|
5
|
+
tracks.write_array_of_pointer([mock_track, mock_track_two])
|
6
|
+
tracks
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:tracks) do
|
10
|
+
instantiate(Hallon::Track, mock_track, mock_track_two)
|
11
|
+
end
|
12
|
+
|
13
|
+
specification_for_callback "tracks_added" do
|
14
|
+
let(:input) { [a_pointer, trackpointers, trackpointers_size, 0, :userdata] }
|
15
|
+
let(:output) { [tracks, 0, subject] }
|
16
|
+
end
|
17
|
+
|
18
|
+
specification_for_callback "tracks_removed" do
|
19
|
+
let(:input) { [a_pointer, trackpointers, trackpointers_size, :userdata] }
|
20
|
+
let(:output) { [tracks, subject] }
|
21
|
+
end
|
22
|
+
|
23
|
+
specification_for_callback "tracks_moved" do
|
24
|
+
let(:input) { [a_pointer, trackpointers, trackpointers_size, 7, :userdata] }
|
25
|
+
let(:output) { [tracks, 7, subject] }
|
26
|
+
end
|
27
|
+
|
28
|
+
specification_for_callback "playlist_renamed" do
|
29
|
+
let(:input) { [a_pointer, :userdata] }
|
30
|
+
let(:output) { [subject] }
|
31
|
+
end
|
32
|
+
|
33
|
+
specification_for_callback "playlist_state_changed" do
|
34
|
+
let(:input) { [a_pointer, :userdata] }
|
35
|
+
let(:output) { [subject] }
|
36
|
+
end
|
37
|
+
|
38
|
+
specification_for_callback "playlist_update_in_progress" do
|
39
|
+
let(:input) { [a_pointer, true, :userdata] }
|
40
|
+
let(:output) { [true, subject] }
|
41
|
+
end
|
42
|
+
|
43
|
+
specification_for_callback "playlist_metadata_updated" do
|
44
|
+
let(:input) { [a_pointer, :userdata] }
|
45
|
+
let(:output) { [subject] }
|
46
|
+
end
|
47
|
+
|
48
|
+
specification_for_callback "track_created_changed" do
|
49
|
+
let(:input) { [a_pointer, 7, mock_user_raw, 15, :userdata] }
|
50
|
+
let(:output) { [7, Hallon::User.new(mock_user), Time.at(15), subject] }
|
51
|
+
end
|
52
|
+
|
53
|
+
specification_for_callback "track_seen_changed" do
|
54
|
+
let(:input) { [a_pointer, 0, true, :userdata] }
|
55
|
+
let(:output) { [0, true, subject] }
|
56
|
+
end
|
57
|
+
|
58
|
+
specification_for_callback "track_message_changed" do
|
59
|
+
let(:input) { [a_pointer, 13, "I LUFF JOO!", :userdata] }
|
60
|
+
let(:output) { [13, "I LUFF JOO!", subject] }
|
61
|
+
end
|
62
|
+
|
63
|
+
specification_for_callback "description_changed" do
|
64
|
+
let(:input) { [a_pointer, "Merily merily merily bong", :userdata] }
|
65
|
+
let(:output) { ["Merily merily merily bong", subject] }
|
66
|
+
end
|
67
|
+
|
68
|
+
specification_for_callback "image_changed" do
|
69
|
+
before { Hallon::Session.stub!(:instance => session) }
|
70
|
+
let(:input) { [a_pointer, mock_image_id, :userdata] }
|
71
|
+
let(:output) { [Hallon::Image.new(mock_image), subject] }
|
72
|
+
|
73
|
+
it "should not fail if the image has been *removed*" do
|
74
|
+
block = proc { |image| }
|
75
|
+
block.should_receive(:call).with(nil, subject)
|
76
|
+
subject.on(:image_changed, &block)
|
77
|
+
subject_callback.call(a_pointer, null_pointer, :userdata)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
specification_for_callback "subscribers_changed" do
|
82
|
+
let(:input) { [a_pointer, :userdata] }
|
83
|
+
let(:output) { [subject] }
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
describe Hallon::Observable::Session do
|
3
|
+
let(:klass) { Class.new { include described_class } }
|
4
|
+
let(:object) { klass.new }
|
5
|
+
|
6
|
+
specification_for_callback "logged_in" do
|
7
|
+
let(:input) { [a_pointer, :ok] }
|
8
|
+
let(:output) { [:ok, subject] }
|
9
|
+
end
|
10
|
+
|
11
|
+
specification_for_callback "logged_out" do
|
12
|
+
let(:input) { [a_pointer] }
|
13
|
+
let(:output) { [subject] }
|
14
|
+
end
|
15
|
+
|
16
|
+
specification_for_callback "metadata_updated" do
|
17
|
+
let(:input) { [a_pointer] }
|
18
|
+
let(:output) { [subject] }
|
19
|
+
end
|
20
|
+
|
21
|
+
specification_for_callback "connection_error" do
|
22
|
+
let(:input) { [a_pointer, :ok] }
|
23
|
+
let(:output) { [:ok, subject] }
|
24
|
+
end
|
25
|
+
|
26
|
+
specification_for_callback "message_to_user" do
|
27
|
+
let(:input) { [a_pointer, "ALL UR BASE"] }
|
28
|
+
let(:output) { ["ALL UR BASE", subject] }
|
29
|
+
end
|
30
|
+
|
31
|
+
specification_for_callback "notify_main_thread" do
|
32
|
+
let(:input) { [a_pointer] }
|
33
|
+
let(:output) { [subject] }
|
34
|
+
end
|
35
|
+
|
36
|
+
specification_for_callback "music_delivery" do
|
37
|
+
let(:num_frames) do
|
38
|
+
data.size / 2
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:data) do
|
42
|
+
(0...100).zip((0...100).to_a.reverse).flatten # [0, 99, 1, 98 …]
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:frames) do
|
46
|
+
channels = 2
|
47
|
+
frames = FFI::MemoryPointer.new(:int16, num_frames * channels)
|
48
|
+
frames.write_array_of_int16(data.flatten)
|
49
|
+
frames
|
50
|
+
end
|
51
|
+
|
52
|
+
let(:format) do
|
53
|
+
struct = Spotify::AudioFormat.new
|
54
|
+
struct[:sample_type] = :int16
|
55
|
+
struct[:sample_rate] = 44100 # 44.1khz
|
56
|
+
struct[:channels] = 2
|
57
|
+
struct.pointer
|
58
|
+
end
|
59
|
+
|
60
|
+
let(:input) { [a_pointer, format, frames, num_frames] }
|
61
|
+
let(:output) { [{rate: 44100, type: :int16, channels: 2}, data.each_slice(2), subject] }
|
62
|
+
|
63
|
+
it "should return the resulting value" do
|
64
|
+
subject.on(:music_delivery) { 7 }
|
65
|
+
subject_callback.call(*input).should eq 7
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should ensure the resulting value is an integer" do
|
69
|
+
subject_callback.call(*input).should eq 0
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
specification_for_callback "play_token_lost" do
|
74
|
+
let(:input) { [a_pointer] }
|
75
|
+
let(:output) { [subject] }
|
76
|
+
end
|
77
|
+
|
78
|
+
specification_for_callback "end_of_track" do
|
79
|
+
let(:input) { [a_pointer] }
|
80
|
+
let(:output) { [subject] }
|
81
|
+
end
|
82
|
+
|
83
|
+
specification_for_callback "start_playback" do
|
84
|
+
let(:input) { [a_pointer] }
|
85
|
+
let(:output) { [subject] }
|
86
|
+
end
|
87
|
+
|
88
|
+
specification_for_callback "stop_playback" do
|
89
|
+
let(:input) { [a_pointer] }
|
90
|
+
let(:output) { [subject] }
|
91
|
+
end
|
92
|
+
|
93
|
+
specification_for_callback "get_audio_buffer_stats" do
|
94
|
+
let(:input) { [a_pointer, Spotify::AudioBufferStats.new.pointer] }
|
95
|
+
let(:output) { [subject] }
|
96
|
+
|
97
|
+
it "should return the resulting audio buffer stats" do
|
98
|
+
stats = Spotify::AudioBufferStats.new
|
99
|
+
subject.on(:get_audio_buffer_stats) { [5, 7] }
|
100
|
+
|
101
|
+
stats[:samples].should eq 0
|
102
|
+
stats[:stutter].should eq 0
|
103
|
+
subject_callback.call(a_pointer, stats.pointer)
|
104
|
+
stats[:samples].should eq 5
|
105
|
+
stats[:stutter].should eq 7
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should report zeroes if there’s no callback" do
|
109
|
+
stats = Spotify::AudioBufferStats.new
|
110
|
+
|
111
|
+
stats[:samples].should eq 0
|
112
|
+
stats[:stutter].should eq 0
|
113
|
+
subject_callback.call(a_pointer, stats.pointer)
|
114
|
+
stats[:samples].should eq 0
|
115
|
+
stats[:stutter].should eq 0
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
specification_for_callback "streaming_error" do
|
120
|
+
let(:input) { [a_pointer, :ok] }
|
121
|
+
let(:output) { [:ok, subject] }
|
122
|
+
end
|
123
|
+
|
124
|
+
specification_for_callback "userinfo_updated" do
|
125
|
+
let(:input) { [a_pointer] }
|
126
|
+
let(:output) { [subject] }
|
127
|
+
end
|
128
|
+
|
129
|
+
specification_for_callback "log_message" do
|
130
|
+
let(:input) { [a_pointer, "WATCHING U!"] }
|
131
|
+
let(:output) { ["WATCHING U!", subject] }
|
132
|
+
end
|
133
|
+
|
134
|
+
specification_for_callback "offline_status_updated" do
|
135
|
+
let(:input) { [a_pointer] }
|
136
|
+
let(:output) { [subject] }
|
137
|
+
end
|
138
|
+
|
139
|
+
specification_for_callback "offline_error" do
|
140
|
+
let(:input) { [a_pointer, :ok] }
|
141
|
+
let(:output) { [:ok, subject] }
|
142
|
+
end
|
143
|
+
end
|
@@ -1,80 +1,155 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
describe Hallon::Observable do
|
2
|
-
|
3
|
-
Class.new
|
3
|
+
let(:klass) do
|
4
|
+
Class.new do
|
5
|
+
class << self
|
6
|
+
def initialize_callbacks
|
7
|
+
%w[testing testing_string testing_symbol testing_arguments].map do |m|
|
8
|
+
callback_for(m)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def testing_callback(pointer)
|
13
|
+
trigger(pointer, :testing)
|
14
|
+
end
|
15
|
+
|
16
|
+
def testing_string_callback(pointer)
|
17
|
+
trigger(pointer, "testing_string")
|
18
|
+
end
|
19
|
+
|
20
|
+
def testing_symbol_callback(pointer)
|
21
|
+
trigger(pointer, :testing_symbol)
|
22
|
+
end
|
23
|
+
|
24
|
+
def testing_arguments_callback(pointer, x, y)
|
25
|
+
trigger(pointer, :testing_arguments, x * 2, y * 4)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
include Hallon::Observable
|
30
|
+
|
31
|
+
attr_reader :callbacks
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
subscribe_for_callbacks do |callbacks|
|
35
|
+
@callbacks = callbacks
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def fire!(name, *args, &block)
|
40
|
+
ptr = FFI::Pointer.new(pointer)
|
41
|
+
cb = self.class.send(:callback_for, name)
|
42
|
+
cb.call(ptr, *args)
|
43
|
+
end
|
44
|
+
|
45
|
+
def pointer
|
46
|
+
FFI::Pointer.new(0xDEADBEEF)
|
47
|
+
end
|
48
|
+
end
|
4
49
|
end
|
5
50
|
|
6
|
-
describe "
|
7
|
-
|
8
|
-
|
51
|
+
describe "ClassMethods" do
|
52
|
+
subject { klass }
|
53
|
+
|
54
|
+
describe ".subscribers_for" do
|
55
|
+
around { |test| Ref::Mock.use(&test) }
|
56
|
+
|
57
|
+
it "should contain a list of weak references to subscribers" do
|
58
|
+
ptr = FFI::Pointer.new(0xDEADBEEF)
|
59
|
+
|
60
|
+
objA = klass.new
|
61
|
+
subject.subscribers_for(ptr).should eq [objA]
|
62
|
+
|
63
|
+
objB = klass.new
|
64
|
+
subject.subscribers_for(ptr).should eq [objA, objB]
|
65
|
+
|
66
|
+
Ref::Mock.gc(objA)
|
67
|
+
subject.subscribers_for(ptr).should eq [objB]
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return an empty array if there are no subscribers" do
|
71
|
+
subject.subscribers_for(null_pointer).should be_empty
|
72
|
+
end
|
73
|
+
end
|
9
74
|
end
|
10
75
|
|
76
|
+
subject { klass.new }
|
77
|
+
|
11
78
|
describe "#on" do
|
12
|
-
it "should
|
13
|
-
|
14
|
-
|
15
|
-
|
79
|
+
it "should take both a symbol and a string" do
|
80
|
+
string = false
|
81
|
+
symbol = false
|
82
|
+
|
83
|
+
subject.on("testing_string") { string = true }
|
84
|
+
subject.on(:testing_symbol) { symbol = true }
|
85
|
+
|
86
|
+
subject.fire!(:testing_string)
|
87
|
+
subject.fire!("testing_symbol")
|
16
88
|
|
17
|
-
|
18
|
-
|
19
|
-
subject.trigger(:c).should eq "yay"
|
89
|
+
string.should be_true
|
90
|
+
symbol.should be_true
|
20
91
|
end
|
21
92
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
93
|
+
it "should receive the callback after it’s been processed" do
|
94
|
+
x = nil
|
95
|
+
y = nil
|
96
|
+
|
97
|
+
subject.on(:testing_arguments) do |a, b|
|
98
|
+
x = a
|
99
|
+
y = b
|
100
|
+
end
|
101
|
+
|
102
|
+
subject.fire!(:testing_arguments, 10, "Hi")
|
103
|
+
|
104
|
+
x.should eq 20
|
105
|
+
y.should eq "HiHiHiHi"
|
26
106
|
end
|
27
107
|
|
28
|
-
|
29
|
-
|
30
|
-
|
108
|
+
it "should replace the previous callback if there was one" do
|
109
|
+
x = 0
|
110
|
+
|
111
|
+
subject.on(:testing) { x += 1 }
|
112
|
+
subject.fire!(:testing)
|
113
|
+
x.should eq 1
|
114
|
+
|
115
|
+
subject.on(:testing) { x -= 1 }
|
116
|
+
subject.fire!(:testing)
|
117
|
+
x.should eq 0
|
31
118
|
end
|
32
119
|
|
33
|
-
it "should
|
34
|
-
subject.on("
|
35
|
-
expect { subject.trigger(:a) }.to raise_error("hell")
|
120
|
+
it "should raise an error trying to bind to a non-existing callback" do
|
121
|
+
expect { subject.on("nonexisting") {} }.to raise_error(NameError)
|
36
122
|
end
|
37
|
-
end
|
38
123
|
|
39
|
-
|
40
|
-
|
41
|
-
called = false
|
42
|
-
subject.on(:a) { called = true }
|
43
|
-
subject.trigger(:a)
|
44
|
-
called.should be_true
|
124
|
+
it "should raise an error when not given a block" do
|
125
|
+
expect { subject.on(:testing) }.to raise_error(ArgumentError)
|
45
126
|
end
|
127
|
+
end
|
46
128
|
|
47
|
-
|
48
|
-
|
49
|
-
subject.
|
50
|
-
subject.trigger(:a, :b, :c)
|
51
|
-
passed_args.should eq [:b, :c]
|
129
|
+
describe "#subscribe_for_callbacks" do
|
130
|
+
it "should yield indiscriminetly" do
|
131
|
+
expect { subject.send(:subscribe_for_callbacks) }.to raise_error(LocalJumpError)
|
52
132
|
end
|
53
133
|
|
54
|
-
it "should
|
55
|
-
|
134
|
+
it "should raise an error if the same object tries to subscribe twice" do
|
135
|
+
# we already subscribed for callbacks in initialize
|
136
|
+
expect { subject.send(:subscribe_for_callbacks) {} }.to raise_error(ArgumentError)
|
56
137
|
end
|
57
138
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
subject.on(:a) { triggered << :a }
|
62
|
-
subject.on(:a) { triggered << :b }
|
63
|
-
subject.trigger(:a)
|
64
|
-
triggered.should eq [:a, :b]
|
65
|
-
end
|
139
|
+
it "should always yield the *same* object" do
|
140
|
+
a = klass.new
|
141
|
+
b = klass.new
|
66
142
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
subject.trigger(:a).should eq :second
|
71
|
-
end
|
143
|
+
a.callbacks.should eq b.callbacks
|
144
|
+
end
|
145
|
+
end
|
72
146
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
147
|
+
describe "#trigger" do
|
148
|
+
it "should always append self to the arguments" do
|
149
|
+
block = proc {}
|
150
|
+
subject.on(:testing, &block)
|
151
|
+
block.should_receive(:call).with(subject)
|
152
|
+
subject.send(:trigger, :testing)
|
78
153
|
end
|
79
154
|
end
|
80
155
|
|
@@ -86,21 +161,15 @@ describe Hallon::Observable do
|
|
86
161
|
end
|
87
162
|
|
88
163
|
it "should restore previous handlers on return" do
|
89
|
-
subject.on(:
|
164
|
+
subject.on(:testing) { "before" }
|
90
165
|
|
91
166
|
subject.protecting_handlers do
|
92
|
-
subject.
|
93
|
-
subject.on(:
|
94
|
-
subject.
|
167
|
+
subject.fire!(:testing).should eq "before"
|
168
|
+
subject.on(:testing) { "after" }
|
169
|
+
subject.fire!(:testing).should eq "after"
|
95
170
|
end
|
96
171
|
|
97
|
-
subject.
|
98
|
-
end
|
99
|
-
|
100
|
-
it "should still allow #trigger to work on non-defined events" do
|
101
|
-
subject.protecting_handlers {}
|
102
|
-
expect { subject.trigger(:does_not_exist) }.to_not raise_error
|
172
|
+
subject.fire!(:testing).should eq "before"
|
103
173
|
end
|
104
174
|
end
|
105
|
-
|
106
175
|
end
|