kagu 1.2.0 → 1.2.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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/kagu.gemspec +1 -2
- metadata +3 -23
- data/.gitignore +0 -7
- data/.rspec +0 -2
- data/Gemfile +0 -3
- data/Rakefile +0 -10
- data/spec/kagu/error_spec.rb +0 -40
- data/spec/kagu/finder_spec.rb +0 -314
- data/spec/kagu/library_spec.rb +0 -57
- data/spec/kagu/playlist_spec.rb +0 -74
- data/spec/kagu/playlists_spec.rb +0 -47
- data/spec/kagu/track_spec.rb +0 -303
- data/spec/kagu/tracks_spec.rb +0 -66
- data/spec/spec_helper.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f2eb7f1dc5e7068bb9aac193c238d9692dabdbf
|
4
|
+
data.tar.gz: 8b6a3dbbdaaa42c74da8060d61b30be3843c594b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a22628b4870b924f88a3db00d910667a1d66286d2112c8d44f1bef072ef872c106134da2fa8d2e32ed8bfd40450b5ffefbb91f40a27250d22d4f9c7bf427a42
|
7
|
+
data.tar.gz: 3b3903a0ded1b34a2e35cd2509964e3779e0ce311cd731c8b9b3b2a360404fa3e0940e826728a94511ab3f2e239633a2e8f29baa2fb32344a0f5cfc97009b3c8
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.1
|
data/kagu.gemspec
CHANGED
@@ -9,8 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.description = 'API to manage iTunes tracks and playlists'
|
10
10
|
s.license = 'MIT'
|
11
11
|
|
12
|
-
s.files = `git ls-files`.split("\n")
|
13
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
12
|
+
s.files = `git ls-files | grep -vE '^(spec/|test/|\\.|Gemfile|Rakefile)'`.split("\n")
|
14
13
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
14
|
s.require_paths = ['lib']
|
16
15
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kagu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexis Toulotte
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -136,12 +136,8 @@ executables: []
|
|
136
136
|
extensions: []
|
137
137
|
extra_rdoc_files: []
|
138
138
|
files:
|
139
|
-
- .gitignore
|
140
|
-
- .rspec
|
141
|
-
- Gemfile
|
142
139
|
- MIT-LICENSE
|
143
140
|
- README.mdown
|
144
|
-
- Rakefile
|
145
141
|
- VERSION
|
146
142
|
- kagu.gemspec
|
147
143
|
- lib/kagu.rb
|
@@ -153,14 +149,6 @@ files:
|
|
153
149
|
- lib/kagu/playlists.rb
|
154
150
|
- lib/kagu/track.rb
|
155
151
|
- lib/kagu/tracks.rb
|
156
|
-
- spec/kagu/error_spec.rb
|
157
|
-
- spec/kagu/finder_spec.rb
|
158
|
-
- spec/kagu/library_spec.rb
|
159
|
-
- spec/kagu/playlist_spec.rb
|
160
|
-
- spec/kagu/playlists_spec.rb
|
161
|
-
- spec/kagu/track_spec.rb
|
162
|
-
- spec/kagu/tracks_spec.rb
|
163
|
-
- spec/spec_helper.rb
|
164
152
|
homepage: https://github.com/alexistoulotte/kagu
|
165
153
|
licenses:
|
166
154
|
- MIT
|
@@ -185,12 +173,4 @@ rubygems_version: 2.0.14.1
|
|
185
173
|
signing_key:
|
186
174
|
specification_version: 4
|
187
175
|
summary: API for iTunes
|
188
|
-
test_files:
|
189
|
-
- spec/kagu/error_spec.rb
|
190
|
-
- spec/kagu/finder_spec.rb
|
191
|
-
- spec/kagu/library_spec.rb
|
192
|
-
- spec/kagu/playlist_spec.rb
|
193
|
-
- spec/kagu/playlists_spec.rb
|
194
|
-
- spec/kagu/track_spec.rb
|
195
|
-
- spec/kagu/tracks_spec.rb
|
196
|
-
- spec/spec_helper.rb
|
176
|
+
test_files: []
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/Gemfile
DELETED
data/Rakefile
DELETED
data/spec/kagu/error_spec.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Kagu::Error do
|
4
|
-
|
5
|
-
let(:error) { Kagu::Error.new('BAM!') }
|
6
|
-
let(:original) { StandardError.new('BIM!') }
|
7
|
-
|
8
|
-
describe '#message' do
|
9
|
-
|
10
|
-
it 'is message set at initialization' do
|
11
|
-
expect(error.message).to eq('BAM!')
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'message is squished' do
|
15
|
-
expect(Kagu::Error.new(" hello \n world").message).to eq('hello world')
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'default one if blank' do
|
19
|
-
expect(Kagu::Error.new(" ").message).to eq('Kagu::Error')
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
describe '#original' do
|
25
|
-
|
26
|
-
it 'is nil by default' do
|
27
|
-
expect(error.original).to be_nil
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'is exception given at initialization' do
|
31
|
-
expect(Kagu::Error.new(original).original).to be(original)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'sets message from original' do
|
35
|
-
expect(Kagu::Error.new(original).message).to eq('BIM!')
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
data/spec/kagu/finder_spec.rb
DELETED
@@ -1,314 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Kagu::Finder do
|
4
|
-
|
5
|
-
let(:finder) { Kagu::Finder.new(library) }
|
6
|
-
let(:library) { Kagu::Library.new }
|
7
|
-
|
8
|
-
describe '.replace' do
|
9
|
-
|
10
|
-
it 'replace given value with replacements' do
|
11
|
-
expect(Kagu::Finder.replace('Hello World!', 'World' => 'John', 'Hello' => 'Bye')).to eq('Bye John!')
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'is case sensitive' do
|
15
|
-
expect(Kagu::Finder.replace('Hello World!', 'world' => 'John', 'Hello' => 'Bye')).to eq('Bye World!')
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'replace given value with some regexp' do
|
19
|
-
expect(Kagu::Finder.replace('Hello World!', 'World' => 'John', /l+/ => 'i')).to eq('Heio John!')
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'returns nil if blank' do
|
23
|
-
expect(Kagu::Finder.replace(' ', 'world' => 'John', 'Hello' => 'Bye')).to be_nil
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'accepts arrays as replacements' do
|
27
|
-
expect(Kagu::Finder.replace('Hello World!', [['World', 'John'], ['Hello', 'Bye']])).to eq('Bye John!')
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
describe '.transliterate' do
|
33
|
-
|
34
|
-
it 'removes accents' do
|
35
|
-
expect(Kagu::Finder.transliterate('éàlôrs')).to eq('ealors')
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'removes consecutive white spaces' do
|
39
|
-
expect(Kagu::Finder.transliterate(" hello \t world\n ")).to eq('hello world')
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'converts value to lower case' do
|
43
|
-
expect(Kagu::Finder.transliterate('Hello World')).to eq('hello world')
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'removes nil if blank' do
|
47
|
-
expect(Kagu::Finder.transliterate(' ')).to be_nil
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
describe '#find' do
|
53
|
-
|
54
|
-
it 'returns some tracks' do
|
55
|
-
tracks = finder.find(artist: 'korn', title: 'blind')
|
56
|
-
expect(tracks).to be_an(Array)
|
57
|
-
expect(tracks.first).to be_a(Kagu::Track)
|
58
|
-
expect(tracks.first.title).to match(/blind/i)
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'returns nothing if artist is blank' do
|
62
|
-
expect(finder.find(title: 'blind')).to be_empty
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'returns nothing if title is blank' do
|
66
|
-
expect(finder.find(artist: 'korn')).to be_empty
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'returns nothing if artist match an artist and a track' do
|
70
|
-
expect(finder.find(artist: 'korn blind')).to be_empty
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'artist and title can be specified as string' do
|
74
|
-
expect(finder.find('artist' => 'KoRn', 'title' => 'Ball Tongue').first).to be_a(Kagu::Track)
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'returns an array of array of tracks if there is some replacements' do
|
78
|
-
finder.reload(replacements: { 'ball tongue' => 'blind' })
|
79
|
-
results = finder.find(artist: 'korn', title: 'blind')
|
80
|
-
expect(results.size).to eq(2)
|
81
|
-
expect(results.first).to be_an(Array)
|
82
|
-
expect(results.first.first.title).to match(/blind/i)
|
83
|
-
expect(results.second.first.title).to match(/ball tongue/i)
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'replacements are working with given attributes' do
|
87
|
-
finder.reload(replacements: { 'hello world' => 'blind' })
|
88
|
-
results = finder.find(artist: 'korn', title: 'hello world')
|
89
|
-
expect(results.size).to eq(1)
|
90
|
-
expect(results.first.first).to be_a(Kagu::Track)
|
91
|
-
expect(results.first.first.title).to match(/blind/i)
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'put at first position the exact matches from given attributes' do
|
95
|
-
finder.reload(replacements: { 'ball tongue' => 'blind' })
|
96
|
-
results = finder.find(artist: 'korn', title: 'ball tongue')
|
97
|
-
expect(results.size).to eq(2)
|
98
|
-
|
99
|
-
expect(results.first).not_to be_empty
|
100
|
-
results.first.each do |track|
|
101
|
-
expect(track.title).to match(/ball tongue/i)
|
102
|
-
end
|
103
|
-
|
104
|
-
expect(results.second).not_to be_empty
|
105
|
-
results.second.each do |track|
|
106
|
-
expect(track.title).to match(/blind/i)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'does not include ignored tracks' do
|
111
|
-
expect {
|
112
|
-
finder.reload(ignored: 'korn blind')
|
113
|
-
}.to change { finder.find(artist: 'korn', title: 'blind').size }.to(0)
|
114
|
-
expect(finder.find(artist: 'korn', title: 'ball tongue')).not_to be_empty
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'does not include ignored tracks for each digest' do
|
118
|
-
finder.reload(replacements: { 'blind' => 'foo' })
|
119
|
-
expect {
|
120
|
-
finder.reload(ignored: 'korn foo', replacements: { 'blind' => 'foo' })
|
121
|
-
}.to change { finder.find(artist: 'korn', title: 'blind').size }.to(0)
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'finds for some tracks with replacements as regexp' do
|
125
|
-
finder.reload(replacements: { /subsonik (\d+)/ => "subsonik podcast \\1" })
|
126
|
-
results = finder.find(artist: 'subsonik', title: '002')
|
127
|
-
expect(results.size).to eq(1)
|
128
|
-
expect(results.first.first.title).to match(/podcast 002/i)
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'does not fails if it does not match last replacements' do
|
132
|
-
finder.reload(replacements: [{ /subsonik (\d+)/ => "subsonik podcast \\1" }, { /\s+/ => '' }])
|
133
|
-
results = finder.find(artist: 'subsonik', title: '002')
|
134
|
-
expect(results.size).to eq(1)
|
135
|
-
expect(results.first.first.title).to match(/podcast 002/i)
|
136
|
-
end
|
137
|
-
|
138
|
-
end
|
139
|
-
|
140
|
-
describe '#ignored' do
|
141
|
-
|
142
|
-
it 'can be set as an array of string' do
|
143
|
-
expect {
|
144
|
-
finder.reload(ignored: ['test', 'foo'])
|
145
|
-
}.to change { finder.ignored }.from([]).to(['test', 'foo'])
|
146
|
-
end
|
147
|
-
|
148
|
-
it 'can be set as a simple string' do
|
149
|
-
expect {
|
150
|
-
finder.reload(ignored: 'test')
|
151
|
-
}.to change { finder.ignored }.from([]).to(['test'])
|
152
|
-
end
|
153
|
-
|
154
|
-
it 'is transliterated' do
|
155
|
-
expect {
|
156
|
-
finder.reload(ignored: ['testé HeLLo World', 'foo'])
|
157
|
-
}.to change { finder.ignored }.from([]).to(['teste hello world', 'foo'])
|
158
|
-
end
|
159
|
-
|
160
|
-
it 'can be set from a track' do
|
161
|
-
expect {
|
162
|
-
finder.reload(ignored: [finder.find(artist: 'KoRn', title: 'Blind').first])
|
163
|
-
}.to change { finder.ignored }.from([]).to(['korn blind'])
|
164
|
-
end
|
165
|
-
|
166
|
-
it 'can be set from an hash (as string keys)' do
|
167
|
-
expect {
|
168
|
-
finder.reload(ignored: { 'artist' => 'KoRn', 'title' => 'Blind' })
|
169
|
-
}.to change { finder.ignored }.from([]).to(['korn blind'])
|
170
|
-
end
|
171
|
-
|
172
|
-
it 'can be set from an hash (with symbol keys)' do
|
173
|
-
expect {
|
174
|
-
finder.reload(ignored: { artist: 'KoRn', title: 'Blind' })
|
175
|
-
}.to change { finder.ignored }.from([]).to(['korn blind'])
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'removes duplicates' do
|
179
|
-
expect {
|
180
|
-
finder.reload(ignored: ['test', 'Foo ', 'foo', 'TEST'])
|
181
|
-
}.to change { finder.ignored }.from([]).to(['test', 'foo'])
|
182
|
-
end
|
183
|
-
|
184
|
-
end
|
185
|
-
|
186
|
-
describe '#ignored?' do
|
187
|
-
|
188
|
-
it 'is false if nil is given' do
|
189
|
-
expect(finder.ignored?(nil)).to be(false)
|
190
|
-
end
|
191
|
-
|
192
|
-
it 'is true if at least one digest is ignored' do
|
193
|
-
finder.reload(replacements: { 'hello' => 'world' }, ignored: 'korn world')
|
194
|
-
expect(finder.ignored?(double(artist: 'korn', title: 'blind'))).to be(false)
|
195
|
-
expect(finder.ignored?(double(artist: 'korn', title: 'hello'))).to be(true)
|
196
|
-
expect(finder.ignored?(double(artist: 'korn', title: 'world'))).to be(true)
|
197
|
-
expect(finder.ignored?(double(artist: 'korn', title: 'hellow'))).to be(false)
|
198
|
-
end
|
199
|
-
|
200
|
-
end
|
201
|
-
|
202
|
-
describe '#library' do
|
203
|
-
|
204
|
-
it 'is library given at initialization' do
|
205
|
-
expect(finder.library).to be(library)
|
206
|
-
end
|
207
|
-
|
208
|
-
it 'raise an error if library is nil' do
|
209
|
-
expect {
|
210
|
-
Kagu::Finder.new(nil)
|
211
|
-
}.to raise_error(ArgumentError, 'Kagu::Finder#library must be a library, nil given')
|
212
|
-
end
|
213
|
-
|
214
|
-
end
|
215
|
-
|
216
|
-
describe '#reload' do
|
217
|
-
|
218
|
-
it 'sets replacements' do
|
219
|
-
expect {
|
220
|
-
finder.reload(replacements: { 'foo' => 'bar' })
|
221
|
-
}.to change { finder.replacements }.from([]).to([{ 'foo' => 'bar' }])
|
222
|
-
end
|
223
|
-
|
224
|
-
it 'removes replacements' do
|
225
|
-
finder.reload(replacements: { 'foo' => 'bar' })
|
226
|
-
expect {
|
227
|
-
finder.reload
|
228
|
-
}.to change { finder.replacements }.to([])
|
229
|
-
end
|
230
|
-
|
231
|
-
it 'removes ignored' do
|
232
|
-
finder.reload(ignored: 'foo')
|
233
|
-
expect {
|
234
|
-
finder.reload
|
235
|
-
}.to change { finder.ignored }.to([])
|
236
|
-
end
|
237
|
-
|
238
|
-
it 'returns finder' do
|
239
|
-
expect(finder.reload).to be(finder)
|
240
|
-
end
|
241
|
-
|
242
|
-
it 'reload tracks' do
|
243
|
-
expect {
|
244
|
-
finder.reload(replacements: { /\./ => '' })
|
245
|
-
}.to change { finder.find(artist: 'korn', title: 'adidas').present? }.from(false).to(true)
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'returns finder' do
|
249
|
-
expect(finder.reload).to be(finder)
|
250
|
-
end
|
251
|
-
|
252
|
-
end
|
253
|
-
|
254
|
-
describe '#reload!' do
|
255
|
-
|
256
|
-
it 'invokes reload' do
|
257
|
-
expect(finder).to receive(:reload).with('foo' => 'bar')
|
258
|
-
finder.reload!('foo' => 'bar')
|
259
|
-
end
|
260
|
-
|
261
|
-
it 'removes tracks cache' do
|
262
|
-
finder.find(artist: 'korn', title: 'blind')
|
263
|
-
expect {
|
264
|
-
finder.reload!
|
265
|
-
}.to change { finder.instance_variable_get(:@tracks) }.to(nil)
|
266
|
-
end
|
267
|
-
|
268
|
-
it 'returns finder' do
|
269
|
-
expect(finder.reload!).to be(finder)
|
270
|
-
end
|
271
|
-
|
272
|
-
end
|
273
|
-
|
274
|
-
describe '#replacements' do
|
275
|
-
|
276
|
-
it 'can be ommited' do
|
277
|
-
expect(finder.reload.replacements).to eq([])
|
278
|
-
end
|
279
|
-
|
280
|
-
it 'can be specified as regexp' do
|
281
|
-
expect(finder.reload(replacements: { /bar/ => 'foo' }).replacements).to eq([/bar/ => 'foo'])
|
282
|
-
end
|
283
|
-
|
284
|
-
it 'can be specified with a string as key' do
|
285
|
-
expect(finder.reload('replacements' => { 'foo' => 'bar' }).replacements).to eq([{ 'foo' => 'bar' }])
|
286
|
-
end
|
287
|
-
|
288
|
-
it 'can be specified as hash' do
|
289
|
-
expect(finder.reload(replacements: { 'foo' => 'bar' }).replacements).to eq([{ 'foo' => 'bar' }])
|
290
|
-
end
|
291
|
-
|
292
|
-
it 'can be specified as array of hashes' do
|
293
|
-
expect(finder.reload(replacements: [{ 'foo' => 'bar' }, { 'titi' => 'toto' }]).replacements).to eq([{ 'foo' => 'bar' }, { 'titi' => 'toto' }])
|
294
|
-
end
|
295
|
-
|
296
|
-
it 'can be specified as array of array' do
|
297
|
-
expect(finder.reload(replacements: [['foo', 'bar' ], ['titi' => 'toto']]).replacements).to eq([['foo', 'bar' ], ['titi' => 'toto']])
|
298
|
-
end
|
299
|
-
|
300
|
-
it 'raise an error if a string is given' do
|
301
|
-
expect {
|
302
|
-
finder.reload(replacements: 'foo')
|
303
|
-
}.to raise_error('Replacements must be an array or a hash, "foo" given')
|
304
|
-
end
|
305
|
-
|
306
|
-
it 'raise an error if it contains something else than an hash or array' do
|
307
|
-
expect {
|
308
|
-
finder.reload(replacements: [{ 'foo' => 'bar' }, 'titi'])
|
309
|
-
}.to raise_error('Replacements must contain only hashes or arrays')
|
310
|
-
end
|
311
|
-
|
312
|
-
end
|
313
|
-
|
314
|
-
end
|
data/spec/kagu/library_spec.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Kagu::Library do
|
4
|
-
|
5
|
-
let(:library) { Kagu::Library.new }
|
6
|
-
|
7
|
-
describe '#initialize' do
|
8
|
-
|
9
|
-
it 'is correct by default' do
|
10
|
-
expect(library.path).to eq("#{ENV['HOME']}/Music/iTunes/iTunes Music Library.xml")
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'raise an error if directory' do
|
14
|
-
expect {
|
15
|
-
Kagu::Library.new('/tmp')
|
16
|
-
}.to raise_error(Kagu::Error, 'No such file: "/tmp"')
|
17
|
-
end
|
18
|
-
|
19
|
-
it "raise an error if file can't be found" do
|
20
|
-
expect {
|
21
|
-
Kagu::Library.new('/tmp/bar.foo.baz')
|
22
|
-
}.to raise_error(Kagu::Error, 'No such file: "/tmp/bar.foo.baz"')
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
describe '#finder' do
|
28
|
-
|
29
|
-
it 'returns a Kagu::Finder instance' do
|
30
|
-
expect(library.finder).to be_a(Kagu::Finder)
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'options can be specified' do
|
34
|
-
expect(library.finder(replacements: { 'foo' => 'bar' }).replacements).to eq([{ 'foo' => 'bar' }])
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
describe '#playlists' do
|
40
|
-
|
41
|
-
it 'returns a Playlists object' do
|
42
|
-
expect(library.playlists).to be_a(Kagu::Playlists)
|
43
|
-
expect(library.playlists.library).to be(library)
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
describe '#tracks' do
|
49
|
-
|
50
|
-
it 'returns a Tracks object' do
|
51
|
-
expect(library.tracks).to be_a(Kagu::Tracks)
|
52
|
-
expect(library.tracks.library).to be(library)
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
data/spec/kagu/playlist_spec.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Kagu::Playlist do
|
4
|
-
|
5
|
-
let(:library) { Kagu::Library.new }
|
6
|
-
let(:playlist) { Kagu::Playlist.new(name: 'Best tracks', tracks: tracks) }
|
7
|
-
let(:tracks) { library.tracks.take(15) }
|
8
|
-
|
9
|
-
describe '#each' do
|
10
|
-
|
11
|
-
it 'is delegated to tracks' do
|
12
|
-
track = nil
|
13
|
-
playlist.each do |t|
|
14
|
-
track = t
|
15
|
-
break
|
16
|
-
end
|
17
|
-
expect(track).to be_a(Kagu::Track)
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
describe '#itunes_name=' do
|
23
|
-
|
24
|
-
it 'set name and convert entities' do
|
25
|
-
expect {
|
26
|
-
playlist.send(:itunes_name=, 'Hello & World')
|
27
|
-
}.to change { playlist.name }.from('Best tracks').to('Hello & World')
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
describe '#name' do
|
33
|
-
|
34
|
-
it 'is set at initialization' do
|
35
|
-
expect(Kagu::Playlist.new(name: 'Best tracks').name).to eq('Best tracks')
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'is squished' do
|
39
|
-
expect(Kagu::Playlist.new(name: "Best \t tracks\n").name).to eq('Best tracks')
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'is mandatory' do
|
43
|
-
expect {
|
44
|
-
Kagu::Playlist.new(name: ' ')
|
45
|
-
}.to raise_error(Kagu::Error, 'Kagu::Playlist#name is mandatory')
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
describe '#to_s' do
|
51
|
-
|
52
|
-
it 'is name' do
|
53
|
-
expect(Kagu::Playlist.new(name: 'Best tracks').to_s).to eq('Best tracks')
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
describe '#tracks' do
|
59
|
-
|
60
|
-
it 'is an empty array by default' do
|
61
|
-
expect(Kagu::Playlist.new(name: 'Test').tracks).to eq([])
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'is tracks given at initialization' do
|
65
|
-
expect(Kagu::Playlist.new(name: 'Test', tracks: tracks).tracks).to eq(tracks)
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'removes invalid tracks' do
|
69
|
-
expect(Kagu::Playlist.new(name: 'Test', tracks: ['bar', [tracks.first], 'foo']).tracks).to eq([tracks.first])
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
data/spec/kagu/playlists_spec.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Kagu::Playlists do
|
4
|
-
|
5
|
-
let(:library) { Kagu::Library.new }
|
6
|
-
let(:playlists) { Kagu::Playlists.new(library) }
|
7
|
-
|
8
|
-
describe '#each' do
|
9
|
-
|
10
|
-
it 'playlists must contains at least 1 song and a name' do
|
11
|
-
expect(playlists.count).to be > 5
|
12
|
-
playlists.each do |playlist|
|
13
|
-
expect(playlist.name).not_to eq('Bibliothèque')
|
14
|
-
expect(playlist.name).not_to match(/\&#\d+;/)
|
15
|
-
expect(playlist.name).to be_a(String)
|
16
|
-
expect(playlist.name).to be_present
|
17
|
-
expect(playlist.tracks.size).to be > 0
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'does not fails if block is not given' do
|
22
|
-
expect {
|
23
|
-
expect(playlists.each).to be_nil
|
24
|
-
}.not_to raise_error
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'returns nil' do
|
28
|
-
expect(playlists.each {}).to be_nil
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
describe '#library' do
|
34
|
-
|
35
|
-
it 'is library given at initialization' do
|
36
|
-
expect(playlists.library).to be(library)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'raise an error if library is nil' do
|
40
|
-
expect {
|
41
|
-
Kagu::Playlists.new(nil)
|
42
|
-
}.to raise_error(ArgumentError, 'Kagu::Playlists#library must be a library, nil given')
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
data/spec/kagu/track_spec.rb
DELETED
@@ -1,303 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Kagu::Track do
|
4
|
-
|
5
|
-
let(:attributes) { { added_at: track.added_at, album: track.album, artist: track.artist, id: track.id, length: track.length, path: track.path, title: track.title } }
|
6
|
-
let(:library) { Kagu::Library.new }
|
7
|
-
let(:track) { library.tracks.first }
|
8
|
-
|
9
|
-
describe '#==' do
|
10
|
-
|
11
|
-
let(:other) { track.dup }
|
12
|
-
|
13
|
-
it 'is false if not a track' do
|
14
|
-
expect(track == 'foo').to be(false)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'is false if artist differs' do
|
18
|
-
expect {
|
19
|
-
allow(other).to receive(:artist).and_return('Foo')
|
20
|
-
}.to change { track == other }.from(true).to(false)
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'is false if title differs' do
|
24
|
-
expect {
|
25
|
-
allow(other).to receive(:title).and_return('Bar')
|
26
|
-
}.to change { track == other }.from(true).to(false)
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'is false if length differs' do
|
30
|
-
expect {
|
31
|
-
allow(other).to receive(:length).and_return(track.length - 5)
|
32
|
-
}.to change { track == other }.from(true).to(false)
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'is true if length differs just a little' do
|
36
|
-
expect {
|
37
|
-
allow(other).to receive(:length).and_return(track.length - 2)
|
38
|
-
}.not_to change { track == other }
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'is true if album differs' do
|
42
|
-
expect {
|
43
|
-
allow(other).to receive(:album).and_return('Baz')
|
44
|
-
}.not_to change { track == other }
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
describe '#<=>' do
|
50
|
-
|
51
|
-
let(:other) { track.dup }
|
52
|
-
|
53
|
-
it 'compares tracks lengths' do
|
54
|
-
expect {
|
55
|
-
allow(other).to receive(:added_at).and_return(1.day.from_now)
|
56
|
-
}.to change { track <=> other }.from(0).to(-1)
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'is nil if added_at is nil' do
|
60
|
-
allow(track).to receive(:added_at).and_return(nil)
|
61
|
-
expect(track <=> other).to be_nil
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'is nil if other track added_at is nil' do
|
65
|
-
allow(other).to receive(:added_at).and_return(nil)
|
66
|
-
expect(track <=> other).to be_nil
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'is nil if other is not a track' do
|
70
|
-
expect(track <=> '').to be_nil
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
describe '#added_at' do
|
76
|
-
|
77
|
-
it 'returns a time' do
|
78
|
-
expect(track.added_at).to be_a(Time)
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'return a time in utc' do
|
82
|
-
expect(track.added_at.zone).to eq('UTC')
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'raise an error if not specified' do
|
86
|
-
expect {
|
87
|
-
Kagu::Track.new(attributes.except(:added_at))
|
88
|
-
}.to raise_error(Kagu::Error, 'Kagu::Track#added_at is mandatory')
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
describe '#album' do
|
94
|
-
|
95
|
-
it 'is is squished' do
|
96
|
-
track.send(:album=, " Life Is \r Peachy \n")
|
97
|
-
expect(track.album).to eq('Life Is Peachy')
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
describe '#artist' do
|
103
|
-
|
104
|
-
it 'is is squished' do
|
105
|
-
track.send(:artist=, " Benny \r Page \n")
|
106
|
-
expect(track.artist).to eq('Benny Page')
|
107
|
-
end
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
describe '#bpm' do
|
112
|
-
|
113
|
-
it 'is nil if invalid' do
|
114
|
-
track.send(:bpm=, "42a")
|
115
|
-
expect(track.bpm).to be_nil
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'is an integer' do
|
119
|
-
track.send(:bpm=, '143')
|
120
|
-
expect(track.bpm).to be(143)
|
121
|
-
end
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
describe '#eql?' do
|
126
|
-
|
127
|
-
it 'is true for same object' do
|
128
|
-
expect(track.eql?(track)).to be(true)
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'is true if == returns true' do
|
132
|
-
other = track.dup
|
133
|
-
expect {
|
134
|
-
allow(track).to receive(:==).and_return(false)
|
135
|
-
}.to change { track.eql?(other) }.from(true).to(false)
|
136
|
-
end
|
137
|
-
|
138
|
-
end
|
139
|
-
|
140
|
-
describe '#exists?' do
|
141
|
-
|
142
|
-
it 'is true if path is a file' do
|
143
|
-
expect {
|
144
|
-
allow(track).to receive(:path).and_return('/tmp/foo.mp3')
|
145
|
-
}.to change { track.exists? }.from(true).to(false)
|
146
|
-
end
|
147
|
-
|
148
|
-
it 'is false if path is a directory' do
|
149
|
-
expect {
|
150
|
-
allow(track).to receive(:path).and_return('/tmp')
|
151
|
-
}.to change { track.exists? }.from(true).to(false)
|
152
|
-
end
|
153
|
-
|
154
|
-
end
|
155
|
-
|
156
|
-
describe '#genre' do
|
157
|
-
|
158
|
-
it 'is correct' do
|
159
|
-
expect(track.genre).to be_a(String)
|
160
|
-
expect(track.genre).to be_present
|
161
|
-
end
|
162
|
-
|
163
|
-
end
|
164
|
-
|
165
|
-
describe '#id' do
|
166
|
-
|
167
|
-
it 'is correct' do
|
168
|
-
expect(track.id).to be_an(Integer)
|
169
|
-
expect(track.id).to be > 0
|
170
|
-
end
|
171
|
-
|
172
|
-
it 'raise an error if not specified' do
|
173
|
-
expect {
|
174
|
-
Kagu::Track.new(attributes.except(:id))
|
175
|
-
}.to raise_error(Kagu::Error, 'Kagu::Track#id is mandatory')
|
176
|
-
end
|
177
|
-
|
178
|
-
end
|
179
|
-
|
180
|
-
describe '#itunes_name=' do
|
181
|
-
|
182
|
-
it 'sets title with entities decoded' do
|
183
|
-
expect {
|
184
|
-
track.send(:itunes_name=, 'Racing & Green')
|
185
|
-
}.to change { track.title }.to('Racing & Green')
|
186
|
-
end
|
187
|
-
|
188
|
-
end
|
189
|
-
|
190
|
-
describe '#length' do
|
191
|
-
|
192
|
-
it 'is correct' do
|
193
|
-
expect(track.length).to be_an(Integer)
|
194
|
-
expect(track.length).to be > 0
|
195
|
-
end
|
196
|
-
|
197
|
-
it 'raise an error if not specified' do
|
198
|
-
expect {
|
199
|
-
Kagu::Track.new(attributes.except(:length))
|
200
|
-
}.to raise_error(Kagu::Error, 'Kagu::Track#length is mandatory')
|
201
|
-
end
|
202
|
-
|
203
|
-
end
|
204
|
-
|
205
|
-
describe '#path' do
|
206
|
-
|
207
|
-
it 'is correct' do
|
208
|
-
expect(track.path).to be_a(String)
|
209
|
-
expect(File.file?(track.path)).to be(true)
|
210
|
-
end
|
211
|
-
|
212
|
-
it 'raise an error if not specified' do
|
213
|
-
expect {
|
214
|
-
Kagu::Track.new(attributes.except(:path))
|
215
|
-
}.to raise_error(Kagu::Error, 'Kagu::Track#path is mandatory')
|
216
|
-
end
|
217
|
-
|
218
|
-
it 'does not raise an error if not found' do
|
219
|
-
expect {
|
220
|
-
Kagu::Track.new(attributes.merge(path: '/tmp/bar.mp3'))
|
221
|
-
}.not_to raise_error
|
222
|
-
end
|
223
|
-
|
224
|
-
it 'logs an error if not exist' do
|
225
|
-
expect(Kagu.logger).to receive(:error)
|
226
|
-
Kagu::Track.new(attributes.merge(path: '/tmp/bar.mp3'))
|
227
|
-
end
|
228
|
-
|
229
|
-
it 'raise an error if exists but not a file' do
|
230
|
-
expect {
|
231
|
-
Kagu::Track.new(attributes.merge(path: '/tmp'))
|
232
|
-
}.to raise_error(Kagu::Error, 'No such file: "/tmp"')
|
233
|
-
end
|
234
|
-
|
235
|
-
end
|
236
|
-
|
237
|
-
describe '#relative_path' do
|
238
|
-
|
239
|
-
it 'is correct' do
|
240
|
-
expect(track.relative_path(ENV['HOME'])).to eq(track.path.gsub("#{ENV['HOME']}/", ''))
|
241
|
-
end
|
242
|
-
|
243
|
-
it 'is full path if not starting with given path' do
|
244
|
-
expect(track.relative_path('/Users/john')).to eq(track.path)
|
245
|
-
end
|
246
|
-
|
247
|
-
end
|
248
|
-
|
249
|
-
describe '#title' do
|
250
|
-
|
251
|
-
it 'is is squished' do
|
252
|
-
track.send(:title=, " Racing \r Green \n")
|
253
|
-
expect(track.title).to eq('Racing Green')
|
254
|
-
end
|
255
|
-
|
256
|
-
end
|
257
|
-
|
258
|
-
describe '#to_s' do
|
259
|
-
|
260
|
-
it 'is "artist - title"' do
|
261
|
-
expect(track.to_s).to eq("#{track.artist} - #{track.title}")
|
262
|
-
end
|
263
|
-
|
264
|
-
end
|
265
|
-
|
266
|
-
describe '#year' do
|
267
|
-
|
268
|
-
it 'is an integer' do
|
269
|
-
expect(track.year).to be_an(Integer)
|
270
|
-
end
|
271
|
-
|
272
|
-
it 'is correct' do
|
273
|
-
expect(track.year.to_s).to match(/\A\d{4}\z/)
|
274
|
-
end
|
275
|
-
|
276
|
-
it 'is nil if negative' do
|
277
|
-
track.send(:year=, -1)
|
278
|
-
expect(track.year).to be_nil
|
279
|
-
end
|
280
|
-
|
281
|
-
it 'is nil if invalid' do
|
282
|
-
track.send(:year=, 20434)
|
283
|
-
expect(track.year).to be_nil
|
284
|
-
end
|
285
|
-
|
286
|
-
it 'can be < 1000' do
|
287
|
-
track.send(:year=, 942)
|
288
|
-
expect(track.year).to be(942)
|
289
|
-
end
|
290
|
-
|
291
|
-
it 'can be set as string' do
|
292
|
-
track.send(:year=, '1984')
|
293
|
-
expect(track.year).to be(1984)
|
294
|
-
end
|
295
|
-
|
296
|
-
it 'is nil if string is invalid' do
|
297
|
-
track.send(:year=, '1984 ')
|
298
|
-
expect(track.year).to be_nil
|
299
|
-
end
|
300
|
-
|
301
|
-
end
|
302
|
-
|
303
|
-
end
|
data/spec/kagu/tracks_spec.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Kagu::Tracks do
|
4
|
-
|
5
|
-
let(:library) { Kagu::Library.new }
|
6
|
-
let(:tracks) { Kagu::Tracks.new(library) }
|
7
|
-
|
8
|
-
describe '#each' do
|
9
|
-
|
10
|
-
it 'most of tracks must be correct path must be a file' do
|
11
|
-
tracks.take(100).each do |track|
|
12
|
-
expect(File.file?(track.path)).to be(true)
|
13
|
-
expect(track).to be_a(Kagu::Track)
|
14
|
-
expect(track.added_at).to be_a(Time)
|
15
|
-
expect(track.album).to be_a(String)
|
16
|
-
expect(track.album).to be_present
|
17
|
-
expect(track.artist).to be_a(String)
|
18
|
-
expect(track.artist).to be_present
|
19
|
-
expect(track.exists?).to be(true)
|
20
|
-
expect(track.genre).to be_a(String)
|
21
|
-
expect(track.genre).to be_present
|
22
|
-
expect(track.id).to be_an(Integer)
|
23
|
-
expect(track.length).to be_an(Integer)
|
24
|
-
expect(track.path).not_to include('file://')
|
25
|
-
expect(track.path).to include('Music')
|
26
|
-
expect(track.title).to be_a(String)
|
27
|
-
expect(track.title).to be_present
|
28
|
-
expect(track.year).to be_an(Integer)
|
29
|
-
expect(track.year.to_s).to match(/\A\d{4}\z/)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'does not fails if block is not given' do
|
34
|
-
expect {
|
35
|
-
expect(tracks.each).to be_nil
|
36
|
-
}.not_to raise_error
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'returns nil' do
|
40
|
-
expect(tracks.each {}).to be_nil
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'all tracks must exists and path should not include UTF-8-MAC charset' do
|
44
|
-
library.tracks.each do |track|
|
45
|
-
expect(track.path).not_to include("\u{65}\u{301}")
|
46
|
-
expect(track.exists?).to be(true)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
describe '#library' do
|
53
|
-
|
54
|
-
it 'is library given at initialization' do
|
55
|
-
expect(tracks.library).to be(library)
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'raise an error if library is nil' do
|
59
|
-
expect {
|
60
|
-
Kagu::Tracks.new(nil)
|
61
|
-
}.to raise_error(ArgumentError, 'Kagu::Tracks#library must be a library, nil given')
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|