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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +20 -5
  4. data/CHANGELOG.md +29 -1
  5. data/Gemfile +5 -0
  6. data/MIT-LICENSE +21 -0
  7. data/README.markdown +75 -50
  8. data/Rakefile +1 -1
  9. data/examples/example-audio_delivery_speed.rb +48 -0
  10. data/examples/{audio-stream_example.rb → example-audio_stream.rb} +14 -29
  11. data/examples/example-console.rb +9 -0
  12. data/examples/example-listing_playlists.rb +89 -0
  13. data/examples/example-loading_object.rb +25 -0
  14. data/examples/example-random_related_artists.rb +53 -0
  15. data/examples/support.rb +106 -0
  16. data/lib/spotify.rb +36 -55
  17. data/lib/spotify/api.rb +54 -26
  18. data/lib/spotify/api/album.rb +45 -2
  19. data/lib/spotify/api/album_browse.rb +81 -3
  20. data/lib/spotify/api/artist.rb +21 -2
  21. data/lib/spotify/api/artist_browse.rb +121 -3
  22. data/lib/spotify/api/error.rb +5 -1
  23. data/lib/spotify/api/image.rb +72 -6
  24. data/lib/spotify/api/inbox.rb +33 -4
  25. data/lib/spotify/api/link.rb +117 -4
  26. data/lib/spotify/api/miscellaneous.rb +12 -0
  27. data/lib/spotify/api/playlist.rb +321 -16
  28. data/lib/spotify/api/playlist_container.rb +168 -9
  29. data/lib/spotify/api/search.rb +156 -3
  30. data/lib/spotify/api/session.rb +390 -26
  31. data/lib/spotify/api/toplist_browse.rb +74 -3
  32. data/lib/spotify/api/track.rb +134 -4
  33. data/lib/spotify/api/user.rb +18 -2
  34. data/lib/spotify/api_helpers.rb +47 -0
  35. data/lib/spotify/data_converters.rb +7 -0
  36. data/lib/spotify/{types → data_converters}/best_effort_string.rb +1 -1
  37. data/lib/spotify/{types → data_converters}/byte_string.rb +0 -0
  38. data/lib/spotify/data_converters/country_code.rb +30 -0
  39. data/lib/spotify/{types → data_converters}/image_id.rb +1 -1
  40. data/lib/spotify/{type_safety.rb → data_converters/type_safety.rb} +0 -0
  41. data/lib/spotify/{types → data_converters}/utf8_string.rb +2 -2
  42. data/lib/spotify/{types → data_converters}/utf8_string_pointer.rb +2 -2
  43. data/lib/spotify/error.rb +180 -47
  44. data/lib/spotify/managed_pointer.rb +32 -12
  45. data/lib/spotify/monkey_patches/ffi_buffer.rb +11 -0
  46. data/lib/spotify/monkey_patches/ffi_enums.rb +4 -0
  47. data/lib/spotify/monkey_patches/ffi_pointer.rb +1 -0
  48. data/lib/spotify/structs.rb +4 -0
  49. data/lib/spotify/structs/session_callbacks.rb +97 -26
  50. data/lib/spotify/structs/session_config.rb +1 -1
  51. data/lib/spotify/structs/subscribers.rb +4 -3
  52. data/lib/spotify/types.rb +104 -5
  53. data/lib/spotify/{objects → types}/album.rb +0 -0
  54. data/lib/spotify/{objects → types}/album_browse.rb +0 -0
  55. data/lib/spotify/{objects → types}/artist.rb +0 -0
  56. data/lib/spotify/{objects → types}/artist_browse.rb +0 -0
  57. data/lib/spotify/{objects → types}/image.rb +0 -0
  58. data/lib/spotify/{objects → types}/inbox.rb +0 -0
  59. data/lib/spotify/{objects → types}/link.rb +0 -0
  60. data/lib/spotify/{objects → types}/playlist.rb +0 -0
  61. data/lib/spotify/{objects → types}/playlist_container.rb +0 -0
  62. data/lib/spotify/{objects → types}/search.rb +0 -0
  63. data/lib/spotify/{objects → types}/session.rb +0 -0
  64. data/lib/spotify/{objects → types}/toplist_browse.rb +0 -0
  65. data/lib/spotify/{objects → types}/track.rb +0 -0
  66. data/lib/spotify/{objects → types}/user.rb +0 -0
  67. data/lib/spotify/util.rb +38 -35
  68. data/lib/spotify/version.rb +1 -1
  69. data/spec/spec_helper.rb +24 -13
  70. data/spec/spotify/api/image_spec.rb +32 -0
  71. data/spec/spotify/api/inbox_spec.rb +34 -0
  72. data/spec/spotify/api/link_spec.rb +40 -0
  73. data/spec/spotify/api/playlist_spec.rb +99 -0
  74. data/spec/spotify/api/playlistcontainer_spec.rb +82 -0
  75. data/spec/spotify/api/session_spec.rb +97 -0
  76. data/spec/spotify/api/track_spec.rb +29 -0
  77. data/spec/spotify/api_error_spec.rb +55 -0
  78. data/spec/spotify/api_spec.rb +17 -11
  79. data/spec/spotify/{types → data_converters}/best_effort_string_spec.rb +4 -4
  80. data/spec/spotify/{types → data_converters}/byte_string_spec.rb +0 -0
  81. data/spec/spotify/data_converters/country_code_spec.rb +16 -0
  82. data/spec/spotify/{types → data_converters}/image_id_spec.rb +1 -1
  83. data/spec/spotify/{type_safety_spec.rb → data_converters/type_safety_spec.rb} +0 -0
  84. data/spec/spotify/{types → data_converters}/utf8_string_pointer_spec.rb +0 -0
  85. data/spec/spotify/{types → data_converters}/utf8_string_spec.rb +1 -1
  86. data/spec/spotify/{api/functions_spec.rb → functions_spec.rb} +2 -0
  87. data/spec/spotify/managed_pointer_spec.rb +13 -13
  88. data/spec/spotify/structs/subscribers_spec.rb +5 -3
  89. data/spec/spotify/{defines_spec.rb → types_spec.rb} +16 -3
  90. data/spec/spotify/util_spec.rb +24 -0
  91. data/spec/spotify_spec.rb +74 -0
  92. data/spec/support/spotify_util.rb +6 -2
  93. data/spec/support/spy_output.rb +16 -0
  94. data/spotify.gemspec +4 -2
  95. metadata +111 -71
  96. data/examples/README.md +0 -15
  97. data/examples/console_example.rb +0 -22
  98. data/examples/example_support.rb +0 -66
  99. data/examples/loading-object_example.rb +0 -43
  100. data/examples/logging-in_example.rb +0 -58
  101. data/lib/spotify/defines.rb +0 -109
  102. data/lib/spotify/objects.rb +0 -17
  103. data/spec/spotify/enums_spec.rb +0 -9
  104. data/spec/spotify/spotify_spec.rb +0 -69
@@ -1,7 +1,7 @@
1
1
  module Spotify
2
2
  # @note See README for versioning policy.
3
3
  # @return [String] Spotify gem version.
4
- VERSION = '12.5.3'
4
+ VERSION = '12.6.0'
5
5
 
6
6
  # @return [String] Compatible libspotify API version.
7
7
  API_VERSION = '12.1.51'
@@ -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
- stderr, $stderr = $stderr, StringIO.new("")
34
- begin
35
- test.run
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