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
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
describe "Spotify::API" do
|
|
2
|
+
describe "#track_set_starred" do
|
|
3
|
+
let(:session) { double }
|
|
4
|
+
let(:track_a) { FFI::MemoryPointer.new(:pointer) }
|
|
5
|
+
let(:track_b) { FFI::MemoryPointer.new(:pointer) }
|
|
6
|
+
let(:tracks) { [track_a, track_b] }
|
|
7
|
+
|
|
8
|
+
it "changes the starred state of the given tracks" do
|
|
9
|
+
api.should_receive(:sp_track_set_starred) do |ptr, buffer, buffer_size, starred|
|
|
10
|
+
ptr.should eq(session)
|
|
11
|
+
buffer.read_array_of_pointer(buffer_size).should eq(tracks)
|
|
12
|
+
starred.should eq(true)
|
|
13
|
+
:ok
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
api.track_set_starred(session, tracks, true).should eq(:ok)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "automatically casts the second parameter to an array" do
|
|
20
|
+
api.should_receive(:sp_track_set_starred) do |ptr, buffer, buffer_size, starred|
|
|
21
|
+
buffer.read_array_of_pointer(1).should eq([track_a])
|
|
22
|
+
buffer_size.should eq(1)
|
|
23
|
+
:ok
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
api.track_set_starred(session, track_a, true).should eq(:ok)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
describe Spotify::APIError do
|
|
2
|
+
let(:context) { nil }
|
|
3
|
+
|
|
4
|
+
describe ".from_native" do
|
|
5
|
+
it "returns an error of the correct class" do
|
|
6
|
+
error = Spotify::APIError.from_native(15, context)
|
|
7
|
+
error.should be_a Spotify::UserNeedsPremiumError
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "returns nil if not an error" do
|
|
11
|
+
Spotify::APIError.from_native(0, context).should be_nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "raises an error if not a valid error code" do
|
|
15
|
+
expect { Spotify::APIError.from_native(1337, context) }
|
|
16
|
+
.to raise_error(ArgumentError, /unknown error code/)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe ".to_i" do
|
|
21
|
+
it "returns the error code" do
|
|
22
|
+
Spotify::APIError.to_i.should be_nil
|
|
23
|
+
Spotify::UserNeedsPremiumError.to_i.should eq(15)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe "#message" do
|
|
28
|
+
it "is a formatted message with an explanation of the error" do
|
|
29
|
+
error = Spotify::UserNeedsPremiumError.new
|
|
30
|
+
error.message.should match /Needs a premium account/
|
|
31
|
+
error.message.should match /15/
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "can be overridden if necessary" do
|
|
35
|
+
error = Spotify::UserNeedsPremiumError.new("hoola hoop")
|
|
36
|
+
error.message.should eq "hoola hoop"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "API mapping" do
|
|
41
|
+
sp_error = API_H_XML.enumerations.each { |enum| break enum if enum.name == "sp_error" }
|
|
42
|
+
sp_error.values.each do |value|
|
|
43
|
+
next if value.name =~ /sp_error_ok/i
|
|
44
|
+
class_name = value.name.downcase.sub(/^sp_error/, "").gsub(/(_|^)(\w)/) { $2.upcase }
|
|
45
|
+
class_name << "Error" unless class_name =~ /Error/
|
|
46
|
+
|
|
47
|
+
describe class_name do
|
|
48
|
+
it "should have the error code number" do
|
|
49
|
+
constant = Spotify.constants.grep(/#{class_name}/i)[0]
|
|
50
|
+
Spotify.const_get(constant).to_i.should eq(value["init"].to_i)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/spec/spotify/api_spec.rb
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
describe Spotify::API do
|
|
2
|
-
describe ".
|
|
3
|
-
it "
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
describe ".attach_function" do
|
|
3
|
+
it "is a retaining class if the method is not creating" do
|
|
4
|
+
begin
|
|
5
|
+
Spotify::API.attach_function :whatever, [], Spotify::User
|
|
6
|
+
rescue FFI::NotFoundError
|
|
7
|
+
# expected, this method does not exist
|
|
8
|
+
end
|
|
6
9
|
|
|
10
|
+
$attached_methods["whatever"][:returns].should eq Spotify::User.retaining_class
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "is a non-retaining class if the method is creating" do
|
|
7
14
|
begin
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
$stderr.read.should include "LAWL"
|
|
12
|
-
ensure
|
|
13
|
-
$stderr = old_stderr
|
|
14
|
-
FFI::Platform::OS.replace(old_platform)
|
|
15
|
+
Spotify::API.attach_function :whatever_create, [], Spotify::User
|
|
16
|
+
rescue FFI::NotFoundError
|
|
17
|
+
# expected, this method does not exist
|
|
15
18
|
end
|
|
19
|
+
|
|
20
|
+
$attached_methods["whatever_create"][:returns].should be Spotify::User
|
|
21
|
+
$attached_methods["whatever_create"][:returns].should_not be Spotify::User.retaining_class
|
|
16
22
|
end
|
|
17
23
|
end
|
|
18
24
|
end
|
|
@@ -4,19 +4,19 @@ describe Spotify::BestEffortString do
|
|
|
4
4
|
it "simply reads a null-terminated string" do
|
|
5
5
|
source = "hello wörld"
|
|
6
6
|
string = Spotify::BestEffortString.to_native(source, nil)
|
|
7
|
-
string.should eq "hello wörld".force_encoding(
|
|
7
|
+
string.should eq "hello wörld".force_encoding(Encoding::BINARY)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
it "cuts the string at the first encountered NULL-byte" do
|
|
11
|
-
source = "hello\x00wörld".force_encoding(
|
|
11
|
+
source = "hello\x00wörld".force_encoding(Encoding::BINARY)
|
|
12
12
|
string = Spotify::BestEffortString.to_native(source, nil)
|
|
13
|
-
string.should eq "hello".force_encoding(
|
|
13
|
+
string.should eq "hello".force_encoding(Encoding::BINARY)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it "treats empty string as empty string, and not null" do
|
|
17
17
|
source = ""
|
|
18
18
|
string = Spotify::BestEffortString.to_native(source, nil)
|
|
19
|
-
string.should eq "".force_encoding(
|
|
19
|
+
string.should eq "".force_encoding(Encoding::BINARY)
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
end
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
describe Spotify::CountryCode do
|
|
2
|
+
let(:context) { nil }
|
|
3
|
+
subject(:type) { Spotify::API.find_type(Spotify::CountryCode) }
|
|
4
|
+
|
|
5
|
+
describe ".from_native" do
|
|
6
|
+
it "decodes a country code" do
|
|
7
|
+
type.from_native(21317, context).should eq "SE"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe ".to_native" do
|
|
12
|
+
it "encodes a country code" do
|
|
13
|
+
type.to_native("SE", context).should eq 21317
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -12,7 +12,7 @@ describe Spotify::ImageID do
|
|
|
12
12
|
let(:image_id) do
|
|
13
13
|
# deliberate NULL in middle of string
|
|
14
14
|
image_id = ":\xD94#\xAD\xD9\x97f\xE0\x00V6\x05\xC6\xE7n\xD2\xB0\xE4P"
|
|
15
|
-
image_id.force_encoding(
|
|
15
|
+
image_id.force_encoding(Encoding::BINARY)
|
|
16
16
|
image_id
|
|
17
17
|
end
|
|
18
18
|
|
|
File without changes
|
|
File without changes
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# coding: utf-8
|
|
2
2
|
describe Spotify::ManagedPointer do
|
|
3
|
-
let(:klass) { described_class }
|
|
4
3
|
let(:null) { FFI::Pointer::NULL }
|
|
5
4
|
let(:pointer) { FFI::Pointer.new(1) }
|
|
6
5
|
let(:klass) { Spotify::User }
|
|
@@ -17,19 +16,17 @@ describe Spotify::ManagedPointer do
|
|
|
17
16
|
api.should_not_receive(:user_release)
|
|
18
17
|
|
|
19
18
|
ptr = retaining_klass.new(FFI::Pointer::NULL)
|
|
20
|
-
ptr.autorelease = false
|
|
21
19
|
ptr.free
|
|
22
20
|
end
|
|
23
21
|
|
|
24
22
|
describe "#release" do
|
|
25
23
|
it "wraps the release pointer properly to avoid type-failures" do
|
|
26
|
-
api.should_receive(:user_release)
|
|
24
|
+
api.should_receive(:user_release) do |pointer|
|
|
27
25
|
pointer.should be_instance_of(klass)
|
|
28
26
|
pointer.should_not be_autorelease # autorelease should be off
|
|
29
27
|
end
|
|
30
28
|
|
|
31
29
|
ptr = klass.new(FFI::Pointer.new(1))
|
|
32
|
-
ptr.autorelease = false
|
|
33
30
|
ptr.free
|
|
34
31
|
end
|
|
35
32
|
end
|
|
@@ -61,6 +58,13 @@ describe Spotify::ManagedPointer do
|
|
|
61
58
|
end
|
|
62
59
|
end
|
|
63
60
|
|
|
61
|
+
describe ".from_native" do
|
|
62
|
+
it "returns nil if pointer is null" do
|
|
63
|
+
native = FFI::Pointer::NULL
|
|
64
|
+
klass.from_native(native, nil).should be_nil
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
64
68
|
describe ".size" do
|
|
65
69
|
it "returns the size of a pointer" do
|
|
66
70
|
Spotify::ManagedPointer.size.should eq FFI.type_size(:pointer)
|
|
@@ -106,21 +110,17 @@ describe Spotify::ManagedPointer do
|
|
|
106
110
|
next unless klass < Spotify::ManagedPointer
|
|
107
111
|
|
|
108
112
|
it "#{klass.name} has a valid retain method" do
|
|
109
|
-
Spotify.should_receive(:
|
|
110
|
-
|
|
111
|
-
method.should match(/_add_ref$/)
|
|
112
|
-
end
|
|
113
|
+
Spotify.should_receive(:"#{klass.type}_add_ref")
|
|
114
|
+
Spotify.should respond_to(:"#{klass.type}_add_ref")
|
|
113
115
|
|
|
114
116
|
klass.retain(FFI::Pointer.new(1))
|
|
115
117
|
end unless klass == Spotify::Session # has no valid retain
|
|
116
118
|
|
|
117
119
|
it "#{klass.name} has a valid release method" do
|
|
118
|
-
Spotify.should_receive(:
|
|
119
|
-
|
|
120
|
-
method.should match(/_release$/)
|
|
121
|
-
end
|
|
120
|
+
Spotify.should_receive(:"#{klass.type}_release")
|
|
121
|
+
Spotify.should respond_to(:"#{klass.type}_release")
|
|
122
122
|
|
|
123
|
-
klass.release(FFI::Pointer.new(1))
|
|
123
|
+
klass.release(FFI::Pointer.new(1)).value
|
|
124
124
|
end
|
|
125
125
|
end
|
|
126
126
|
end
|
|
@@ -100,10 +100,12 @@ describe Spotify::Subscribers do
|
|
|
100
100
|
end
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
+
it "returns an enumerator when not given a block" do
|
|
104
|
+
subscribers.each.should be_a Enumerator
|
|
105
|
+
end
|
|
106
|
+
|
|
103
107
|
it "returns an enumerator with a defined size when not given a block", :ruby_version => ">= 2.0.0" do
|
|
104
|
-
|
|
105
|
-
enumerator.should be_a Enumerator
|
|
106
|
-
enumerator.size.should eq 3
|
|
108
|
+
subscribers.each.size.should eq 3
|
|
107
109
|
end
|
|
108
110
|
|
|
109
111
|
it "yields every subscriber as an UTF-8 encoded string" do
|
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
describe "Spotify
|
|
1
|
+
describe "Spotify types" do
|
|
2
|
+
describe "audio sample types" do
|
|
3
|
+
Spotify::API.enum_type(:sampletype).symbols.each do |symbol|
|
|
4
|
+
specify "#{symbol} has a reader in FFI" do
|
|
5
|
+
FFI::Pointer.new(1).should respond_to "read_array_of_#{symbol}"
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
2
10
|
API_H_XML.enumerations.each do |enum|
|
|
3
|
-
|
|
11
|
+
next if enum["name"] == "sp_error"
|
|
12
|
+
|
|
13
|
+
attached_tag = enum["name"].sub(/\Asp_/, '').to_sym
|
|
14
|
+
attached_enum = Spotify.enum_type(attached_tag)
|
|
15
|
+
unless attached_enum.tag == attached_tag
|
|
16
|
+
raise "Cannot find attached enum for #{enum["name"]}"
|
|
17
|
+
end
|
|
4
18
|
original_enum = enum.values.map { |v| [v["name"].downcase, v["init"]] }
|
|
5
19
|
|
|
6
20
|
describe enum["name"] do
|
|
@@ -19,4 +33,3 @@ describe "Spotify enums" do
|
|
|
19
33
|
end
|
|
20
34
|
end
|
|
21
35
|
end
|
|
22
|
-
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
describe "Spotify::Util" do
|
|
2
|
+
describe ".enum_value!" do
|
|
3
|
+
it "raises an error if given an invalid enum value" do
|
|
4
|
+
expect { Spotify::Util.enum_value!(:moo, "error value") }.to raise_error(ArgumentError)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
it "gives back the enum value for that enum" do
|
|
8
|
+
Spotify::Util.enum_value!(:no_tracks, "search browse").should eq 1
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe ".platform" do
|
|
13
|
+
it "prints a warning containing the OS if platform unknown" do
|
|
14
|
+
suppress = true
|
|
15
|
+
_, err = spy_output(suppress) do
|
|
16
|
+
stub_const("FFI::Platform::OS", "LAWL")
|
|
17
|
+
Spotify::Util.platform
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
err.should match "unknown platform"
|
|
21
|
+
err.should match "LAWL"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
describe Spotify do
|
|
2
|
+
describe "VERSION" do
|
|
3
|
+
it "is defined" do
|
|
4
|
+
defined?(Spotify::VERSION).should eq "constant"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
it "is the same version as in api.h" do
|
|
8
|
+
spotify_version = API_H_SRC.match(/#define\s+SPOTIFY_API_VERSION\s+(\d+)/)[1]
|
|
9
|
+
Spotify::API_VERSION.to_i.should eq spotify_version.to_i
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "proxying" do
|
|
14
|
+
it "responds to the spotify methods" do
|
|
15
|
+
Spotify.should respond_to :error_message
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "allows creating proxy methods" do
|
|
19
|
+
api.should_receive(:error_message).and_return("Some error")
|
|
20
|
+
Spotify.method(:error_message).call.should eq "Some error"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe ".log" do
|
|
25
|
+
it "print nothing if not debugging" do
|
|
26
|
+
out, err = spy_output do
|
|
27
|
+
old_debug, $DEBUG = $DEBUG, false
|
|
28
|
+
Spotify.log "They see me loggin'"
|
|
29
|
+
$DEBUG = old_debug
|
|
30
|
+
end
|
|
31
|
+
out.should be_empty
|
|
32
|
+
err.should be_empty
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "prints output and path if debugging" do
|
|
36
|
+
suppress = true
|
|
37
|
+
out, err = spy_output(suppress) do
|
|
38
|
+
old_debug, $DEBUG = $DEBUG, true
|
|
39
|
+
Spotify.log "Testin' Spotify log"
|
|
40
|
+
$DEBUG = old_debug
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
out.should match "Testin' Spotify log"
|
|
44
|
+
out.should match "spec/spotify_spec.rb"
|
|
45
|
+
|
|
46
|
+
err.should be_empty
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe ".try" do
|
|
51
|
+
it "raises an error when the result is not OK" do
|
|
52
|
+
api.should_receive(:error_example).and_return(Spotify::APIError.from_native(5, nil))
|
|
53
|
+
expect { Spotify.try(:error_example) }.to raise_error(Spotify::BadApplicationKeyError, /Invalid application key/)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "does not raise an error when the result is OK" do
|
|
57
|
+
api.should_receive(:error_example).and_return(nil)
|
|
58
|
+
Spotify.try(:error_example).should eq nil
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "does not raise an error when the result is not an error-type" do
|
|
62
|
+
result = Object.new
|
|
63
|
+
api.should_receive(:error_example).and_return(result)
|
|
64
|
+
Spotify.try(:error_example).should eq result
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "does not raise an error when the resource is loading" do
|
|
68
|
+
api.should_receive(:error_example).and_return(Spotify::APIError.from_native(17, nil))
|
|
69
|
+
error = Spotify.try(:error_example)
|
|
70
|
+
error.should be_a(Spotify::IsLoadingError)
|
|
71
|
+
error.message.should match /Resource not loaded yet/
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
module Spotify
|
|
2
2
|
# used to find the actual type of a thing
|
|
3
3
|
def self.resolve_type(type)
|
|
4
|
-
if type.is_a?(Class) and type <= Spotify::ManagedPointer
|
|
4
|
+
found = if type.is_a?(Class) and type <= Spotify::ManagedPointer
|
|
5
|
+
type
|
|
6
|
+
elsif type == Spotify::APIError
|
|
5
7
|
type
|
|
6
8
|
elsif type.respond_to?(:native_type)
|
|
7
9
|
type.native_type
|
|
8
10
|
else
|
|
9
11
|
type = Spotify::API.find_type(type)
|
|
10
|
-
type = type.type if type.respond_to?(:type)
|
|
11
12
|
type
|
|
12
13
|
end
|
|
14
|
+
|
|
15
|
+
found = found.type while found.respond_to?(:type)
|
|
16
|
+
found
|
|
13
17
|
end
|
|
14
18
|
|
|
15
19
|
# @return [Array<FFI::Struct>] all structs in Spotify namespace
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require "stringio"
|
|
2
|
+
|
|
3
|
+
def spy_output(suppress = false)
|
|
4
|
+
old_out, $stdout = $stdout, StringIO.new
|
|
5
|
+
old_err, $stderr = $stderr, StringIO.new
|
|
6
|
+
yield
|
|
7
|
+
out = $stdout.tap(&:rewind).read
|
|
8
|
+
err = $stderr.tap(&:rewind).read
|
|
9
|
+
[out, err]
|
|
10
|
+
ensure
|
|
11
|
+
old_out.write(out) if not suppress and out
|
|
12
|
+
old_err.write(err) if not suppress and err
|
|
13
|
+
|
|
14
|
+
$stderr = old_err
|
|
15
|
+
$stdout = old_out
|
|
16
|
+
end
|