cultome_player 2.0.0 → 2.0.2
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/README.md +24 -79
- data/Rakefile +38 -4
- data/bin/cultome_player +16 -4
- data/config/environment.yml +4 -0
- data/cultome_player.gemspec +8 -1
- data/lib/cultome_player.rb +45 -19
- data/lib/cultome_player/command/language.rb +3 -4
- data/lib/cultome_player/command/processor.rb +9 -7
- data/lib/cultome_player/command/reader.rb +11 -2
- data/lib/cultome_player/environment.rb +21 -13
- data/lib/cultome_player/events.rb +7 -7
- data/lib/cultome_player/objects/album.rb +9 -2
- data/lib/cultome_player/objects/artist.rb +9 -2
- data/lib/cultome_player/objects/command.rb +10 -1
- data/lib/cultome_player/objects/drive.rb +4 -1
- data/lib/cultome_player/objects/genre.rb +4 -1
- data/lib/cultome_player/objects/parameter.rb +21 -1
- data/lib/cultome_player/objects/response.rb +5 -1
- data/lib/cultome_player/objects/song.rb +9 -4
- data/lib/cultome_player/player/adapter/mpg123.rb +3 -4
- data/lib/cultome_player/player/interactive.rb +67 -11
- data/lib/cultome_player/player/interface/basic.rb +13 -9
- data/lib/cultome_player/player/interface/extended.rb +26 -12
- data/lib/cultome_player/player/interface/helper.rb +73 -9
- data/lib/cultome_player/plugins.rb +44 -18
- data/lib/cultome_player/plugins/alias.rb +85 -0
- data/lib/cultome_player/plugins/gestures.rb +90 -0
- data/lib/cultome_player/plugins/help.rb +4 -4
- data/lib/cultome_player/plugins/keyboard_special_keys.rb +22 -0
- data/lib/cultome_player/plugins/points.rb +51 -0
- data/lib/cultome_player/utils.rb +117 -7
- data/lib/cultome_player/version.rb +1 -1
- data/xbindkeys/xbindkeysrc +12 -0
- metadata +37 -89
- data/.coveralls.yml +0 -1
- data/.gitignore +0 -24
- data/.rspec +0 -2
- data/.travis.yml +0 -7
- data/db/001_create_schema.rb +0 -58
- data/spec/config.yml +0 -0
- data/spec/cultome_player/command/processor_spec.rb +0 -168
- data/spec/cultome_player/command/reader_spec.rb +0 -45
- data/spec/cultome_player/cultome_player_spec.rb +0 -17
- data/spec/cultome_player/environment_spec.rb +0 -65
- data/spec/cultome_player/events_spec.rb +0 -22
- data/spec/cultome_player/media_spec.rb +0 -41
- data/spec/cultome_player/player/adapter/mpg123_spec.rb +0 -82
- data/spec/cultome_player/player/interface/basic_spec.rb +0 -168
- data/spec/cultome_player/player/interface/extended/connect_spec.rb +0 -117
- data/spec/cultome_player/player/interface/extended/search_spec.rb +0 -90
- data/spec/cultome_player/player/interface/extended/show_spec.rb +0 -36
- data/spec/cultome_player/player/interface/extended/shuffle_spec.rb +0 -26
- data/spec/cultome_player/player/interface/extended_spec.rb +0 -136
- data/spec/cultome_player/player/interface/helper_spec.rb +0 -63
- data/spec/cultome_player/player/interface_spec.rb +0 -17
- data/spec/cultome_player/player/playlist_spec.rb +0 -301
- data/spec/cultome_player/plugins/help_spec.rb +0 -21
- data/spec/cultome_player/plugins_spec.rb +0 -19
- data/spec/cultome_player/utils_spec.rb +0 -15
- data/spec/spec_helper.rb +0 -108
- data/spec/test/uno/dos/dos.mp3 +0 -0
- data/spec/test/uno/dos/tres/tres.mp3 +0 -0
- data/spec/test/uno/uno.mp3 +0 -0
- data/tasks/console.rake +0 -19
- data/tasks/db.rake +0 -19
- data/tasks/run.rake +0 -7
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe CultomePlayer::Player::Adapter::Mpg123 do
|
4
|
-
let(:t){ TestClass.new }
|
5
|
-
let(:song) do
|
6
|
-
s = Song.new
|
7
|
-
s.stub(:path){'/duck/path'}
|
8
|
-
s
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'can check if player is running' do
|
12
|
-
t.should respond_to :player_running?
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'start the player if is not running' do
|
16
|
-
t.should_receive :start_player
|
17
|
-
t.should_not be_player_running
|
18
|
-
t.play_in_player song
|
19
|
-
end
|
20
|
-
|
21
|
-
context 'with active playback' do
|
22
|
-
before :each do
|
23
|
-
t.play_in_player song
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'pause a song' do
|
27
|
-
t.should_receive(:send_to_player).with('pause')
|
28
|
-
t.pause_in_player
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'stops a song' do
|
32
|
-
t.should_receive(:send_to_player).with('stop')
|
33
|
-
t.stop_in_player
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'resume a paused song' do
|
37
|
-
t.pause_in_player
|
38
|
-
t.should_receive(:send_to_player).with("pause")
|
39
|
-
t.resume_in_player
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'resume a stopped song' do
|
43
|
-
t.stop_in_player
|
44
|
-
t.should_receive(:start_player)
|
45
|
-
t.play_in_player song
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'running actual mpg123 player', mplayer: true do
|
50
|
-
it 'dont show the initial text from mpg123' do
|
51
|
-
th = Thread.new do
|
52
|
-
class MplayerTest
|
53
|
-
include CultomePlayer
|
54
|
-
end
|
55
|
-
|
56
|
-
song1 = double(:song1, path: "/home/csoria/music/unknown/Torches/02 Pumped Up Kicks.mp3")
|
57
|
-
song2 = double(:song2, path: "/home/csoria/music/unknown/Torches/07 Houdini.mp3")
|
58
|
-
p = MplayerTest.new
|
59
|
-
p.prepare_environment(:rspec)
|
60
|
-
|
61
|
-
puts "Primera cancion..."
|
62
|
-
p.play_in_player(song1)
|
63
|
-
i = 0
|
64
|
-
while i < 3
|
65
|
-
sleep 1
|
66
|
-
i += 1
|
67
|
-
end
|
68
|
-
|
69
|
-
puts "Segunda cancion(running: #{p.player_running?})..."
|
70
|
-
p.play_in_player(song2)
|
71
|
-
i = 0
|
72
|
-
while i < 3
|
73
|
-
sleep 1
|
74
|
-
i += 1
|
75
|
-
end
|
76
|
-
puts "Terminado!"
|
77
|
-
end # Thread
|
78
|
-
|
79
|
-
th.join
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,168 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe CultomePlayer::Player::Interface::Basic do
|
4
|
-
let(:t){ TestClass.new }
|
5
|
-
|
6
|
-
describe '#pause' do
|
7
|
-
it 'calls the underliying player' do
|
8
|
-
t.should_receive(:pause_in_player)
|
9
|
-
t.execute "pause on"
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'respond to description_help' do
|
13
|
-
t.should respond_to(:description_help)
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'respond to usage_help' do
|
17
|
-
t.should respond_to(:usage_help)
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'respond with Response object' do
|
21
|
-
t.execute("pause on").should be_instance_of Response
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#stop' do
|
26
|
-
before :each do
|
27
|
-
t.execute "connect '#{test_folder}' => test"
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'calls the underliying player' do
|
31
|
-
t.should_receive(:stop_in_player)
|
32
|
-
t.execute "play"
|
33
|
-
t.execute "stop"
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'respond to description_stop' do
|
37
|
-
t.should respond_to(:description_stop)
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'respond to usage_stop' do
|
41
|
-
t.should respond_to(:usage_stop)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'respond with Response object' do
|
45
|
-
t.execute("stop").should be_instance_of Response
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe '#play' do
|
50
|
-
|
51
|
-
it 'respond to description_play' do
|
52
|
-
t.should respond_to(:description_play)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'respond to usage_play' do
|
56
|
-
t.should respond_to(:usage_play)
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'respond with Response object' do
|
60
|
-
t.execute("play").should be_instance_of Response
|
61
|
-
end
|
62
|
-
|
63
|
-
context 'without music connected' do
|
64
|
-
it 'advise to connect music first if no music is connected' do
|
65
|
-
r = t.execute("play")
|
66
|
-
r.message.should eq "No music connected! You should try 'connect /home/yoo/music => main' first"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context 'with music connected' do
|
71
|
-
before :each do
|
72
|
-
t.execute "connect '#{test_folder}' => test"
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'calls the underliying player to play' do
|
76
|
-
t.should_receive(:play_in_player)
|
77
|
-
t.execute 'play'
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'calls the underliying player to resume playback' do
|
81
|
-
t.should_receive(:resume_in_player)
|
82
|
-
t.execute 'play'
|
83
|
-
t.execute "pause on"
|
84
|
-
t.execute 'play'
|
85
|
-
end
|
86
|
-
|
87
|
-
context 'without parameters' do
|
88
|
-
it 'in clean state should play all the library' do
|
89
|
-
r = t.execute 'play'
|
90
|
-
r.playlist.should have(3).items
|
91
|
-
r.should respond_to(:now_playing)
|
92
|
-
r.should respond_to(:playlist)
|
93
|
-
t.current_playlist.to_a.should have(3).items
|
94
|
-
t.current_song.should_not be_nil
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'if paused should resume playback' do
|
98
|
-
t.execute "pause on"
|
99
|
-
t.should be_paused
|
100
|
-
t.execute 'play'
|
101
|
-
t.should_not be_paused
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'if stopped should resume last playback from the begin' do
|
105
|
-
t.execute "play"
|
106
|
-
my_song = t.current_song
|
107
|
-
t.execute "stop"
|
108
|
-
t.should be_stopped
|
109
|
-
t.execute 'play'
|
110
|
-
t.should be_playing
|
111
|
-
my_song.should eq t.current_song
|
112
|
-
end
|
113
|
-
|
114
|
-
it 'get an error message if playing' do
|
115
|
-
t.execute 'play'
|
116
|
-
r = t.execute 'play'
|
117
|
-
r.message.should eq 'What you mean? Im already playing!'
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'with number parameter' do
|
122
|
-
it 'play the nth element in focus list without altering the current playlist' do
|
123
|
-
t.execute 'search a'
|
124
|
-
t.execute 'play 2'
|
125
|
-
t.current_song.name.should eq t.playlists[:focus].at(1).name
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'with criteria parameter' do
|
130
|
-
it 'different criterias create an AND filter' do
|
131
|
-
t.execute "play t:a"
|
132
|
-
t.current_playlist.should have(2).songs
|
133
|
-
t.execute "play t:a a:m"
|
134
|
-
t.current_playlist.should have(1).songs
|
135
|
-
end
|
136
|
-
|
137
|
-
it 'same criterias create an OR filter' do
|
138
|
-
t.execute "play t:a"
|
139
|
-
t.current_playlist.should have(2).songs
|
140
|
-
t.execute "play t:a t:d"
|
141
|
-
t.current_playlist.should have(3).songs
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
context 'with object parameter' do
|
146
|
-
it 'replace the current playlist with the object content' do
|
147
|
-
t.execute 'play'
|
148
|
-
t.current_playlist.should have(3).songs
|
149
|
-
t.execute 'next'
|
150
|
-
t.execute 'next'
|
151
|
-
t.execute 'play @history'
|
152
|
-
t.current_playlist.should have(2).songs
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
context 'with literal parameter' do
|
157
|
-
it 'create an OR filter with the fields trackname, artist and album' do
|
158
|
-
t.execute 'play way'
|
159
|
-
t.current_playlist.should have(1).songs
|
160
|
-
t.execute 'play sing'
|
161
|
-
t.current_playlist.should have(1).songs
|
162
|
-
t.execute 'play sing way'
|
163
|
-
t.current_playlist.should have(2).songs
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
include CultomePlayer::Objects
|
4
|
-
|
5
|
-
describe CultomePlayer::Player::Interface::Extended do
|
6
|
-
let(:t){ TestClass.new }
|
7
|
-
|
8
|
-
before :each do
|
9
|
-
Song.create!(id: 1, name: "song_uno", artist_id: 1, album_id: 1, drive_id: 1, relative_path: "uno/uno.mp3")
|
10
|
-
Song.create!(id: 2, name: "song_dos", artist_id: 1, album_id: 1, drive_id: 1, relative_path: "uno/dos/dos.mp3")
|
11
|
-
|
12
|
-
Artist.create!(id: 1, name: "artist_uno")
|
13
|
-
|
14
|
-
Album.create!(id: 1, name: "album_uno")
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'detect all the files in the subdirectories' do
|
18
|
-
r = t.execute "connect '#{test_folder}' => test"
|
19
|
-
r.files_detected.should eq 3
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'import the files not imported before and update the rest' do
|
23
|
-
r = t.execute "connect '#{test_folder}' => test"
|
24
|
-
r.files_detected.should eq 3
|
25
|
-
r.files_updated.should eq 2
|
26
|
-
r.files_imported.should eq 1
|
27
|
-
end
|
28
|
-
|
29
|
-
context 'with only a literal parameter' do
|
30
|
-
it 'connect the named drive if exist' do
|
31
|
-
Drive.create!(name: "test", path: test_folder, connected: false)
|
32
|
-
Drive.find_by(name: 'test').should_not be_connected
|
33
|
-
r = t.execute "connect test"
|
34
|
-
Drive.find_by(name: 'test').should be_connected
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'raise an error if drive not exists' do
|
38
|
-
r = t.execute("connect ghost")
|
39
|
-
r.message.should eq 'invalid name'
|
40
|
-
r.details.should eq 'the named drive doesnt exists'
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context 'with a path and a literal' do
|
45
|
-
it 'create the drive if not exists' do
|
46
|
-
Drive.find_by(name: 'new').should be_nil
|
47
|
-
r = t.execute "connect '#{test_folder}' => new"
|
48
|
-
Drive.find_by(name: 'new').should_not be_nil
|
49
|
-
r.drive_updated.should be_false
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'update the drive if exists' do
|
53
|
-
Drive.create!(name: "test", path: test_folder)
|
54
|
-
r = t.execute "connect '#{test_folder}' => test"
|
55
|
-
r.drive_updated.should be_true
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'raise an error if path is invalid' do
|
59
|
-
r = t.execute('connect /invalid => ghost')
|
60
|
-
r.message.should eq 'invalid path'
|
61
|
-
r.details.should eq 'the directory is invalid'
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe 'with mp3 files' do
|
66
|
-
let(:t2){ TestClass.new }
|
67
|
-
|
68
|
-
before :each do
|
69
|
-
Drive.create!(name: "library", path: test_folder)
|
70
|
-
end
|
71
|
-
|
72
|
-
describe 'create information from file' do
|
73
|
-
it 'create the song' do
|
74
|
-
expect{ t2.execute "connect '#{test_folder}' => test" }.to change{ Song.all.count }.by(1)
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'create the artist' do
|
78
|
-
expect{ t2.execute "connect '#{test_folder}' => test" }.to change{ Artist.all.count }.by(2) # una de las rolas no tiene artist
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'create the album' do
|
82
|
-
expect{ t2.execute "connect '#{test_folder}' => test" }.to change{ Album.all.count }.by(2) # una de las rolas no tiene album
|
83
|
-
end
|
84
|
-
|
85
|
-
context 'already imported into library' do
|
86
|
-
before :each do
|
87
|
-
DatabaseCleaner.clean_with(:truncation)
|
88
|
-
r = t2.execute "connect '#{test_folder}/uno/dos/tres' => test"
|
89
|
-
r.files_imported.should eq 1
|
90
|
-
r.files_updated.should eq 0
|
91
|
-
@track = Song.all.first
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'insert the correct song information' do
|
95
|
-
@track.name.should eq "Sing For Absolution"
|
96
|
-
@track.year.should eq 2003
|
97
|
-
@track.track.should eq 4
|
98
|
-
@track.duration.should eq 295
|
99
|
-
@track.relative_path.should eq "tres.mp3"
|
100
|
-
# dependencias
|
101
|
-
@track.artist_id.should eq 1
|
102
|
-
@track.album_id.should eq 1
|
103
|
-
@track.drive_id.should eq 1
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'insert the correct artist information' do
|
107
|
-
@track.artist.name.should eq "Muse"
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'insert the correct album information' do
|
111
|
-
@track.album.name.should eq "Absolution"
|
112
|
-
@track.album.artists.first.name.should eq "Muse"
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
include CultomePlayer::Objects
|
4
|
-
|
5
|
-
describe CultomePlayer::Player::Interface::Extended do
|
6
|
-
let(:t){ TestClass.new }
|
7
|
-
|
8
|
-
before :each do
|
9
|
-
Drive.create!(id: 1, name: 'test', path: '/patito', connected: true)
|
10
|
-
Song.create!(id: 1, name: "song_uno", artist_id: 1, album_id: 1, drive_id: 1, relative_path: "uno/uno.mp3")
|
11
|
-
Song.create!(id: 2, name: "song_dos", artist_id: 1, album_id: 2, drive_id: 1, relative_path: "uno/dos/dos.mp3")
|
12
|
-
Song.create!(id: 3, name: "song_tres", artist_id: 1, album_id: 2, drive_id: 1, relative_path: "uno/dos/tres/tres.mp3")
|
13
|
-
Song.create!(id: 4, name: "song_cuatro", artist_id: 2, album_id: 3, drive_id: 1, relative_path: "fake/cuatro.mp3")
|
14
|
-
Song.create!(id: 5, name: "song_cinco", artist_id: 3, album_id: 4, drive_id: 1, relative_path: "fake/cinco.mp3")
|
15
|
-
|
16
|
-
Artist.create!(id: 1, name: "artist_uno")
|
17
|
-
Artist.create!(id: 2, name: "artist_dos")
|
18
|
-
Artist.create!(id: 3, name: "artist_tres")
|
19
|
-
Artist.create!(id: 4, name: "artist_cuatro")
|
20
|
-
|
21
|
-
Album.create!(id: 1, name: "album_uno")
|
22
|
-
Album.create!(id: 2, name: "album_dos")
|
23
|
-
Album.create!(id: 3, name: "album_tres")
|
24
|
-
Album.create!(id: 4, name: "album_cuatro")
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'return a Response object' do
|
28
|
-
t.execute('search a:artist_uno').should be_instance_of Response
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'respond success when there are results' do
|
32
|
-
r = t.execute('search a:artist_uno')
|
33
|
-
r.should be_success
|
34
|
-
r.should respond_to :songs
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'respond failure when there are not results' do
|
38
|
-
r = t.execute('search a:nothing')
|
39
|
-
r.should be_failure
|
40
|
-
r.should respond_to :message
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'with criteria parameters' do
|
44
|
-
it 'different criterias create an AND filter' do
|
45
|
-
r = t.execute 'search a:artist_uno b:album_dos'
|
46
|
-
songs = r.send(r.response_type)
|
47
|
-
songs.should have(2).items
|
48
|
-
songs.each{|s| s.artist.name.should match /uno/ }
|
49
|
-
songs.each{|s| s.album.name.should match /dos/ }
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'same criterias create an OR filter' do
|
53
|
-
r = t.execute 'search a:artist_dos a:artist_tres'
|
54
|
-
songs = r.send(r.response_type)
|
55
|
-
songs.should have(2).songs
|
56
|
-
songs.each{|s| s.artist.name.should match /(dos|tres)/ }
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'with object parameters' do
|
61
|
-
it 'search using an object as criteria' do
|
62
|
-
r = t.execute 'search @artist'
|
63
|
-
songs = r.send(r.response_type)
|
64
|
-
songs.should have(3).item
|
65
|
-
songs.each{|s| s.artist.name.should eq t.current_artist.name }
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'create and OR filter more than one object' do
|
69
|
-
t.execute('search @artist @album').should have(4).songs
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'with literal parameters' do
|
74
|
-
it 'create an OR filter with the fields trackname, artist and album' do
|
75
|
-
t.execute('search song_cuatro song_cinco').should have(2).songs
|
76
|
-
t.execute('search song_uno song_dos').should have(2).songs
|
77
|
-
t.execute('search album_dos cinco').should have(3).songs
|
78
|
-
t.execute('search cinco').should have(1).songs
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
context 'with mixed parameters' do
|
83
|
-
it 'create an OR filter between each type' do
|
84
|
-
t.execute('search t:song_tres artist_tres @album').should have(3).songs
|
85
|
-
t.execute('search t:song_cuatro t:song_dos @album').should have(2).songs
|
86
|
-
t.execute('search song_dos song_uno').should have(2).songs
|
87
|
-
t.execute('search @artist song_tres').should have(3).songs
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|