rbrainz 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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