rbrainz 0.1.0 → 0.1.1

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.
@@ -1,4 +1,4 @@
1
- # $Id: query.rb 4 2007-05-21 02:04:26Z phw $
1
+ # $Id: query.rb 31 2007-05-29 02:38:42Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -16,8 +16,7 @@ module MusicBrainz
16
16
  end
17
17
 
18
18
  def get_artist_by_id(id, include = nil)
19
- xml = @webservice.get(Model::Artist.entity_type, id, :include => include)
20
- return MBXML.new(xml).get_entity(Model::Artist.entity_type)
19
+ return get_entity_by_id(Model::Artist.entity_type, id, include)
21
20
  end
22
21
 
23
22
  # TODO: implement
@@ -26,8 +25,7 @@ module MusicBrainz
26
25
  end
27
26
 
28
27
  def get_release_by_id(id, include = nil)
29
- xml = @webservice.get(Model::Release.entity_type, id, :include => include)
30
- return MBXML.new(xml).get_entity(Model::Release.entity_type)
28
+ return get_entity_by_id(Model::Release.entity_type, id, include)
31
29
  end
32
30
 
33
31
  # TODO: implement
@@ -36,8 +34,7 @@ module MusicBrainz
36
34
  end
37
35
 
38
36
  def get_track_by_id(id, include = nil)
39
- xml = @webservice.get(Model::Track.entity_type, id, :include => include)
40
- return MBXML.new(xml).get_entity(Model::Track.entity_type)
37
+ return get_entity_by_id(Model::Track.entity_type, id, include)
41
38
  end
42
39
 
43
40
  # TODO: implement
@@ -46,8 +43,7 @@ module MusicBrainz
46
43
  end
47
44
 
48
45
  def get_label_by_id(id, include = nil)
49
- xml = @webservice.get(Model::Label.entity_type, id, :include => include)
50
- return MBXML.new(xml).get_entity(Model::Label.entity_type)
46
+ return get_entity_by_id(Model::Label.entity_type, id, include)
51
47
  end
52
48
 
53
49
  # TODO: implement
@@ -55,6 +51,14 @@ module MusicBrainz
55
51
  raise NotImplementedError.new
56
52
  end
57
53
 
54
+ private
55
+
56
+ # Helper method which will return any entity by ID.
57
+ def get_entity_by_id(entity_type, id, include)
58
+ xml = @webservice.get(entity_type, id, :include => include)
59
+ return MBXML.new(xml).get_entity(entity_type)
60
+ end
61
+
58
62
  end
59
63
 
60
64
  end
@@ -1,4 +1,4 @@
1
- # $Id: webservice.rb 4 2007-05-21 02:04:26Z phw $
1
+ # $Id: webservice.rb 36 2007-05-29 18:43:36Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -22,7 +22,7 @@ module MusicBrainz
22
22
  # Must be implemented by the concrete webservices.
23
23
  # TODO: Specify and implement in Webservice.
24
24
  def post
25
- raise Exception.new('Called abstract method.')
25
+ raise NotImplementedError.new('Called abstract method.')
26
26
  end
27
27
 
28
28
  end
@@ -31,24 +31,54 @@ module MusicBrainz
31
31
  # TODO: Implement authorization.
32
32
  class Webservice < IWebservice
33
33
 
34
+ # Timeouts for opening and reading connections (in seconds)
35
+ attr_accessor :open_timeout, :read_timeout
36
+
34
37
  def initialize(options = {:host => nil, :port => nil, :path_prefix => nil})
35
38
  @host = options[:host] ? options[:host] : 'musicbrainz.org'
36
39
  @port = options[:port] ? options[:port] : 80
37
40
  @path_prefix = options[:path_prefix] ? options[:path_prefix] : '/ws'
41
+ @open_timeout = nil
42
+ @read_timeout = nil
38
43
  end
39
44
 
40
45
  # Query the Webservice with HTTP GET.
41
- # TODO: Exception handling.
46
+ #
47
+ # Raises: +RequestError+, +ResourceNotFoundError+, +AuthenticationError+,
48
+ # +ConnectionError+
42
49
  def get(entity, id, options = {:include => nil, :filter => nil, :version => 1})
43
50
  url = URI.parse(create_uri(entity, id, options))
44
- req = Net::HTTP::Get.new(url.request_uri)
45
- res = Net::HTTP.start(url.host, url.port) {|http|
46
- http.request(req)
47
- }
48
- return res.body
51
+ request = Net::HTTP::Get.new(url.request_uri)
52
+ connection = Net::HTTP.new(url.host, url.port)
53
+
54
+ # Set timeouts
55
+ connection.open_timeout = @open_timeout if @open_timeout
56
+ connection.read_timeout = @read_timeout if @read_timeout
57
+
58
+ # Make the request
59
+ begin
60
+ response = connection.start {|http|
61
+ http.request(request)
62
+ }
63
+ rescue Timeout::Error, Errno::ETIMEDOUT
64
+ raise ConnectionError.new('%s timed out' % url.to_s)
65
+ end
66
+
67
+ # Handle response errors.
68
+ if response.is_a? Net::HTTPBadRequest # 400
69
+ raise RequestError.new(url.to_s)
70
+ elsif response.is_a? Net::HTTPUnauthorized # 401
71
+ raise AuthenticationError.new(url.to_s)
72
+ elsif response.is_a? Net::HTTPNotFound # 404
73
+ raise ResourceNotFoundError.new(url.to_s)
74
+ elsif not response.is_a? Net::HTTPSuccess
75
+ raise ConnectionError.new(response.class.name)
76
+ end
77
+
78
+ return response.body
49
79
  end
50
80
 
51
- private
81
+ private # ----------------------------------------------------------------
52
82
 
53
83
  # Builds a request URI for querying the webservice.
54
84
  def create_uri(entity, id, options = {:include => nil, :filter => nil, :version => 1})
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_entity.rb 29 2007-05-29 02:03:36Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -50,9 +50,71 @@ module TestEntity
50
50
  assert_equal nil, entity.id
51
51
  end
52
52
 
53
- # Relations will get implemented in version 0.1.1
54
- #def test_relations
55
- # assert false, 'Unit test for ' + self.class.name + ' not implemented!'
56
- #end
53
+ def test_relations
54
+ entity = @tested_class.new
55
+
56
+ # Create some test relations
57
+ artist_rel = Model::Relation.new
58
+ artist_rel.target = Model::Artist.new
59
+ artist_rel.type = Model::NS_REL_1 + 'Vocal'
60
+ artist_rel.direction = Model::Relation::DIR_BACKWARD
61
+ artist_rel.attributes << 'Guest'
62
+ artist_rel.attributes << 'Lead'
63
+ assert_nothing_raised {entity.add_relation artist_rel}
64
+
65
+ track_rel = Model::Relation.new
66
+ track_rel.target = Model::Track.new
67
+ track_rel.type = Model::NS_REL_1 + 'Vocal'
68
+ track_rel.direction = Model::Relation::DIR_FORWARD
69
+ track_rel.attributes << 'Lead'
70
+ track_rel.attributes << 'Guest'
71
+ assert_nothing_raised {entity.add_relation track_rel}
72
+
73
+ url_rel = Model::Relation.new
74
+ url_rel.target = 'http://www.example.com'
75
+ url_rel.type = Model::NS_REL_1 + 'OfficialHomepage'
76
+ assert_nothing_raised {entity.add_relation url_rel}
77
+
78
+ # Get all relations
79
+ rel_list = []
80
+ assert_nothing_raised {rel_list = entity.get_relations()}
81
+ assert_equal 3, rel_list.size
82
+ assert rel_list.include?(artist_rel)
83
+ assert rel_list.include?(track_rel)
84
+ assert rel_list.include?(url_rel)
85
+
86
+ # Get only artist relation by target type
87
+ assert_nothing_raised {rel_list = entity.get_relations(
88
+ :target_type => Model::Relation::TO_ARTIST)}
89
+ assert_equal 1, rel_list.size
90
+ assert rel_list.include?(artist_rel)
91
+
92
+ # Get only url relation type
93
+ assert_nothing_raised {rel_list = entity.get_relations(
94
+ :relation_type => Model::NS_REL_1 + 'OfficialHomepage')}
95
+ assert_equal 1, rel_list.size
96
+ assert rel_list.include?(url_rel)
97
+
98
+ # Get only artist and track relation by attribute
99
+ assert_nothing_raised {rel_list = entity.get_relations(
100
+ :required_attributes => ['Guest', 'Lead'])}
101
+ assert_equal 2, rel_list.size
102
+ assert rel_list.include?(artist_rel)
103
+ assert rel_list.include?(track_rel)
104
+
105
+ # Get only artist relation by target type
106
+ assert_nothing_raised {rel_list = entity.get_relations(
107
+ :direction => Model::Relation::DIR_BACKWARD)}
108
+ assert_equal 1, rel_list.size
109
+ assert rel_list.include?(artist_rel)
110
+
111
+ # Test the target types
112
+ target_types = entity.relation_target_types
113
+ assert_equal 3, target_types.size, target_types.inspect
114
+ [Model::Relation::TO_ARTIST, Model::Relation::TO_TRACK,
115
+ Model::Relation::TO_URL].each {|type|
116
+ assert target_types.include?(type), target_types.inspect
117
+ }
118
+ end
57
119
 
58
120
  end
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: testing_helper.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
data/test/test_alias.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_alias.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
data/test/test_artist.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_artist.rb 30 2007-05-29 02:12:33Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -100,13 +100,6 @@ class TestArtist < Test::Unit::TestCase
100
100
  assert_equal 0, artist.releases.size
101
101
  end
102
102
 
103
- # You can pass an array of releases to add them all.
104
- def test_add_several_releases_at_once
105
- artist = Model::Artist.new
106
- assert_nothing_raised {artist.releases = @releases}
107
- assert_equal @releases, artist.releases
108
- end
109
-
110
103
  # Many aliases can be added
111
104
  def test_add_and_remove_aliases
112
105
  artist = Model::Artist.new
@@ -122,11 +115,4 @@ class TestArtist < Test::Unit::TestCase
122
115
  assert_equal 0, artist.aliases.size
123
116
  end
124
117
 
125
- # You can pass an array of aliases to add them all.
126
- def test_add_several_aliases_at_once
127
- artist = Model::Artist.new
128
- assert_nothing_raised {artist.aliases = @aliases}
129
- assert_equal @aliases, artist.aliases
130
- end
131
-
132
118
  end
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_artist_filter.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_artist_includes.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
data/test/test_disc.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_disc.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_incomplete_date.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
data/test/test_label.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_label.rb 30 2007-05-29 02:12:33Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -119,11 +119,4 @@ class TestLabel < Test::Unit::TestCase
119
119
  assert_equal 0, label.releases.size
120
120
  end
121
121
 
122
- # You can pass an array of releases to add them all.
123
- def test_add_several_releases_at_once
124
- label = Model::Label.new
125
- assert_nothing_raised {label.releases = @releases}
126
- assert_equal @releases, label.releases
127
- end
128
-
129
122
  end
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_label_filter.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_label_includes.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
data/test/test_mbid.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_mbid.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
data/test/test_mbxml.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_mbxml.rb 33 2007-05-29 14:48:47Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -107,7 +107,25 @@ class TestMBXML < Test::Unit::TestCase
107
107
  mbxml = Webservice::MBXML.new IO.read(DATA_PATH + 'artist/Tori_Amos_3.xml')
108
108
  artist = mbxml.get_entity(:artist)
109
109
 
110
- assert false, 'Test not implemented'
110
+ assert_equal 'c0b2500e-0cef-4130-869d-732b23ed9df5', artist.id.uuid
111
+ assert_equal Model::Artist::TYPE_PERSON, artist.type
112
+ assert_equal 'Tori Amos', artist.name
113
+ assert_equal 'Amos, Tori', artist.sort_name
114
+ assert_equal '1963-08-22', artist.begin_date.to_s
115
+
116
+ artist_rels = artist.get_relations(:target_type => Model::Relation::TO_ARTIST)
117
+ assert_equal 1, artist_rels.size
118
+ assert_equal Model::NS_REL_1 + 'Married', artist_rels[0].type
119
+ assert_equal Model::Relation::DIR_BACKWARD, artist_rels[0].direction
120
+ assert_equal Model::IncompleteDate.new('1998'), artist_rels[0].begin_date
121
+ assert artist_rels[0].target.is_a?(Model::Artist)
122
+
123
+ url_rels = artist.get_relations(:target_type => Model::Relation::TO_URL)
124
+ assert_equal 2, url_rels.size
125
+ assert_equal Model::NS_REL_1 + 'Discography', url_rels[0].type
126
+ assert_equal 'http://www.yessaid.com/albums.html', url_rels[0].target
127
+ assert_equal Model::NS_REL_1 + 'Wikipedia', url_rels[1].type
128
+ assert_equal 'http://en.wikipedia.org/wiki/Tori_Amos', url_rels[1].target
111
129
  end
112
130
 
113
131
  def test_artist_tori_amos_4
@@ -283,7 +301,17 @@ class TestMBXML < Test::Unit::TestCase
283
301
  mbxml = Webservice::MBXML.new IO.read(DATA_PATH + 'track/Silent_All_These_Years_2.xml')
284
302
  track = mbxml.get_entity(:track)
285
303
 
286
- assert false, 'Test not implemented'
304
+ assert_equal 'd6118046-407d-4e06-a1ba-49c399a4c42f', track.id.uuid
305
+ assert_equal 'Silent All These Years', track.title
306
+ assert_equal 253466, track.duration
307
+ assert_equal 'c0b2500e-0cef-4130-869d-732b23ed9df5', track.artist.id.uuid
308
+
309
+ track_rels = track.get_relations(:target_type => Model::Relation::TO_TRACK)
310
+ assert_equal 1, track_rels.size, track.get_relations.inspect
311
+ assert_equal Model::NS_REL_1 + 'Cover', track_rels[0].type
312
+ assert_equal Model::Relation::DIR_BACKWARD, track_rels[0].direction
313
+ assert track_rels[0].target.is_a?(Model::Track)
314
+ assert_equal '5bcd4eaa-fae7-465f-9f03-d005b959ed02', track_rels[0].target.artist.id.uuid
287
315
  end
288
316
 
289
317
  def test_track_silent_all_these_years_3
@@ -313,11 +341,18 @@ class TestMBXML < Test::Unit::TestCase
313
341
  assert_equal '42ab76ea-5d42-4259-85d7-e7f2c69e4485', track.puids[6]
314
342
  end
315
343
 
344
+ # This test is similiar to silent_all_these_years_3, but it includes an
345
+ # schema exctension which mustn't disturb the parsing.
316
346
  def test_track_silent_all_these_years_5
317
347
  mbxml = Webservice::MBXML.new IO.read(DATA_PATH + 'track/Silent_All_These_Years_5.xml')
318
348
  track = mbxml.get_entity(:track)
319
349
 
320
- assert false, 'Test not implemented'
350
+ assert_equal 'd6118046-407d-4e06-a1ba-49c399a4c42f', track.id.uuid
351
+ assert_equal 'Silent All These Years', track.title
352
+ assert_equal 253466, track.duration
353
+ assert_equal 7, track.puids.size
354
+ assert_equal 'c2a2cee5-a8ca-4f89-a092-c3e1e65ab7e6', track.puids[0]
355
+ assert_equal '42ab76ea-5d42-4259-85d7-e7f2c69e4485', track.puids[6]
321
356
  end
322
357
 
323
358
  def test_label_search
data/test/test_query.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ # $Id: test_query.rb 27 2007-05-28 23:15:21Z phw $
2
2
  # Copyright (c) 2007, Philipp Wolfer
3
3
  # All rights reserved.
4
4
  # See LICENSE for permissions.
@@ -0,0 +1,116 @@
1
+ # $Id: test_relation.rb 33 2007-05-29 14:48:47Z phw $
2
+ # Copyright (c) 2007, Philipp Wolfer
3
+ # All rights reserved.
4
+ # See LICENSE for permissions.
5
+
6
+ require 'test/unit'
7
+ require 'rbrainz/model'
8
+ include MusicBrainz
9
+
10
+ # Unit test for the Relation model.
11
+ class TestRelation < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @target_entity = Model::Artist.new
15
+ @target_entity.id = Model::MBID.from_uuid :artist, '727ad90b-7ef4-48d2-8f16-c34016544822'
16
+ end
17
+
18
+ def teardown
19
+ end
20
+
21
+ def test_new_relation
22
+ disc = nil
23
+ assert_nothing_raised {disc = Model::Relation.new}
24
+ end
25
+
26
+ def test_type
27
+ relation = Model::Relation.new
28
+ assert relation.type.nil?
29
+ assert_nothing_raised {relation.type = Model::NS_REL_1 + 'Performer'}
30
+ assert_equal Model::NS_REL_1 + 'Performer', relation.type
31
+ end
32
+
33
+ def test_direction
34
+ relation = Model::Relation.new
35
+ assert relation.direction.nil?
36
+ [Model::Relation::DIR_BACKWARD, Model::Relation::DIR_FORWARD,
37
+ Model::Relation::DIR_BOTH].each {|dir|
38
+ assert_nothing_raised {relation.direction = dir}
39
+ assert_equal dir, relation.direction
40
+ }
41
+ end
42
+
43
+ def test_begin_date
44
+ relation = Model::Relation.new
45
+ date = Model::IncompleteDate.new '1988-04-18'
46
+ assert_nothing_raised {relation.begin_date}
47
+ assert_equal nil, relation.begin_date
48
+ assert_nothing_raised {relation.begin_date = date}
49
+ assert_equal date, relation.begin_date
50
+
51
+ # It should be able to supply a date as a string,
52
+ # but Relation should convert it to an IncompleteDate.
53
+ assert_nothing_raised {relation.begin_date = '1988-04-20'}
54
+ assert_equal Model::IncompleteDate.new('1988-04-20'), relation.begin_date
55
+ end
56
+
57
+ def test_end_date
58
+ relation = Model::Relation.new
59
+ date = Model::IncompleteDate.new '1988-04-18'
60
+ assert_nothing_raised {relation.end_date}
61
+ assert_equal nil, relation.end_date
62
+ assert_nothing_raised {relation.end_date = date}
63
+ assert_equal date, relation.end_date
64
+
65
+ # It should be able to supply a date as a string,
66
+ # but Relation should convert it to an IncompleteDate.
67
+ assert_nothing_raised {relation.end_date = '1988-04-20'}
68
+ assert_equal Model::IncompleteDate.new('1988-04-20'), relation.end_date
69
+ end
70
+
71
+ def test_target
72
+ relation = Model::Relation.new
73
+ assert relation.target.nil?
74
+ assert_nothing_raised {relation.target = @target_entity}
75
+ assert_equal @target_entity, relation.target
76
+ assert_nothing_raised {relation.target = 'http://www.example.com'}
77
+ assert_equal 'http://www.example.com', relation.target
78
+ end
79
+
80
+ # Target type is read-only and is automatically set
81
+ # when the target is set.
82
+ def test_target_type
83
+ relation = Model::Relation.new
84
+ assert relation.target_type.nil?
85
+ assert_raise(NoMethodError) {relation.target_type = Model::Relation::TO_RELEASE}
86
+
87
+ relation.target = Model::Artist.new
88
+ assert_equal Model::Relation::TO_ARTIST, relation.target_type
89
+
90
+ relation.target = Model::Release.new
91
+ assert_equal Model::Relation::TO_RELEASE, relation.target_type
92
+
93
+ relation.target = Model::Track.new
94
+ assert_equal Model::Relation::TO_TRACK, relation.target_type
95
+
96
+ relation.target = Model::Label.new
97
+ assert_equal Model::Relation::TO_LABEL, relation.target_type
98
+
99
+ relation.target = 'http://www.example.com'
100
+ assert_equal Model::Relation::TO_URL, relation.target_type
101
+ end
102
+
103
+ def test_attributes
104
+ relation = Model::Relation.new
105
+ assert_equal 0, relation.attributes.size
106
+ assert_nothing_raised {relation.attributes << Model::NS_REL_1 + 'Lead'}
107
+ assert_equal 1, relation.attributes.size
108
+ assert_nothing_raised {relation.attributes.delete(Model::NS_REL_1 + 'Lead')}
109
+ assert_equal 0, relation.attributes.size
110
+ end
111
+
112
+ # The to_s method could return a readable representation of the relation.
113
+ #def test_to_string
114
+ #end
115
+
116
+ end