spotify 12.5.3 → 12.6.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +20 -5
- data/CHANGELOG.md +29 -1
- data/Gemfile +5 -0
- data/MIT-LICENSE +21 -0
- data/README.markdown +75 -50
- data/Rakefile +1 -1
- data/examples/example-audio_delivery_speed.rb +48 -0
- data/examples/{audio-stream_example.rb → example-audio_stream.rb} +14 -29
- data/examples/example-console.rb +9 -0
- data/examples/example-listing_playlists.rb +89 -0
- data/examples/example-loading_object.rb +25 -0
- data/examples/example-random_related_artists.rb +53 -0
- data/examples/support.rb +106 -0
- data/lib/spotify.rb +36 -55
- data/lib/spotify/api.rb +54 -26
- data/lib/spotify/api/album.rb +45 -2
- data/lib/spotify/api/album_browse.rb +81 -3
- data/lib/spotify/api/artist.rb +21 -2
- data/lib/spotify/api/artist_browse.rb +121 -3
- data/lib/spotify/api/error.rb +5 -1
- data/lib/spotify/api/image.rb +72 -6
- data/lib/spotify/api/inbox.rb +33 -4
- data/lib/spotify/api/link.rb +117 -4
- data/lib/spotify/api/miscellaneous.rb +12 -0
- data/lib/spotify/api/playlist.rb +321 -16
- data/lib/spotify/api/playlist_container.rb +168 -9
- data/lib/spotify/api/search.rb +156 -3
- data/lib/spotify/api/session.rb +390 -26
- data/lib/spotify/api/toplist_browse.rb +74 -3
- data/lib/spotify/api/track.rb +134 -4
- data/lib/spotify/api/user.rb +18 -2
- data/lib/spotify/api_helpers.rb +47 -0
- data/lib/spotify/data_converters.rb +7 -0
- data/lib/spotify/{types → data_converters}/best_effort_string.rb +1 -1
- data/lib/spotify/{types → data_converters}/byte_string.rb +0 -0
- data/lib/spotify/data_converters/country_code.rb +30 -0
- data/lib/spotify/{types → data_converters}/image_id.rb +1 -1
- data/lib/spotify/{type_safety.rb → data_converters/type_safety.rb} +0 -0
- data/lib/spotify/{types → data_converters}/utf8_string.rb +2 -2
- data/lib/spotify/{types → data_converters}/utf8_string_pointer.rb +2 -2
- data/lib/spotify/error.rb +180 -47
- data/lib/spotify/managed_pointer.rb +32 -12
- data/lib/spotify/monkey_patches/ffi_buffer.rb +11 -0
- data/lib/spotify/monkey_patches/ffi_enums.rb +4 -0
- data/lib/spotify/monkey_patches/ffi_pointer.rb +1 -0
- data/lib/spotify/structs.rb +4 -0
- data/lib/spotify/structs/session_callbacks.rb +97 -26
- data/lib/spotify/structs/session_config.rb +1 -1
- data/lib/spotify/structs/subscribers.rb +4 -3
- data/lib/spotify/types.rb +104 -5
- data/lib/spotify/{objects → types}/album.rb +0 -0
- data/lib/spotify/{objects → types}/album_browse.rb +0 -0
- data/lib/spotify/{objects → types}/artist.rb +0 -0
- data/lib/spotify/{objects → types}/artist_browse.rb +0 -0
- data/lib/spotify/{objects → types}/image.rb +0 -0
- data/lib/spotify/{objects → types}/inbox.rb +0 -0
- data/lib/spotify/{objects → types}/link.rb +0 -0
- data/lib/spotify/{objects → types}/playlist.rb +0 -0
- data/lib/spotify/{objects → types}/playlist_container.rb +0 -0
- data/lib/spotify/{objects → types}/search.rb +0 -0
- data/lib/spotify/{objects → types}/session.rb +0 -0
- data/lib/spotify/{objects → types}/toplist_browse.rb +0 -0
- data/lib/spotify/{objects → types}/track.rb +0 -0
- data/lib/spotify/{objects → types}/user.rb +0 -0
- data/lib/spotify/util.rb +38 -35
- data/lib/spotify/version.rb +1 -1
- data/spec/spec_helper.rb +24 -13
- data/spec/spotify/api/image_spec.rb +32 -0
- data/spec/spotify/api/inbox_spec.rb +34 -0
- data/spec/spotify/api/link_spec.rb +40 -0
- data/spec/spotify/api/playlist_spec.rb +99 -0
- data/spec/spotify/api/playlistcontainer_spec.rb +82 -0
- data/spec/spotify/api/session_spec.rb +97 -0
- data/spec/spotify/api/track_spec.rb +29 -0
- data/spec/spotify/api_error_spec.rb +55 -0
- data/spec/spotify/api_spec.rb +17 -11
- data/spec/spotify/{types → data_converters}/best_effort_string_spec.rb +4 -4
- data/spec/spotify/{types → data_converters}/byte_string_spec.rb +0 -0
- data/spec/spotify/data_converters/country_code_spec.rb +16 -0
- data/spec/spotify/{types → data_converters}/image_id_spec.rb +1 -1
- data/spec/spotify/{type_safety_spec.rb → data_converters/type_safety_spec.rb} +0 -0
- data/spec/spotify/{types → data_converters}/utf8_string_pointer_spec.rb +0 -0
- data/spec/spotify/{types → data_converters}/utf8_string_spec.rb +1 -1
- data/spec/spotify/{api/functions_spec.rb → functions_spec.rb} +2 -0
- data/spec/spotify/managed_pointer_spec.rb +13 -13
- data/spec/spotify/structs/subscribers_spec.rb +5 -3
- data/spec/spotify/{defines_spec.rb → types_spec.rb} +16 -3
- data/spec/spotify/util_spec.rb +24 -0
- data/spec/spotify_spec.rb +74 -0
- data/spec/support/spotify_util.rb +6 -2
- data/spec/support/spy_output.rb +16 -0
- data/spotify.gemspec +4 -2
- metadata +111 -71
- data/examples/README.md +0 -15
- data/examples/console_example.rb +0 -22
- data/examples/example_support.rb +0 -66
- data/examples/loading-object_example.rb +0 -43
- data/examples/logging-in_example.rb +0 -58
- data/lib/spotify/defines.rb +0 -109
- data/lib/spotify/objects.rb +0 -17
- data/spec/spotify/enums_spec.rb +0 -9
- data/spec/spotify/spotify_spec.rb +0 -69
data/lib/spotify/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
require "rbgccxml"
|
|
3
3
|
require "rspec"
|
|
4
|
-
require "pry"
|
|
5
4
|
require "stringio"
|
|
6
5
|
|
|
7
6
|
require "spec/support/hook_spotify"
|
|
8
7
|
require "spec/support/spotify_util"
|
|
8
|
+
require "spec/support/spy_output"
|
|
9
9
|
|
|
10
10
|
# You can pregenerate new XML files through:
|
|
11
11
|
# gccxml spec/api-mac.h -fxml=spec/api-mac.xml
|
|
12
12
|
# gccxml spec/api-linux.h -fxml=spec/api-linux.xml
|
|
13
|
-
API_H_PATH = File.expand_path("../support/api-#{Spotify.platform}.h", __FILE__)
|
|
13
|
+
API_H_PATH = File.expand_path("../support/api-#{Spotify::Util.platform}.h", __FILE__)
|
|
14
14
|
API_H_SRC = File.read(API_H_PATH)
|
|
15
15
|
API_H_XML = RbGCCXML.parse_xml(API_H_PATH.sub('.h', '.xml'))
|
|
16
16
|
|
|
17
|
+
class << Spotify
|
|
18
|
+
attr_accessor :performer
|
|
19
|
+
end
|
|
20
|
+
|
|
17
21
|
RSpec.configure do |config|
|
|
18
22
|
def api
|
|
19
23
|
Spotify::API
|
|
20
24
|
end
|
|
21
25
|
|
|
26
|
+
config.expect_with :rspec do |c|
|
|
27
|
+
c.syntax = [:should, :expect]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
config.mock_with :rspec do |c|
|
|
31
|
+
c.syntax = [:should, :expect]
|
|
32
|
+
end
|
|
33
|
+
|
|
22
34
|
config.filter_run_excluding(engine: ->(engine) do
|
|
23
35
|
! Array(engine).include?(RUBY_ENGINE)
|
|
24
36
|
end)
|
|
@@ -30,17 +42,16 @@ RSpec.configure do |config|
|
|
|
30
42
|
end)
|
|
31
43
|
|
|
32
44
|
config.around(:each) do |test|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
$stderr.rewind
|
|
37
|
-
warnings = $stderr.read
|
|
38
|
-
if warnings =~ %r"lib/spotify"
|
|
39
|
-
stderr.write(warnings)
|
|
40
|
-
raise "#{example.description.inspect} caused a warning, #{warnings.inspect}"
|
|
41
|
-
end
|
|
42
|
-
ensure
|
|
43
|
-
$stderr = stderr
|
|
45
|
+
_, warnings = spy_output { test.run }
|
|
46
|
+
if warnings =~ %r"lib/spotify" and not $DEBUG
|
|
47
|
+
raise "#{example.description.inspect} caused a warning, #{warnings.inspect}"
|
|
44
48
|
end
|
|
45
49
|
end
|
|
50
|
+
|
|
51
|
+
config.around(:each) do |example|
|
|
52
|
+
Spotify.performer = Performer.new
|
|
53
|
+
example.run
|
|
54
|
+
task = Spotify.performer.shutdown
|
|
55
|
+
task.value # wait for shutdown
|
|
56
|
+
end
|
|
46
57
|
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
describe "Spotify::API" do
|
|
2
|
+
describe "#image_data" do
|
|
3
|
+
let(:image) { double }
|
|
4
|
+
|
|
5
|
+
it "reads the raw image data" do
|
|
6
|
+
api.should_receive(:sp_image_data) do |img, img_size_pointer|
|
|
7
|
+
img.should eq(image)
|
|
8
|
+
img_size_pointer.write_size_t(8)
|
|
9
|
+
FFI::MemoryPointer.from_string("image data")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
api.image_data(image).should eq "image da"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "is nil if image data is null" do
|
|
16
|
+
api.should_receive(:sp_image_data) do |img, img_size_pointer|
|
|
17
|
+
FFI::Pointer::NULL
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
api.image_data(image).should be_nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "is nil if image data size is 0" do
|
|
24
|
+
api.should_receive(:sp_image_data) do |img, img_size_pointer|
|
|
25
|
+
img_size_pointer.write_size_t(0)
|
|
26
|
+
FFI::MemoryPointer.from_string("image data")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
api.image_data(image).should be_nil
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
describe "Spotify::API" do
|
|
2
|
+
describe "#inbox_post_tracks" do
|
|
3
|
+
let(:session) { double }
|
|
4
|
+
let(:callback) { lambda {} }
|
|
5
|
+
let(:track_a) { FFI::MemoryPointer.new(:pointer) }
|
|
6
|
+
let(:track_b) { FFI::MemoryPointer.new(:pointer) }
|
|
7
|
+
let(:tracks) { [track_a, track_b] }
|
|
8
|
+
let(:inbox) { double }
|
|
9
|
+
|
|
10
|
+
it "posts an array of tracks to a user's inbox" do
|
|
11
|
+
api.should_receive(:sp_inbox_post_tracks) do |ptr, username, buffer, buffer_size, message, ptr_callback, userdata|
|
|
12
|
+
ptr.should eq(session)
|
|
13
|
+
username.should eq("burgestrand")
|
|
14
|
+
buffer.read_array_of_pointer(buffer_size).should eq(tracks)
|
|
15
|
+
message.should eq("You must listen to these!")
|
|
16
|
+
ptr_callback.should eq(callback)
|
|
17
|
+
userdata.should eq(:userdata)
|
|
18
|
+
inbox
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
api.inbox_post_tracks(session, "burgestrand", tracks, "You must listen to these!", callback, :userdata).should eq(inbox)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "casts a single track to an array" do
|
|
25
|
+
api.should_receive(:sp_inbox_post_tracks) do |ptr, username, buffer, buffer_size, message, ptr_callback, userdata|
|
|
26
|
+
buffer.read_array_of_pointer(1).should eq([track_a])
|
|
27
|
+
buffer_size.should eq(1)
|
|
28
|
+
inbox
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
api.inbox_post_tracks(session, "burgestrand", track_a, "You must listen to these!", callback, :userdata).should eq(inbox)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
describe "Spotify::API" do
|
|
2
|
+
describe "#link_as_string" do
|
|
3
|
+
let(:link) { double }
|
|
4
|
+
|
|
5
|
+
it "reads the link as an UTF-8 encoded string" do
|
|
6
|
+
api.should_receive(:sp_link_as_string).twice do |ptr, buffer, buffer_size|
|
|
7
|
+
ptr.should eq(link)
|
|
8
|
+
buffer.write_bytes("spotify:user:burgestrandX") if buffer
|
|
9
|
+
24
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
string = api.link_as_string(link)
|
|
13
|
+
string.should eq "spotify:user:burgestrand"
|
|
14
|
+
string.encoding.should eq(Encoding::UTF_8)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "#link_as_track_and_offset" do
|
|
19
|
+
let(:link) { double }
|
|
20
|
+
let(:track) { double }
|
|
21
|
+
|
|
22
|
+
it "reads the link as a track with offset information" do
|
|
23
|
+
api.should_receive(:sp_link_as_track_and_offset) do |ptr, offset_pointer|
|
|
24
|
+
ptr.should eq(link)
|
|
25
|
+
offset_pointer.write_int(6000)
|
|
26
|
+
track
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
api.link_as_track_and_offset(link).should eq([track, 6000])
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "returns nil if the link is not a track link" do
|
|
33
|
+
api.should_receive(:sp_link_as_track_and_offset) do |ptr, offset_pointer|
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
api.link_as_track_and_offset(link).should be_nil
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
describe "Spotify::API" do
|
|
2
|
+
let(:playlist) { double }
|
|
3
|
+
|
|
4
|
+
describe "#playlist_get_image" do
|
|
5
|
+
let(:image_id) { "v\xE5\xAA\xD3F\xF8\xEE4G\xA1.D\x9C\x85 \xC5\xFD\x80]\x99".force_encoding(Encoding::BINARY) }
|
|
6
|
+
|
|
7
|
+
it "returns the image ID if playlist has an image" do
|
|
8
|
+
api.should_receive(:sp_playlist_get_image) do |ptr, image_id_pointer|
|
|
9
|
+
ptr.should eq(playlist)
|
|
10
|
+
image_id_pointer.write_bytes(image_id)
|
|
11
|
+
true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
api.playlist_get_image(playlist).should eq(image_id)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "returns nil if playlist has no image" do
|
|
18
|
+
api.should_receive(:sp_playlist_get_image) do |ptr, image_id_pointer|
|
|
19
|
+
false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
api.playlist_get_image(playlist).should be_nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "#playlist_add_tracks" do
|
|
27
|
+
let(:session) { double }
|
|
28
|
+
let(:track_a) { FFI::MemoryPointer.new(:pointer) }
|
|
29
|
+
let(:track_b) { FFI::MemoryPointer.new(:pointer) }
|
|
30
|
+
let(:tracks) { [track_a, track_b] }
|
|
31
|
+
|
|
32
|
+
it "adds an array of tracks to a playlist" do
|
|
33
|
+
api.should_receive(:sp_playlist_add_tracks) do |ptr, buffer, buffer_size, offset, ptr_session|
|
|
34
|
+
ptr.should eq(playlist)
|
|
35
|
+
buffer.read_array_of_pointer(buffer_size).should eq(tracks)
|
|
36
|
+
offset.should eq(2)
|
|
37
|
+
ptr_session.should eq(session)
|
|
38
|
+
:ok
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
api.playlist_add_tracks(playlist, tracks, 2, session).should eq(:ok)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "casts a single track to an array" do
|
|
45
|
+
api.should_receive(:sp_playlist_add_tracks) do |ptr, buffer, buffer_size, offset, ptr_session|
|
|
46
|
+
buffer.read_array_of_pointer(1).should eq([track_a])
|
|
47
|
+
buffer_size.should eq(1)
|
|
48
|
+
:ok
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
api.playlist_add_tracks(playlist, track_a, 2, session).should eq(:ok)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe "#playlist_remove_tracks" do
|
|
56
|
+
it "removes tracks from a playlist" do
|
|
57
|
+
api.should_receive(:sp_playlist_remove_tracks) do |ptr, buffer, buffer_size|
|
|
58
|
+
ptr.should eq(playlist)
|
|
59
|
+
buffer.read_array_of_int(buffer_size).should eq([1, 3, 7])
|
|
60
|
+
:ok
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
api.playlist_remove_tracks(playlist, [1, 3, 7]).should eq(:ok)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "casts a single index to an array" do
|
|
67
|
+
api.should_receive(:sp_playlist_remove_tracks) do |ptr, buffer, buffer_size|
|
|
68
|
+
buffer.read_array_of_int(1).should eq([3])
|
|
69
|
+
buffer_size.should eq(1)
|
|
70
|
+
:ok
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
api.playlist_remove_tracks(playlist, 3).should eq(:ok)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe "#playlist_reorder_tracks" do
|
|
78
|
+
it "reorders tracks from a playlist" do
|
|
79
|
+
api.should_receive(:sp_playlist_reorder_tracks) do |ptr, buffer, buffer_size, index|
|
|
80
|
+
ptr.should eq(playlist)
|
|
81
|
+
buffer.read_array_of_int(buffer_size).should eq([1, 3, 7])
|
|
82
|
+
index.should eq(3)
|
|
83
|
+
:ok
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
api.playlist_reorder_tracks(playlist, [1, 3, 7], 3).should eq(:ok)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "casts a single index to an array" do
|
|
90
|
+
api.should_receive(:sp_playlist_reorder_tracks) do |ptr, buffer, buffer_size, index|
|
|
91
|
+
buffer.read_array_of_int(1).should eq([7])
|
|
92
|
+
buffer_size.should eq(1)
|
|
93
|
+
:ok
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
api.playlist_reorder_tracks(playlist, 7, 3).should eq(:ok)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
describe "Spotify::API" do
|
|
2
|
+
let(:container) { double }
|
|
3
|
+
|
|
4
|
+
describe "#playlistcontainer_playlist_folder_name" do
|
|
5
|
+
let(:index) { 0 }
|
|
6
|
+
|
|
7
|
+
it "returns the folder name" do
|
|
8
|
+
api.should_receive(:sp_playlistcontainer_playlist_folder_name) do |ptr, index, name_pointer, name_pointer_size|
|
|
9
|
+
ptr.should eq(container)
|
|
10
|
+
name_pointer.write_bytes("Summer Playlists\x00")
|
|
11
|
+
:ok
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
folder_name = api.playlistcontainer_playlist_folder_name(container, index)
|
|
15
|
+
folder_name.should eq "Summer Playlists"
|
|
16
|
+
folder_name.encoding.should eq(Encoding::UTF_8)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "returns nil if out of range" do
|
|
20
|
+
api.should_receive(:sp_playlistcontainer_playlist_folder_name) do |ptr, index, name_pointer, name_pointer_size|
|
|
21
|
+
:error_index_out_of_range
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
api.playlistcontainer_playlist_folder_name(container, index).should be_nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "returns nil if not a folder" do
|
|
28
|
+
api.should_receive(:sp_playlistcontainer_playlist_folder_name) do |ptr, index, name_pointer, name_pointer_size|
|
|
29
|
+
name_pointer.write_bytes("\x00")
|
|
30
|
+
:ok
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
api.playlistcontainer_playlist_folder_name(container, index).should be_nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe "#playlistcontainer_get_unseen_tracks" do
|
|
38
|
+
def track(id)
|
|
39
|
+
pointer = FFI::MemoryPointer.new(:int)
|
|
40
|
+
pointer.write_int(id.to_i)
|
|
41
|
+
pointer
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
let(:playlist) { double }
|
|
45
|
+
let(:track_a) { track(1337) }
|
|
46
|
+
let(:track_b) { track(7331) }
|
|
47
|
+
|
|
48
|
+
it "returns an array of unseen tracks" do
|
|
49
|
+
Spotify::Track.retaining_class.should_receive(:from_native).twice do |pointer, context|
|
|
50
|
+
pointer.read_int
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
api.should_receive(:sp_playlistcontainer_get_unseen_tracks).twice do |ptr, ptr_playlist, tracks_buffer, tracks_buffer_size|
|
|
54
|
+
ptr.should eq(container)
|
|
55
|
+
ptr_playlist.should eq(playlist)
|
|
56
|
+
if tracks_buffer
|
|
57
|
+
tracks_buffer.write_array_of_pointer([track_a, track_b])
|
|
58
|
+
tracks_buffer_size.should eq(2)
|
|
59
|
+
end
|
|
60
|
+
2
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
api.playlistcontainer_get_unseen_tracks(container, playlist).should eq([1337, 7331])
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "returns an empty array when there are no unseen tracks" do
|
|
67
|
+
api.should_receive(:sp_playlistcontainer_get_unseen_tracks) do |ptr, playlist, tracks_buffer, tracks_buffer_size|
|
|
68
|
+
0
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
api.playlistcontainer_get_unseen_tracks(container, playlist).should be_empty
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "returns an empty array on failure" do
|
|
75
|
+
api.should_receive(:sp_playlistcontainer_get_unseen_tracks) do |ptr, playlist, tracks_buffer, tracks_buffer_size|
|
|
76
|
+
-1
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
api.playlistcontainer_get_unseen_tracks(container, playlist).should be_empty
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
describe "Spotify::API" do
|
|
2
|
+
let(:session) { double }
|
|
3
|
+
|
|
4
|
+
describe "#session_create" do
|
|
5
|
+
let(:config) do
|
|
6
|
+
{
|
|
7
|
+
user_agent: "This is a test",
|
|
8
|
+
callbacks: Spotify::SessionCallbacks.new(music_delivery: proc {})
|
|
9
|
+
}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:session_pointer) { FFI::MemoryPointer.new(:pointer) }
|
|
13
|
+
|
|
14
|
+
it "creates a session with the given configuration" do
|
|
15
|
+
api.should_receive(:sp_session_create) do |struct_config, ptr_session|
|
|
16
|
+
struct_config.should be_a(Spotify::SessionConfig)
|
|
17
|
+
struct_config[:user_agent].should eq("This is a test")
|
|
18
|
+
struct_config[:callbacks].should be_a(Spotify::SessionCallbacks)
|
|
19
|
+
ptr_session.write_pointer(session_pointer)
|
|
20
|
+
:ok
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
error, session = api.session_create(config)
|
|
24
|
+
error.should be_nil
|
|
25
|
+
session.should be_a(Spotify::Session)
|
|
26
|
+
session.address.should eq(session_pointer.address)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "returns the error without session on failure" do
|
|
30
|
+
api.should_receive(:sp_session_create) do |struct_config, ptr_session|
|
|
31
|
+
:bad_api_version
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
error, session = api.session_create(config)
|
|
35
|
+
error.should eq(:bad_api_version)
|
|
36
|
+
session.should be_nil
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "#session_process_events" do
|
|
41
|
+
it "returns time until session_process_events should be called again" do
|
|
42
|
+
api.should_receive(:sp_session_process_events) do |ptr, timeout_pointer|
|
|
43
|
+
ptr.should eq(session)
|
|
44
|
+
timeout_pointer.write_int(1337)
|
|
45
|
+
:ok
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
api.session_process_events(session).should eq(1337)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "#session_remembered_user" do
|
|
53
|
+
it "returns the name of the remembered user" do
|
|
54
|
+
api.should_receive(:sp_session_remembered_user).twice do |ptr, string_pointer, string_pointer_size|
|
|
55
|
+
ptr.should eq(session)
|
|
56
|
+
string_pointer.write_bytes("BurgeX") if string_pointer
|
|
57
|
+
5
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
api.session_remembered_user(session).should eq("Burge")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "returns nil if there is no remembered user" do
|
|
64
|
+
api.should_receive(:sp_session_remembered_user) do |ptr, string_pointer, string_pointer_size|
|
|
65
|
+
-1
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
api.session_remembered_user(session).should be_nil
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe "#session_is_scrobbling" do
|
|
73
|
+
it "returns the scrobbling state" do
|
|
74
|
+
api.should_receive(:sp_session_is_scrobbling) do |ptr, social_provider, state_pointer|
|
|
75
|
+
ptr.should eq(session)
|
|
76
|
+
social_provider.should eq(:spotify)
|
|
77
|
+
state_pointer.write_int(3)
|
|
78
|
+
:ok
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
api.session_is_scrobbling(session, :spotify).should eq(:global_enabled)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe "#session_is_scrobbling_possible" do
|
|
86
|
+
it "returns true if scrobbling is possible" do
|
|
87
|
+
api.should_receive(:sp_session_is_scrobbling_possible) do |ptr, social_provider, buffer_out|
|
|
88
|
+
ptr.should eq(session)
|
|
89
|
+
social_provider.should eq(:spotify)
|
|
90
|
+
buffer_out.write_char(1)
|
|
91
|
+
:ok
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
api.session_is_scrobbling_possible(session, :spotify).should eq(true)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|