hallon 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -8,21 +8,7 @@ require 'yard'
8
8
  YARD::Rake::YardocTask.new
9
9
 
10
10
  require 'rspec/core/rake_task'
11
-
12
- desc "Run all specs (even those requiring logging in to Spotify)"
13
- RSpec::Core::RakeTask.new('spec:full')
14
-
15
- desc "Run all specs like spec:full, but with debug mode and full warnings enabled"
16
- RSpec::Core::RakeTask.new('spec:debug') do |task|
17
- task.skip_bundler = true
18
- task.ruby_opts = '-d -W2'
19
- end
20
-
21
- desc "Run all offline specs"
22
- RSpec::Core::RakeTask.new('spec') do |task|
23
- task.pattern = 'spec/hallon/*_spec.rb'
24
- task.rspec_opts = '--tag ~logged_in'
25
- end
11
+ RSpec::Core::RakeTask.new('spec')
26
12
 
27
13
  desc "Run the full test suite and generate a coverage report"
28
14
  task 'spec:cov' => ['clean', 'spec:full'] do
data/hallon.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.required_ruby_version = '~> 1.9'
20
20
 
21
21
  gem.add_dependency 'spotify', '~> 8.0.5'
22
+ gem.add_development_dependency 'mockspotify', '~> 0.1.2'
22
23
  gem.add_development_dependency 'rake', '~> 0.8'
23
24
  gem.add_development_dependency 'rspec', '~> 2'
24
25
  gem.add_development_dependency 'autotest-standalone'
data/lib/hallon/error.rb CHANGED
@@ -40,14 +40,13 @@ module Hallon
40
40
  # @return [nil]
41
41
  def maybe_raise(error)
42
42
  error, symbol = disambiguate(error)
43
+ return symbol if symbol == :ok
43
44
 
44
- unless symbol == :ok
45
- message = []
46
- message << "[#{symbol.upcase}]"
47
- message << explain(error)
48
- message << "(#{error})"
49
- raise Hallon::Error, message.join(' ')
50
- end
45
+ message = []
46
+ message << "[#{symbol.upcase}]"
47
+ message << explain(error)
48
+ message << "(#{error})"
49
+ raise Hallon::Error, message.join(' ')
51
50
  end
52
51
  end
53
52
  end
@@ -121,6 +121,7 @@ module Hallon
121
121
  end
122
122
  end
123
123
  end
124
+ alias :wait_for :process_events_on
124
125
 
125
126
  # Log into Spotify using the given credentials.
126
127
  #
@@ -3,5 +3,5 @@ module Hallon
3
3
  # Current release version of Hallon
4
4
  #
5
5
  # @see http://semver.org/
6
- VERSION = [0, 1, 1].join('.')
6
+ VERSION = [0, 2, 0].join('.')
7
7
  end
@@ -8,4 +8,4 @@ def example_uris
8
8
  "spotify:user:burgestrand" => :profile,
9
9
  "spotify:user:burgestrand:starred" => :starred,
10
10
  }
11
- end
11
+ end
@@ -1,30 +1,39 @@
1
1
  describe Hallon::Error do
2
2
  subject { described_class }
3
-
3
+
4
4
  it { should <= RuntimeError }
5
-
5
+
6
6
  describe "::disambiguate" do
7
7
  it "should not fail on invalid numbers" do
8
8
  subject.disambiguate(10000).should eq [-1, nil]
9
9
  end
10
-
10
+
11
11
  it "should not fail on invalid symbols" do
12
12
  subject.disambiguate(:fail).should eq [-1, nil]
13
13
  end
14
14
  end
15
-
15
+
16
16
  describe "::explain" do
17
- it { subject.explain(0).should eq 'No error' }
18
- it { subject.explain(-1).should eq 'invalid error code' }
17
+ it "should work properly given an integer" do
18
+ subject.explain(0).should eq 'sp_error: 0'
19
+ end
20
+
21
+ it "should work properly given a symbol" do
22
+ subject.explain(:bad_api_version).should eq 'sp_error: 1'
23
+ end
19
24
  end
20
-
25
+
21
26
  describe "::maybe_raise" do
22
27
  it "should not raise error when given 0 as error code" do
23
28
  expect { subject.maybe_raise(0) }.to_not raise_error
24
29
  end
25
-
30
+
26
31
  it "should raise error when given non-0 as error code" do
27
32
  expect { subject.maybe_raise(1) }.to raise_error(Hallon::Error)
28
33
  end
34
+
35
+ it "should return the error symbol if it's ok" do
36
+ subject.maybe_raise(0).should eq :ok
37
+ end
29
38
  end
30
- end
39
+ end
@@ -1,6 +1,6 @@
1
1
  describe Hallon do
2
2
  describe "VERSION" do
3
- specify { Hallon::VERSION.should == "0.0.0" }
3
+ specify { Hallon::VERSION.should be_a String }
4
4
  end
5
5
 
6
6
  describe "API_VERSION" do
@@ -1,37 +1,44 @@
1
1
  # coding: utf-8
2
- describe Hallon::Image, :logged_in => true do
3
- context "created from a Spotify URI" do
4
- before(:all) do
5
- @uri = "spotify:image:3ad93423add99766e02d563605c6e76ed2b0e450"
6
- @image = Hallon::Image.new @uri
7
- @image.status.should eq :is_loading
8
- session.process_events_on { @image.loaded? }
9
- end
2
+ require 'ostruct'
10
3
 
11
- subject { @image }
4
+ describe Hallon::Image, :session => true do
5
+ let(:session) { double.stub(:pointer).and_return(nil) }
6
+ let(:image) do
7
+ Hallon::Session.should_receive(:instance).and_return double.stub(:pointer => nil)
12
8
 
13
- its(:status) { should be :ok }
14
- its(:format) { should be :jpeg }
9
+ image = Spotify.mock_image(
10
+ "3ad93423add99766e02d563605c6e76ed2b0e450".gsub(/../) { |x| x.to_i(16).chr },
11
+ :jpeg,
12
+ File.size(fixture_image_path),
13
+ File.read(fixture_image_path),
14
+ :ok
15
+ )
15
16
 
16
- specify "its #id should match its’ spotify uri" do
17
- @uri.should match @image.id
18
- end
17
+ Hallon::Image.new(image)
18
+ end
19
+
20
+ subject { image }
19
21
 
20
- describe "#data" do
21
- it "should correspond to the fixture image" do
22
- @image.data.should eq File.read(fixture_image_path, :encoding => 'binary')
23
- end
22
+ its(:status) { should be :ok }
23
+ its(:format) { should be :jpeg }
24
+ its(:id) { should eq "3ad93423add99766e02d563605c6e76ed2b0e450" }
24
25
 
25
- it "should have a binary encoding" do
26
- @image.data.encoding.name.should eq 'ASCII-8BIT'
27
- end
26
+ describe "#data" do
27
+ it "should correspond to the fixture image" do
28
+ image.data.should eq File.read(fixture_image_path, :encoding => 'binary')
29
+ end
30
+
31
+ it "should have a binary encoding" do
32
+ image.data.encoding.name.should eq 'ASCII-8BIT'
28
33
  end
29
34
  end
30
35
 
31
36
  describe "callbacks" do
32
37
  it "should trigger :load when loaded" do
38
+ pending "waiting for mockspotify event system"
39
+
33
40
  uri = "spotify:image:c78f091482e555bd2ffacfcd9cbdc0714b221663"
34
- image = Hallon::Image.new(uri)
41
+ image = Hallon::Image.new(uri, session)
35
42
  image.should_not be_loaded
36
43
  image.should_receive(:trigger).with(:load).once
37
44
 
@@ -1,4 +1,4 @@
1
- describe Hallon::Link, :session => true do
1
+ describe Hallon::Link do
2
2
  subject { Hallon::Link.new("spotify:user:burgestrand") }
3
3
 
4
4
  context "class methods" do
@@ -1,5 +1,26 @@
1
+ # coding: utf-8
1
2
  describe Hallon::Session do
2
- include_context "initialized session"
3
+ it { Hallon::Session.should_not respond_to :new }
4
+
5
+ describe "#instance" do
6
+ it "should require an application key" do
7
+ expect { Hallon::Session.send(:new) }.to raise_error(ArgumentError)
8
+ end
9
+ end
10
+
11
+ describe "#new" do
12
+ it "should fail on an invalid application key" do
13
+ expect { create_session(false) }.to raise_error(Hallon::Error, /BAD_APPLICATION_KEY/)
14
+ end
15
+
16
+ it "should fail on a small user-agent of multibyte chars (> 255 characters)" do
17
+ expect { create_session(true, :user_agent => 'ö' * 128) }.to raise_error(ArgumentError)
18
+ end
19
+
20
+ it "should fail on a huge user agent (> 255 characters)" do
21
+ expect { create_session(true, :user_agent => 'a' * 256) }.to raise_error(ArgumentError)
22
+ end
23
+ end
3
24
 
4
25
  describe "options" do
5
26
  subject { session.options }
@@ -54,7 +75,7 @@ describe Hallon::Session do
54
75
 
55
76
  describe "#relation_type?" do
56
77
  it "should retrieve the relation between the current user and given user" do
57
- session.relation_type?(session.user).should eq :unknown
78
+ session.relation_type?(session.user).should eq :none
58
79
  end
59
80
  end
60
81
  end
@@ -28,34 +28,34 @@ describe Hallon::User do
28
28
  end
29
29
 
30
30
  describe "an instance", :logged_in => true do
31
- let(:link) { Hallon::Link.new("spotify:user:burgestrand") }
32
- let(:user) { Hallon::User.new(link) }
33
- subject { user }
34
-
35
- before(:all) do
36
- session.process_events_on(:userinfo_updated) { user.loaded? }
31
+ let(:user) do
32
+ user = Spotify.mock_user(
33
+ "burgestrand", "Burgestrand", "Kim Burgestrand",
34
+ "https://secure.gravatar.com/avatar/b67b73b5b1fd84119ec788b1c3df02ad",
35
+ :none, true
36
+ )
37
+ Hallon::User.new(user)
37
38
  end
38
39
 
40
+ subject { user }
41
+
39
42
  describe "#to_link" do
40
43
  it "should return a Link for this user" do
41
- user.to_link.should eq link
44
+ user.to_link.should eq "spotify:user:burgestrand"
42
45
  end
43
46
  end
44
47
 
45
48
  describe "#name" do
46
49
  it "should be able to get the display name" do
47
- Spotify.should_receive(:user_display_name)
48
- user.name(:display).should be_a String
50
+ user.name(:display).should eq "Burgestrand"
49
51
  end
50
52
 
51
53
  it "should be able to get the full name" do
52
- Spotify.should_receive(:user_full_name)
53
- user.name(:full).should be_a String
54
+ user.name(:full).should eq "Kim Burgestrand"
54
55
  end
55
56
 
56
57
  it "should get the canonical name when unspecified" do
57
- Spotify.should_receive(:user_canonical_name)
58
- user.name.should be_a String
58
+ user.name.should eq "burgestrand"
59
59
  end
60
60
 
61
61
  it "should fail on invalid name types" do
@@ -65,8 +65,7 @@ describe Hallon::User do
65
65
 
66
66
  describe "#picture" do
67
67
  it "should retrieve the user picture" do
68
- Spotify.should_receive(:user_picture)
69
- user.picture.should be_a String
68
+ user.picture.should eq "https://secure.gravatar.com/avatar/b67b73b5b1fd84119ec788b1c3df02ad"
70
69
  end
71
70
  end
72
71
  end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ require 'mockspotify'
2
3
  require 'hallon'
3
4
 
4
5
  # Bail on failure
@@ -7,65 +8,28 @@ Thread.abort_on_exception = true
7
8
  RSpec.configure do |config|
8
9
  config.treat_symbols_as_metadata_keys_with_true_values = true
9
10
 
10
- def options
11
+ def fixture_image_path
12
+ File.expand_path('../fixtures/pink_cover.jpg', __FILE__)
13
+ end
14
+
15
+ def create_session(valid_appkey = true, options = options)
16
+ appkey = valid_appkey ? 'appkey_good' : 'appkey_bad'
17
+ Hallon::Session.send(:new, appkey, options)
18
+ end
19
+ end
20
+
21
+ RSpec::Core::ExampleGroup.instance_eval do
22
+ let(:options) do
11
23
  {
12
24
  :user_agent => "Hallon (rspec)",
13
25
  :settings_path => "tmp",
14
- :cache_path => "tmp/cache"
26
+ :cache_path => ""
15
27
  }
16
28
  end
17
29
 
18
- def session
19
- @session ||= Hallon::Session.instance(Hallon::APPKEY, options)
20
- end
21
-
22
- def fixture_image_path
23
- File.expand_path('../fixtures/pink_cover.jpg', __FILE__)
24
- end
30
+ let(:session) { create_session }
25
31
  end
26
32
 
27
33
  # Requires supporting files in ./support/ and ./fixtures/
28
34
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
29
35
  Dir["#{File.dirname(__FILE__)}/fixtures/**/*.rb"].each {|f| require f}
30
-
31
- unless ENV.values_at(*%w(HALLON_APPKEY HALLON_USERNAME HALLON_PASSWORD)).all?
32
- abort <<-ERROR
33
- You must supply a valid Spotify username, password and application
34
- key in order to run Hallons specs. This is done by setting these
35
- environment variables:
36
-
37
- - HALLON_APPKEY (path to spotify_appkey.key)
38
- - HALLON_USERNAME (your spotify username)
39
- - HALLON_PASSWORD (your spotify password)
40
- ERROR
41
- end
42
-
43
- module Hallon
44
- APPKEY ||= IO.read File.expand_path(ENV['HALLON_APPKEY'])
45
- end
46
-
47
- # Hallon::Session#instance requires that a Session object have not been created
48
- # so test it here instead. This assures it is tested before anything else!
49
- describe Hallon::Session do
50
- it { Hallon::Session.should_not respond_to :new }
51
-
52
- describe "#instance" do
53
- it "should require an application key" do
54
- expect { Hallon::Session.instance }.to raise_error(ArgumentError)
55
- end
56
-
57
- it "should fail on an invalid application key" do
58
- expect { Hallon::Session.instance('invalid') }.to raise_error(Hallon::Error, /BAD_APPLICATION_KEY/)
59
- end
60
-
61
- it "should fail on a small user-agent of multibyte chars (> 255 characters)" do
62
- expect { Hallon::Session.send(:new, Hallon::APPKEY, :user_agent => 'ö' * 128) }.
63
- to raise_error(ArgumentError)
64
- end
65
-
66
- it "should fail on a huge user agent (> 255 characters)" do
67
- expect { Hallon::Session.send(:new, Hallon::APPKEY, :user_agent => 'a' * 256) }.
68
- to raise_error(ArgumentError)
69
- end
70
- end
71
- end
@@ -1,16 +1,11 @@
1
1
  shared_context "logged in", :logged_in do
2
2
  before(:all) do
3
- unless session.logged_in?
4
- session.login ENV['HALLON_USERNAME'], ENV['HALLON_PASSWORD']
5
- logged_in = session.process_events_on(:logged_in) { |error| error }
6
- logged_in.should eq :ok
7
-
8
- finished = session.process_events_on(:connection_error) { |error| session.logged_in? or error }
9
- finished.should be_true
10
- end
11
-
3
+ session.login 'username', 'password'
12
4
  session.should be_logged_in
13
5
  end
14
6
 
15
- before(:each) { session.should be_logged_in }
7
+ after(:all) do
8
+ session.logout
9
+ session.should_not be_logged_in
10
+ end
16
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hallon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-18 00:00:00.000000000Z
12
+ date: 2011-07-21 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: spotify
16
- requirement: &2152996240 !ruby/object:Gem::Requirement
16
+ requirement: &2153174180 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,21 @@ dependencies:
21
21
  version: 8.0.5
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2152996240
24
+ version_requirements: *2153174180
25
+ - !ruby/object:Gem::Dependency
26
+ name: mockspotify
27
+ requirement: &2153173600 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.1.2
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2153173600
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: rake
27
- requirement: &2152995280 !ruby/object:Gem::Requirement
38
+ requirement: &2153172780 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ~>
@@ -32,10 +43,10 @@ dependencies:
32
43
  version: '0.8'
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *2152995280
46
+ version_requirements: *2153172780
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: rspec
38
- requirement: &2152994340 !ruby/object:Gem::Requirement
49
+ requirement: &2153171860 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ~>
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: '2'
44
55
  type: :development
45
56
  prerelease: false
46
- version_requirements: *2152994340
57
+ version_requirements: *2153171860
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: autotest-standalone
49
- requirement: &2152993140 !ruby/object:Gem::Requirement
60
+ requirement: &2153171320 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: '0'
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *2152993140
68
+ version_requirements: *2153171320
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: autotest-growl
60
- requirement: &2152992000 !ruby/object:Gem::Requirement
71
+ requirement: &2153170600 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: '0'
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *2152992000
79
+ version_requirements: *2153170600
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: cover_me
71
- requirement: &2152989700 !ruby/object:Gem::Requirement
82
+ requirement: &2153169940 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,10 +87,10 @@ dependencies:
76
87
  version: '0'
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *2152989700
90
+ version_requirements: *2153169940
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: yard
82
- requirement: &2152979360 !ruby/object:Gem::Requirement
93
+ requirement: &2153169300 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ! '>='
@@ -87,10 +98,10 @@ dependencies:
87
98
  version: '0'
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *2152979360
101
+ version_requirements: *2153169300
91
102
  - !ruby/object:Gem::Dependency
92
103
  name: rdiscount
93
- requirement: &2152978740 !ruby/object:Gem::Requirement
104
+ requirement: &2153168620 !ruby/object:Gem::Requirement
94
105
  none: false
95
106
  requirements:
96
107
  - - ! '>='
@@ -98,7 +109,7 @@ dependencies:
98
109
  version: '0'
99
110
  type: :development
100
111
  prerelease: false
101
- version_requirements: *2152978740
112
+ version_requirements: *2153168620
102
113
  description:
103
114
  email: kim@burgestrand.se
104
115
  executables: []
@@ -146,7 +157,6 @@ files:
146
157
  - spec/hallon/user_spec.rb
147
158
  - spec/spec_helper.rb
148
159
  - spec/support/.gitkeep
149
- - spec/support/context_initialized_session.rb
150
160
  - spec/support/context_logged_in.rb
151
161
  - spec/support/cover_me.rb
152
162
  - spec/support/shared_for_loadable_objects.rb
@@ -190,7 +200,6 @@ test_files:
190
200
  - spec/hallon/user_spec.rb
191
201
  - spec/spec_helper.rb
192
202
  - spec/support/.gitkeep
193
- - spec/support/context_initialized_session.rb
194
203
  - spec/support/context_logged_in.rb
195
204
  - spec/support/cover_me.rb
196
205
  - spec/support/shared_for_loadable_objects.rb
@@ -1,3 +0,0 @@
1
- shared_context "initialized session", :session do
2
- before(:all) { @session = session }
3
- end