hallon 0.1.1 → 0.2.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/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