rbpod 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +9 -9
- data/Rakefile +5 -3
- data/ext/rbpod/collection.c +58 -60
- data/ext/rbpod/collection.h +1 -3
- data/ext/rbpod/database.c +46 -15
- data/ext/rbpod/device.c +2 -1
- data/ext/rbpod/error.c +27 -0
- data/ext/rbpod/error.h +12 -0
- data/ext/rbpod/playlist.c +14 -22
- data/ext/rbpod/playlist_collection.c +74 -41
- data/ext/rbpod/playlist_collection.h +1 -5
- data/ext/rbpod/rbpod.c +35 -23
- data/ext/rbpod/rbpod.h +3 -1
- data/ext/rbpod/track_collection.c +38 -10
- data/ext/rbpod/track_collection.h +1 -5
- data/lib/rbpod/version.rb +1 -1
- data/spec/rbpod/collection_spec.rb +25 -0
- data/spec/{database_spec.rb → rbpod/database_spec.rb} +14 -21
- data/spec/rbpod/device_spec.rb +70 -0
- data/spec/rbpod/playlist_collection_spec.rb +44 -0
- data/spec/{playlist_spec.rb → rbpod/playlist_spec.rb} +1 -1
- data/spec/rbpod/track_collection_spec.rb +15 -0
- data/spec/{track_spec.rb → rbpod/track_spec.rb} +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/support/shared_contexts.rb +18 -0
- metadata +24 -16
- data/spec/collection_spec.rb +0 -39
- data/spec/device_spec.rb +0 -83
- /data/spec/{rbpod_spec.rb → rbpod/rbpod_spec.rb} +0 -0
@@ -1,6 +1,7 @@
|
|
1
1
|
/* playlist_collection.c */
|
2
2
|
|
3
3
|
#include "rbpod.h"
|
4
|
+
#include "database.h"
|
4
5
|
#include "playlist.h"
|
5
6
|
#include "collection.h"
|
6
7
|
#include "playlist_collection.h"
|
@@ -9,7 +10,7 @@
|
|
9
10
|
* call-seq:
|
10
11
|
* database() -> RbPod::Database
|
11
12
|
*
|
12
|
-
*
|
13
|
+
* Returns the database this playlist collection is attached to.
|
13
14
|
*/
|
14
15
|
static VALUE rbpod_playlist_collection_database(VALUE self)
|
15
16
|
{
|
@@ -18,65 +19,92 @@ static VALUE rbpod_playlist_collection_database(VALUE self)
|
|
18
19
|
|
19
20
|
/*
|
20
21
|
* call-seq:
|
21
|
-
*
|
22
|
-
* [](name) -> RbPod::Playlist
|
22
|
+
* include?(playlist) -> Boolean
|
23
23
|
*
|
24
|
-
* Returns
|
24
|
+
* Returns true or false if the given RbPod::Playlist +playlist+ exists within the database.
|
25
25
|
*/
|
26
|
-
static VALUE
|
26
|
+
static VALUE rbpod_playlist_collection_include_p(VALUE self, VALUE playlist)
|
27
27
|
{
|
28
|
-
VALUE
|
29
|
-
Itdb_iTunesDB *
|
30
|
-
Itdb_Playlist *
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
return Data_Wrap_Struct(cRbPodPlaylist, NULL, NULL, (void *) playlist);
|
28
|
+
VALUE database = rbpod_playlist_collection_database(self);
|
29
|
+
Itdb_iTunesDB *_database = TYPED_DATA_PTR(database, Itdb_iTunesDB);
|
30
|
+
Itdb_Playlist *_playlist = TYPED_DATA_PTR(playlist, Itdb_Playlist);
|
31
|
+
|
32
|
+
if (rb_obj_is_instance_of(playlist, cRbPodPlaylist) == FALSE) {
|
33
|
+
rb_raise(eRbPodError, "Invalid argument: expected RbPod::Playlist, got %s", StringValueCStr(playlist));
|
34
|
+
return Qfalse;
|
36
35
|
}
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
return BooleanValue(itdb_playlist_exists(_database, _playlist));
|
38
|
+
}
|
39
|
+
|
40
|
+
/*
|
41
|
+
* call-seq:
|
42
|
+
* master() -> RbPod::Playlist
|
43
|
+
*
|
44
|
+
* Returns the master playlist from the database.
|
45
|
+
*/
|
46
|
+
static VALUE rbpod_playlist_collection_master(VALUE self)
|
47
|
+
{
|
48
|
+
VALUE database = rbpod_playlist_collection_database(self);
|
49
|
+
Itdb_iTunesDB *_database = TYPED_DATA_PTR(database, Itdb_iTunesDB);
|
50
|
+
Itdb_Playlist *_playlist = itdb_playlist_mpl(_database);
|
51
|
+
|
52
|
+
if (_playlist == NULL) {
|
53
|
+
return Qnil;
|
41
54
|
}
|
42
55
|
|
43
|
-
|
56
|
+
/* Create a new instance of the master playlist from the data provided. */
|
57
|
+
return rb_class_new_instance_with_data(0, NULL, cRbPodPlaylist, _playlist);
|
44
58
|
}
|
45
59
|
|
46
60
|
/*
|
47
61
|
* call-seq:
|
48
62
|
* podcast() -> RbPod::Playlist
|
49
63
|
*
|
50
|
-
* Returns the podcast playlist
|
64
|
+
* Returns the podcast playlist from the database.
|
51
65
|
*/
|
52
|
-
static VALUE
|
66
|
+
static VALUE rbpod_playlist_collection_podcast(VALUE self)
|
53
67
|
{
|
54
|
-
VALUE
|
55
|
-
Itdb_iTunesDB *
|
56
|
-
Itdb_Playlist *
|
57
|
-
|
68
|
+
VALUE database = rbpod_playlist_collection_database(self);
|
69
|
+
Itdb_iTunesDB *_database = TYPED_DATA_PTR(database, Itdb_iTunesDB);
|
70
|
+
Itdb_Playlist *_playlist = itdb_playlist_podcasts(_database);
|
71
|
+
|
72
|
+
if (_playlist == NULL) {
|
73
|
+
return Qnil;
|
74
|
+
}
|
75
|
+
|
76
|
+
/* Create a new instance of the podcast playlist from the data provided. */
|
77
|
+
return rb_class_new_instance_with_data(0, NULL, cRbPodPlaylist, _playlist);
|
58
78
|
}
|
59
79
|
|
60
80
|
/*
|
61
81
|
* call-seq:
|
62
|
-
*
|
82
|
+
* initialize(database) -> RbPod::PlaylistCollection
|
63
83
|
*
|
64
|
-
*
|
84
|
+
* Given an RbPod::Database +database+ creates a collection of playlists from it.
|
65
85
|
*/
|
66
|
-
static VALUE
|
86
|
+
static VALUE rbpod_playlist_collection_initialize(VALUE self, VALUE database)
|
67
87
|
{
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
88
|
+
Itdb_iTunesDB *_database = TYPED_DATA_PTR(database, Itdb_iTunesDB);
|
89
|
+
|
90
|
+
if (rb_obj_is_instance_of(database, cRbPodDatabase) == FALSE) {
|
91
|
+
rb_raise(eRbPodError, "Invalid Arguments: Expected RbPod::Database, got %s", StringValueCStr(database));
|
92
|
+
return Qnil;
|
93
|
+
}
|
94
|
+
|
95
|
+
rb_iv_set(self, "@database", database);
|
96
|
+
|
97
|
+
DATA_PTR(self) = _database->playlists;
|
98
|
+
|
99
|
+
return self;
|
72
100
|
}
|
73
101
|
|
74
|
-
|
102
|
+
/*
|
103
|
+
* :nodoc:
|
104
|
+
*/
|
105
|
+
static VALUE rbpod_playlist_collection_type(VALUE self)
|
75
106
|
{
|
76
|
-
|
77
|
-
rb_extend_object(collection, mRbPodPlaylistCollection);
|
78
|
-
rb_iv_set(collection, "@database", database);
|
79
|
-
return collection;
|
107
|
+
return cRbPodPlaylist;
|
80
108
|
}
|
81
109
|
|
82
110
|
void Init_rbpod_playlist_collection(void)
|
@@ -84,15 +112,20 @@ void Init_rbpod_playlist_collection(void)
|
|
84
112
|
#if RDOC_CAN_PARSE_DOCUMENTATION
|
85
113
|
mRbPod = rb_define_module("RbPod");
|
86
114
|
#endif
|
87
|
-
|
88
|
-
|
115
|
+
cRbPodPlaylistCollection = rb_define_class_under(mRbPod, "PlaylistCollection", rb_cObject);
|
116
|
+
|
117
|
+
rb_real_include_module(cRbPodPlaylistCollection, mRbPodCollection);
|
118
|
+
|
119
|
+
rb_define_private_method(cRbPodPlaylistCollection, "type", rbpod_playlist_collection_type, 0);
|
120
|
+
|
121
|
+
rb_define_method(cRbPodPlaylistCollection, "initialize", rbpod_playlist_collection_initialize, 1);
|
89
122
|
|
90
|
-
rb_define_method(
|
123
|
+
rb_define_method(cRbPodPlaylistCollection, "database", rbpod_playlist_collection_database, 0);
|
91
124
|
|
92
|
-
rb_define_method(
|
93
|
-
rb_define_method(mRbPodPlaylistCollection, "podcast", rbpod_playlist_collection_podcast_get, 0);
|
125
|
+
rb_define_method(cRbPodPlaylistCollection, "include?", rbpod_playlist_collection_include_p, 1);
|
94
126
|
|
95
|
-
rb_define_method(
|
127
|
+
rb_define_method(cRbPodPlaylistCollection, "master", rbpod_playlist_collection_master, 0);
|
128
|
+
rb_define_method(cRbPodPlaylistCollection, "podcast", rbpod_playlist_collection_podcast, 0);
|
96
129
|
|
97
130
|
return;
|
98
131
|
}
|
@@ -3,12 +3,8 @@
|
|
3
3
|
#ifndef RBPOD_PLAYLIST_COLLECTION_H
|
4
4
|
#define RBPOD_PLAYLIST_COLLECTION_H
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
RUBY_EXTERN VALUE mRbPodPlaylistCollection;
|
6
|
+
RUBY_EXTERN VALUE cRbPodPlaylistCollection;
|
9
7
|
|
10
8
|
void Init_rbpod_playlist_collection(void);
|
11
9
|
|
12
|
-
inline VALUE rbpod_playlist_collection_create(VALUE parent, GList *items);
|
13
|
-
|
14
10
|
#endif /* RBPOD_PLAYLIST_COLLECTION_H */
|
data/ext/rbpod/rbpod.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
/* rbpod.c */
|
2
2
|
|
3
3
|
#include "rbpod.h"
|
4
|
+
#include "error.h"
|
4
5
|
#include "track.h"
|
5
6
|
#include "device.h"
|
6
7
|
#include "playlist.h"
|
@@ -15,28 +16,15 @@ VALUE eRbPodError;
|
|
15
16
|
VALUE cRbPodDatabase;
|
16
17
|
VALUE cRbPodDevice;
|
17
18
|
|
18
|
-
VALUE cRbPodCollection;
|
19
|
-
|
20
|
-
VALUE cRbPodPlaylist;
|
21
|
-
VALUE mRbPodPlaylistCollection;
|
22
|
-
|
23
19
|
VALUE cRbPodTrack;
|
24
|
-
VALUE
|
25
|
-
|
26
|
-
VALUE rb_cPathname;
|
20
|
+
VALUE cRbPodPlaylist;
|
27
21
|
|
28
|
-
|
29
|
-
{
|
30
|
-
VALUE error_message;
|
22
|
+
VALUE mRbPodCollection;
|
31
23
|
|
32
|
-
|
33
|
-
|
34
|
-
g_error_free(error);
|
35
|
-
rb_raise(eRbPodError, "%s", StringValueCStr(error_message));
|
36
|
-
}
|
24
|
+
VALUE cRbPodTrackCollection;
|
25
|
+
VALUE cRbPodPlaylistCollection;
|
37
26
|
|
38
|
-
|
39
|
-
}
|
27
|
+
VALUE rb_cPathname;
|
40
28
|
|
41
29
|
/*
|
42
30
|
* call-seq:
|
@@ -50,16 +38,38 @@ static VALUE rbpod_load_database(VALUE self, VALUE mount_point)
|
|
50
38
|
return rb_class_new_instance(1, &mount_point, cRbPodDatabase);
|
51
39
|
}
|
52
40
|
|
41
|
+
/*
|
42
|
+
* This is a hack used to inject a pointer from the data of one class instance into another.
|
43
|
+
*/
|
44
|
+
inline VALUE rb_class_new_instance_with_data(int argc, VALUE *argv, VALUE class, void *handle)
|
45
|
+
{
|
46
|
+
/* Create a new instance of this class. */
|
47
|
+
VALUE instance = rb_class_new_instance(argc, argv, class);
|
48
|
+
|
49
|
+
/* Assign it's DATA pointer to the given handle. */
|
50
|
+
DATA_PTR(instance) = handle;
|
51
|
+
|
52
|
+
return instance;
|
53
|
+
}
|
54
|
+
|
55
|
+
/*
|
56
|
+
* This is a hack so that including a module will trigger the +included+ singleton method.
|
57
|
+
*/
|
58
|
+
inline void rb_real_include_module(VALUE klass, VALUE module)
|
59
|
+
{
|
60
|
+
ID included = rb_intern("included");
|
61
|
+
|
62
|
+
rb_include_module(klass, module);
|
63
|
+
|
64
|
+
rb_funcall(mRbPodCollection, included, 1, klass);
|
65
|
+
}
|
66
|
+
|
53
67
|
void Init_rbpod(void)
|
54
68
|
{
|
55
69
|
/* This is the wrapper for all RbPod related classes. */
|
56
70
|
mRbPod = rb_define_module("RbPod");
|
57
71
|
|
58
|
-
|
59
|
-
eRbPodError = rb_define_class_under(mRbPod, "Error", rb_eRuntimeError);
|
60
|
-
|
61
|
-
rb_cPathname = rb_const_get(rb_cObject, rb_intern("Pathname"));
|
62
|
-
|
72
|
+
Init_rbpod_error();
|
63
73
|
Init_rbpod_database();
|
64
74
|
Init_rbpod_device();
|
65
75
|
Init_rbpod_collection();
|
@@ -70,6 +80,8 @@ void Init_rbpod(void)
|
|
70
80
|
|
71
81
|
rb_define_global_function("RbPod", rbpod_load_database, 1);
|
72
82
|
|
83
|
+
rb_cPathname = rb_const_get(rb_cObject, rb_intern("Pathname"));
|
84
|
+
|
73
85
|
return;
|
74
86
|
}
|
75
87
|
|
data/ext/rbpod/rbpod.h
CHANGED
@@ -15,6 +15,8 @@ RUBY_EXTERN VALUE eRbPodError;
|
|
15
15
|
|
16
16
|
RUBY_EXTERN VALUE rb_cPathname;
|
17
17
|
|
18
|
-
inline VALUE
|
18
|
+
inline VALUE rb_class_new_instance_with_data(int argc, VALUE *argv, VALUE class, void *handle);
|
19
|
+
|
20
|
+
inline void rb_real_include_module(VALUE klass, VALUE module);
|
19
21
|
|
20
22
|
#endif /* RBPOD_H */
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
#include "rbpod.h"
|
4
4
|
#include "track.h"
|
5
|
+
#include "playlist.h"
|
5
6
|
#include "collection.h"
|
6
7
|
#include "track_collection.h"
|
7
8
|
|
@@ -9,19 +10,41 @@
|
|
9
10
|
* call-seq:
|
10
11
|
* playlist() -> RbPod::Playlist
|
11
12
|
*
|
12
|
-
*
|
13
|
+
* Returns the playlist this track collection is attached to.
|
13
14
|
*/
|
14
15
|
static VALUE rbpod_track_collection_playlist(VALUE self)
|
15
16
|
{
|
16
|
-
return rb_iv_get(self, "@
|
17
|
+
return rb_iv_get(self, "@playlist");
|
17
18
|
}
|
18
19
|
|
19
|
-
|
20
|
+
/*
|
21
|
+
* call-seq:
|
22
|
+
* initialize(playlist) -> RbPod::TrackCollection
|
23
|
+
*
|
24
|
+
* Given an RbPod::Playlist +playlist+, returns a collection of tracks within the playlist.
|
25
|
+
*/
|
26
|
+
static VALUE rbpod_track_collection_initialize(VALUE self, VALUE playlist)
|
27
|
+
{
|
28
|
+
Itdb_Playlist *_playlist = TYPED_DATA_PTR(playlist, Itdb_Playlist);
|
29
|
+
|
30
|
+
if (rb_obj_is_instance_of(playlist, cRbPodPlaylist) == FALSE) {
|
31
|
+
rb_raise(eRbPodError, "Invalid Arguments: Expected RbPod::Playlist, got %s", StringValueCStr(playlist));
|
32
|
+
return Qnil;
|
33
|
+
}
|
34
|
+
|
35
|
+
rb_iv_set(self, "@playlist", playlist);
|
36
|
+
|
37
|
+
DATA_PTR(self) = _playlist->members;
|
38
|
+
|
39
|
+
return self;
|
40
|
+
}
|
41
|
+
|
42
|
+
/*
|
43
|
+
* :nodoc:
|
44
|
+
*/
|
45
|
+
static VALUE rbpod_track_collection_type(VALUE self)
|
20
46
|
{
|
21
|
-
|
22
|
-
rb_extend_object(collection, mRbPodTrackCollection);
|
23
|
-
rb_iv_set(collection, "@playlist", playlist);
|
24
|
-
return collection;
|
47
|
+
return cRbPodTrack;
|
25
48
|
}
|
26
49
|
|
27
50
|
void Init_rbpod_track_collection(void)
|
@@ -29,10 +52,15 @@ void Init_rbpod_track_collection(void)
|
|
29
52
|
#if RDOC_CAN_PARSE_DOCUMENTATION
|
30
53
|
mRbPod = rb_define_module("RbPod");
|
31
54
|
#endif
|
32
|
-
|
33
|
-
|
55
|
+
cRbPodTrackCollection = rb_define_class_under(mRbPod, "TrackCollection", rb_cObject);
|
56
|
+
|
57
|
+
rb_real_include_module(cRbPodTrackCollection, mRbPodCollection);
|
58
|
+
|
59
|
+
rb_define_method(cRbPodTrackCollection, "initialize", rbpod_track_collection_initialize, 1);
|
60
|
+
|
61
|
+
rb_define_private_method(cRbPodTrackCollection, "type", rbpod_track_collection_type, 0);
|
34
62
|
|
35
|
-
rb_define_method(
|
63
|
+
rb_define_method(cRbPodTrackCollection, "playlist", rbpod_track_collection_playlist, 0);
|
36
64
|
|
37
65
|
return;
|
38
66
|
}
|
@@ -3,12 +3,8 @@
|
|
3
3
|
#ifndef RBPOD_TRACK_COLLECTION_H
|
4
4
|
#define RBPOD_TRACK_COLLECTION_H
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
RUBY_EXTERN VALUE mRbPodTrackCollection;
|
6
|
+
RUBY_EXTERN VALUE cRbPodTrackCollection;
|
9
7
|
|
10
8
|
void Init_rbpod_track_collection(void);
|
11
9
|
|
12
|
-
inline VALUE rbpod_track_collection_create(VALUE parent, GList *items);
|
13
|
-
|
14
10
|
#endif /* RBPOD_TRACK_COLLECTION_H */
|
data/lib/rbpod/version.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
shared_examples_for RbPod::Collection do
|
2
|
+
it 'should be a collection' do
|
3
|
+
collection.should be_kind_of(RbPod::Collection)
|
4
|
+
end
|
5
|
+
|
6
|
+
it 'should implement #each' do
|
7
|
+
collection.should respond_to(:each)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should implement #size' do
|
11
|
+
collection.should respond_to(:size)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should implement #first' do
|
15
|
+
collection.should respond_to(:first)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should implement #last' do
|
19
|
+
collection.should respond_to(:last)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should implement #[]' do
|
23
|
+
collection.should respond_to(:[])
|
24
|
+
end
|
25
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
describe RbPod::Database do
|
2
|
-
context '
|
2
|
+
context 'Without a new database' do
|
3
3
|
describe '.create!' do
|
4
4
|
it 'should create an empty default database and load it' do
|
5
5
|
within_temporary_directory do |directory|
|
@@ -33,55 +33,48 @@ describe RbPod::Database do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
context '
|
37
|
-
|
38
|
-
@directory = within_temporary_directory
|
39
|
-
@database = RbPod::Database.create!(@directory)
|
40
|
-
end
|
41
|
-
|
42
|
-
after do
|
43
|
-
# This is a godawful hack.
|
44
|
-
FileUtils.remove_entry_secure(@directory)
|
45
|
-
end
|
36
|
+
context 'With a new database' do
|
37
|
+
include_context 'a new database'
|
46
38
|
|
47
39
|
describe '#initialize' do
|
48
40
|
it 'should return a Database instance' do
|
49
|
-
|
41
|
+
database.should be_instance_of(RbPod::Database)
|
50
42
|
end
|
51
43
|
end
|
52
44
|
|
53
45
|
describe '#mountpoint' do
|
54
46
|
it 'should match the mount point it was loaded from' do
|
55
|
-
|
47
|
+
database.mountpoint.to_s.should == directory
|
56
48
|
end
|
57
49
|
end
|
58
50
|
|
59
51
|
describe '#filename' do
|
60
52
|
it 'should be an existing iTunes database on the file system' do
|
61
|
-
File.exists?(
|
53
|
+
File.exists?(database.filename).should be_true
|
62
54
|
end
|
63
55
|
end
|
64
56
|
|
65
57
|
describe '#device' do
|
66
58
|
it 'should return a Device instance' do
|
67
|
-
|
59
|
+
database.device.should be_instance_of(RbPod::Device)
|
68
60
|
end
|
69
61
|
end
|
70
62
|
|
71
63
|
describe '#synchronized?' do
|
72
64
|
it 'should be marked as synchronized' do
|
73
|
-
|
65
|
+
database.should be_synchronized
|
74
66
|
end
|
75
67
|
end
|
76
68
|
|
77
69
|
describe '#playlists' do
|
78
|
-
it 'should return a collection' do
|
79
|
-
|
70
|
+
it 'should return a playlist collection' do
|
71
|
+
database.playlists.should be_instance_of(RbPod::PlaylistCollection)
|
80
72
|
end
|
73
|
+
end
|
81
74
|
|
82
|
-
|
83
|
-
|
84
|
-
|
75
|
+
describe '#tracks' do
|
76
|
+
it 'should return a track collection' do
|
77
|
+
database.tracks.should be_instance_of(RbPod::TrackCollection)
|
85
78
|
end
|
86
79
|
end
|
87
80
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
describe RbPod::Device do
|
2
|
+
context 'On a device backed by a new database' do
|
3
|
+
include_context 'a new database'
|
4
|
+
|
5
|
+
let(:device) { database.device }
|
6
|
+
|
7
|
+
describe '#[]' do
|
8
|
+
it 'should return a nil value for any key' do
|
9
|
+
device['ModelNumStr'].should be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should return nil with an invalid key' do
|
13
|
+
device['NonExistentValue'].should be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should return nil when unsetting a key' do
|
17
|
+
device['NotARealKey'] = nil
|
18
|
+
device['NotARealKey'].should be_nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#save!' do
|
23
|
+
it 'should return nil' do
|
24
|
+
device.save!.should eq(nil)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#uuid' do
|
29
|
+
it 'should be nil' do
|
30
|
+
device.uuid.should eq(nil)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#capacity' do
|
35
|
+
it 'should be zero' do
|
36
|
+
device.capacity.should be_kind_of(Float)
|
37
|
+
device.capacity.should eq(0.0)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#generation' do
|
42
|
+
it 'should be "Unknown"' do
|
43
|
+
device.generation.should be_kind_of(String)
|
44
|
+
device.generation.should eq('Unknown')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#model_name' do
|
49
|
+
it 'should be "Invalid"' do
|
50
|
+
device.model_name.should be_kind_of(String)
|
51
|
+
device.model_name.should eq('Invalid')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#model_number' do
|
56
|
+
it 'should be "Invalid"' do
|
57
|
+
device.model_number.should be_kind_of(String)
|
58
|
+
device.model_number.should eq('Invalid')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
%w[photos videos artwork podcasts chapter_images].each do |feature|
|
63
|
+
describe "#supports_#{feature}?" do
|
64
|
+
it 'should be false' do
|
65
|
+
device.send("supports_#{feature}?").should be_false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
describe RbPod::PlaylistCollection do
|
2
|
+
it_behaves_like RbPod::Collection
|
3
|
+
# Create a temporary database for the test.
|
4
|
+
include_context 'a new database'
|
5
|
+
|
6
|
+
# Use it as a parent to the playlist collection.
|
7
|
+
let (:collection) { RbPod::PlaylistCollection.new(database) }
|
8
|
+
|
9
|
+
describe '#database' do
|
10
|
+
it 'should return the parent database' do
|
11
|
+
collection.database.should eq(database)
|
12
|
+
collection.database.should be_kind_of(RbPod::Database)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#master' do
|
17
|
+
it 'should return a playlist' do
|
18
|
+
collection.master.should be_kind_of(RbPod::Playlist)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should be marked as the master playlist' do
|
22
|
+
collection.master.should be_master
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#podcast' do
|
27
|
+
context 'on a new database' do
|
28
|
+
it 'should return nil' do
|
29
|
+
collection.podcast.should be_nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#include?' do
|
35
|
+
it 'should detect the master playlist' do
|
36
|
+
collection.include?(collection.master).should be_true
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should not detect a new playlist' do
|
40
|
+
anonymous_playlist = RbPod::Playlist.new()
|
41
|
+
collection.include?(anonymous_playlist).should be_false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
describe RbPod::TrackCollection do
|
2
|
+
it_behaves_like RbPod::Collection
|
3
|
+
# A track collection only requires a playlist, so we don't need a database.
|
4
|
+
let(:playlist) { RbPod::Playlist.new() }
|
5
|
+
|
6
|
+
# Use the new playlist as a parent for this track collection.
|
7
|
+
let(:collection) { described_class.new(playlist) }
|
8
|
+
|
9
|
+
describe '#playlist' do
|
10
|
+
it 'should return the parent playlist' do
|
11
|
+
collection.playlist.should eq(playlist)
|
12
|
+
collection.playlist.should be_kind_of(RbPod::Playlist)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
shared_context 'a new database' do
|
2
|
+
# Create a temporary folder and initialize a database in it.
|
3
|
+
before(:all) do
|
4
|
+
@directory = within_temporary_directory
|
5
|
+
@database = RbPod::Database.create!(@directory)
|
6
|
+
end
|
7
|
+
|
8
|
+
# This is a godawful hack, but it's needed to clean up after the tests finish.
|
9
|
+
after(:all) do
|
10
|
+
FileUtils.remove_entry_secure(@directory)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Temporary directory for database.
|
14
|
+
let(:directory) { @directory }
|
15
|
+
|
16
|
+
# The database instance itself.
|
17
|
+
let(:database) { @database }
|
18
|
+
end
|