rbpod 0.0.4 → 0.0.5
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/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
|