radiodan 0.0.1 → 0.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.
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'event_binding'
3
+
4
+ describe Radiodan::EventBinding do
5
+ it 'exists' do
6
+ subject.is_a?(Class)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'logging'
3
+
4
+ describe Radiodan::Logging do
5
+ it 'exists' do
6
+ subject.is_a?(Class)
7
+ end
8
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+ require 'player'
3
+
4
+ describe Radiodan::Player do
5
+ context 'adapter' do
6
+ it 'accepts an adapter' do
7
+ adapter = mock.as_null_object
8
+ subject.adapter = adapter
9
+ subject.adapter.should == adapter
10
+ end
11
+
12
+ it 'passes itself to the adapter' do
13
+ adapter = stub
14
+ adapter.should_receive(:player=).with(subject)
15
+
16
+ subject.adapter = adapter
17
+ end
18
+ end
19
+
20
+ context 'playlist' do
21
+ it 'triggers a new playlist event' do
22
+ playlist = mock
23
+
24
+ subject.should_receive(:trigger_event).with(:playlist, playlist)
25
+ subject.playlist = playlist
26
+ end
27
+ end
28
+
29
+ context 'syncs' do
30
+ before :each do
31
+ subject.playlist = stub.as_null_object
32
+ subject.adapter = stub.as_null_object
33
+ end
34
+
35
+ it 'returns false unless adapter is set' do
36
+ subject.stub(:adapter).and_return(nil)
37
+ subject.sync.should == false
38
+ end
39
+
40
+ it 'returns true if expected and actual state are the same' do
41
+ Radiodan::PlaylistSync.any_instance.stub(:sync?).and_return(true)
42
+
43
+ subject.sync.should == true
44
+ end
45
+
46
+ context 'sync error triggers events' do
47
+ before :each do
48
+ Radiodan::PlaylistSync.any_instance.stub(:sync?).and_return(false)
49
+ end
50
+
51
+ it 'playback state' do
52
+ Radiodan::PlaylistSync.any_instance.stub(:errors).and_return([:state])
53
+ subject.playlist.stub(:state => :playing)
54
+
55
+ subject.should_receive(:trigger_event).with(:play_state, :playing)
56
+ subject.sync.should == false
57
+ end
58
+
59
+ it 'playback mode' do
60
+ Radiodan::PlaylistSync.any_instance.stub(:errors).and_return([:mode])
61
+ subject.playlist.stub(:mode => :random)
62
+
63
+ subject.should_receive(:trigger_event).with(:play_mode, :random)
64
+ subject.sync.should == false
65
+ end
66
+
67
+ it 'playlist' do
68
+ Radiodan::PlaylistSync.any_instance.stub(:errors).and_return([:playlist])
69
+
70
+ playlist_content = stub
71
+ subject.playlist.stub(:content => playlist_content)
72
+
73
+ subject.should_receive(:trigger_event).with(:playlist, subject.playlist)
74
+ subject.sync.should == false
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ require 'adapter/mpd/playlist_parser'
3
+
4
+ describe Radiodan::MPD::PlaylistParser do
5
+ before :all do
6
+ @attributes = { "volume"=>"57", "repeat"=>"1", "random"=>"1", "single"=>"0", "consume"=>"0", "playlist"=>"3",
7
+ "playlistlength"=>"1", "xfade"=>"0", "mixrampdb"=>"0.000000", "mixrampdelay"=>"nan", "state"=>"pause",
8
+ "song"=>"0", "songid"=>"2", "time"=>"0:0", "elapsed"=>"214.599", "bitrate"=>"0", "audio"=>"0:?:0" }
9
+ end
10
+
11
+ it 'creates matching playlist object' do
12
+ playlist = subject.parse(@attributes, [file: '1'])
13
+
14
+ playlist.state.should == :pause
15
+ playlist.mode.should == :random
16
+ playlist.repeat.should == true
17
+ playlist.tracks.should == [file: '1']
18
+ playlist.position.should == 0
19
+ playlist.seek.should == 214.599
20
+ playlist.volume.should == 57
21
+ end
22
+ end
23
+
@@ -0,0 +1,147 @@
1
+ require 'spec_helper'
2
+ require 'playlist'
3
+
4
+ describe Radiodan::Playlist do
5
+ describe 'default attributes' do
6
+ it 'has a state of playing' do
7
+ subject.state.should == :play
8
+ end
9
+
10
+ it 'has a playback mode of sequential' do
11
+ subject.mode.should == :sequential
12
+ end
13
+
14
+ it 'has a repeat value of false' do
15
+ subject.repeat.should == false
16
+ end
17
+
18
+ it 'has an empty array of tracks' do
19
+ subject.tracks.should == Array.new
20
+ end
21
+
22
+ it 'has a starting position of zero' do
23
+ subject.position.should == 0
24
+ end
25
+
26
+ it 'has a default seek of 0.0' do
27
+ subject.seek.should == 0.0
28
+ end
29
+
30
+ it 'has a default volume of 100%' do
31
+ subject.volume.should == 100
32
+ end
33
+ end
34
+
35
+ describe 'playback state' do
36
+ it 'can be set' do
37
+ subject.state = :play
38
+ subject.state.should == :play
39
+ end
40
+
41
+ it 'cannot be set to an unknown state' do
42
+ subject.class::STATES.should_not include :nothing
43
+ expect { subject.state = :nothing }.to raise_error subject.class::StateError
44
+ end
45
+ end
46
+
47
+ describe 'playback mode' do
48
+ it 'can be set' do
49
+ subject.mode = :sequential
50
+ subject.mode.should == :sequential
51
+ end
52
+
53
+ it 'cannot be set to an unknown state' do
54
+ subject.class::MODES.should_not include :inverted
55
+ expect { subject.mode = :inverted }.to raise_error subject.class::ModeError
56
+ end
57
+ end
58
+
59
+ describe 'repeat mode' do
60
+ it 'can be set' do
61
+ subject.repeat = true
62
+ subject.repeat.should == true
63
+ end
64
+
65
+ it 'is only set to true when passed TrueClass' do
66
+ subject.repeat = 1
67
+ subject.repeat.should == false
68
+
69
+ subject.repeat = 'true'
70
+ subject.repeat.should == false
71
+ end
72
+ end
73
+
74
+ describe 'tracks' do
75
+ it 'creates an array of tracks' do
76
+ subject.tracks = 'x.mp3'
77
+ subject.tracks.size.should == 1
78
+ subject.tracks.first.should == {file: 'x.mp3'}
79
+ subject.position.should == 0
80
+ end
81
+
82
+ it 'accepts an array of tracks' do
83
+ subject.tracks = '1.mp3', '2.mp3'
84
+ subject.tracks.size.should == 2
85
+ end
86
+ end
87
+
88
+ describe 'starting position' do
89
+ before :each do
90
+ subject.tracks = 'a.mp3'
91
+ end
92
+
93
+ it 'should not be larger than the size of the playlist' do
94
+ expect { subject.position = 1 }.to_not raise_error
95
+ expect { subject.position = 2 }.to raise_error subject.class::PositionError
96
+ end
97
+
98
+ it 'should be cast to an integer' do
99
+ subject.position = '1'
100
+ subject.position.should == 1
101
+ end
102
+
103
+ it 'raises when it cannot be coerced into integer' do
104
+ expect { subject.position = 'dave' }.to raise_error subject.class::PositionError
105
+ subject.position.should == 0
106
+ end
107
+ end
108
+
109
+ describe 'current item playing' do
110
+ before :each do
111
+ subject.tracks = %w{1.mp3 2.mp3}
112
+ end
113
+
114
+ it 'returns item from current position' do
115
+ subject.position.should == 0
116
+ subject.current.should == '1.mp3'
117
+ end
118
+ end
119
+
120
+ describe 'seek time' do
121
+ it 'is expressed as a float' do
122
+ subject.seek = '22'
123
+ subject.seek.should == 22.0
124
+
125
+ subject.seek = 22.2
126
+ subject.seek.should == 22.2
127
+ end
128
+
129
+ it 'raises when it cannot be coerced into a float' do
130
+ expect { subject.seek = 'dave' }.to raise_error subject.class::SeekError
131
+ subject.seek.should == 0.0
132
+ end
133
+ end
134
+
135
+ describe 'volume' do
136
+ it 'is expressed as an integer' do
137
+ subject.volume = '24'
138
+ subject.volume.should == 24
139
+ end
140
+
141
+ it 'has a legal range of 0-100' do
142
+ expect { subject.volume = '999' }.to raise_error subject.class::VolumeError
143
+ expect { subject.volume = -29 }.to raise_error subject.class::VolumeError
144
+ subject.volume.should == 100
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+ require 'playlist_sync'
3
+
4
+ describe Radiodan::PlaylistSync do
5
+ subject(:playlist_sync) do
6
+ Radiodan::PlaylistSync.new \
7
+ stub(:state => nil, :mode => nil, :tracks => [], :size => 0),
8
+ stub(:state => nil, :mode => nil, :tracks => [], :size => 0)
9
+ end
10
+
11
+ context 'prerequisites for sync' do
12
+ it 'requires expected playlist' do
13
+ playlist_sync.expected = nil
14
+ expect { playlist_sync.sync? }.to raise_error(Radiodan::PlaylistSync::SyncError)
15
+ end
16
+
17
+ it 'requires current state' do
18
+ playlist_sync.current = nil
19
+ expect { playlist_sync.sync? }.to raise_error(Radiodan::PlaylistSync::SyncError)
20
+ end
21
+ end
22
+
23
+ context 'playback state' do
24
+ before :each do
25
+ playlist_sync.stub(:compare_playback_mode => true, :compare_playlist => true)
26
+ playlist_sync.expected.stub(:state => :playing)
27
+ end
28
+
29
+ it 'catches non-matching state' do
30
+ playlist_sync.current.stub(:state => :paused)
31
+
32
+ playlist_sync.sync?.should == false
33
+ playlist_sync.errors.should == [:state]
34
+ end
35
+
36
+ it 'allows matching state' do
37
+ playlist_sync.current.stub(:state => :playing)
38
+ playlist_sync.sync?.should == true
39
+ playlist_sync.errors.should be_empty
40
+ end
41
+ end
42
+
43
+ context 'playback mode' do
44
+ before :each do
45
+ playlist_sync.stub(:compare_playback_state => true, :compare_playlist => true)
46
+ playlist_sync.expected.stub(:mode => :random)
47
+ end
48
+
49
+ it 'catches non-matching state' do
50
+ playlist_sync.current.stub(:mode => :resume)
51
+
52
+ playlist_sync.sync?.should == false
53
+ playlist_sync.errors.should == [:mode]
54
+ end
55
+
56
+ it 'allows matching state' do
57
+ playlist_sync.current.stub(:mode => :random)
58
+ playlist_sync.sync?.should == true
59
+ playlist_sync.errors.should be_empty
60
+ end
61
+ end
62
+
63
+ context 'playlists' do
64
+ before :each do
65
+ playlist_sync.stub(:compare_playback_mode => true, :compare_playback_state => true)
66
+ playlist_sync.expected.stub(:tracks => [1,2,3,4], :size => 4)
67
+ end
68
+
69
+ it 'catches non-matching tracks' do
70
+ playlist_sync.current.stub(:tracks => [], :size => 4)
71
+
72
+ playlist_sync.sync?.should == false
73
+ playlist_sync.errors.should == [:playlist]
74
+ end
75
+
76
+ it 'catches non-matching size' do
77
+ playlist_sync.current.stub(:tracks => [1,2,3,4], :size => 2)
78
+
79
+ playlist_sync.sync?.should == false
80
+ playlist_sync.errors.should == [:playlist]
81
+ end
82
+
83
+ it 'allows matching state' do
84
+ playlist_sync.current.stub(:tracks => [1,2,3,4], :size => 4)
85
+ playlist_sync.sync?.should == true
86
+ playlist_sync.errors.should be_empty
87
+ end
88
+ end
89
+
90
+ context 'error messages' do
91
+ it 'captures multiple errors' do
92
+ playlist_sync.expected.stub(:tracks => [1], :mode => :random, :size => 1)
93
+ playlist_sync.sync?.should == false
94
+ playlist_sync.errors.should == [:mode, :playlist]
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'track'
3
+
4
+ describe Radiodan::Track do
5
+ it "requires a file attribute" do
6
+ expect { Radiodan::Track.new(:name => stub) }.to raise_error Radiodan::Track::NoFileError
7
+ expect { Radiodan::Track.new(:file => stub) }.to_not raise_error
8
+ end
9
+
10
+ context "parsing attributes" do
11
+ it "with symbols" do
12
+ file = stub
13
+ track = Radiodan::Track.new(:file => file)
14
+ track[:file].should == file
15
+ track['file'].should == file
16
+ end
17
+
18
+ it "with strings" do
19
+ file = stub
20
+ track = Radiodan::Track.new('file' => file)
21
+ track[:file].should == file
22
+ track['file'].should == file
23
+ end
24
+
25
+ it "into reader methods" do
26
+ file = stub
27
+ track = Radiodan::Track.new(:file => file)
28
+ track.file.should == file
29
+ end
30
+ end
31
+
32
+ context "comparison" do
33
+ it 'is equal when files match' do
34
+ file1 = stub
35
+ file2 = stub
36
+
37
+ Radiodan::Track.new(file: file1).should == Radiodan::Track.new(file: file1)
38
+ Radiodan::Track.new(file: file1).should_not == Radiodan::Track.new(file: file2)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ require 'rspec/autorun'
2
+ $: << File.expand_path('../../lib/radiodan', __FILE__)
3
+
4
+ RSpec.configure do |config|
5
+ #config.mock_with :mocha
6
+
7
+ # Use color in STDOUT
8
+ config.color_enabled = true
9
+
10
+ # Use color not only in STDOUT but also in pagers and files
11
+ config.tty = true
12
+
13
+ # Use the specified formatter
14
+ config.formatter = :documentation # :progress, :html, :textmate
15
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radiodan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,72 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-03 00:00:00.000000000 Z
12
+ date: 2013-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 10.1.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 10.1.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.13.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.13.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: guard-rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.6.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.6.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: terminal-notifier-guard
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 1.5.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.5.0
14
78
  - !ruby/object:Gem::Dependency
15
79
  name: eventmachine
16
80
  requirement: !ruby/object:Gem::Requirement
@@ -91,6 +155,22 @@ dependencies:
91
155
  - - ~>
92
156
  - !ruby/object:Gem::Version
93
157
  version: 3.0.0
158
+ - !ruby/object:Gem::Dependency
159
+ name: i18n
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ version: 0.6.4
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: 0.6.4
94
174
  description: Web-enabled radio that plays to my schedule.
95
175
  email:
96
176
  - pixelblend@gmail.com
@@ -101,23 +181,39 @@ files:
101
181
  - .gitignore
102
182
  - Gemfile
103
183
  - Gemfile.lock
184
+ - Guardfile
104
185
  - LICENSE.txt
105
186
  - README.md
106
187
  - Rakefile
107
188
  - TODO
108
- - lib/em_additions.rb
189
+ - doc/state.markdown
109
190
  - lib/radiodan.rb
191
+ - lib/radiodan/adapter/mpd.rb
192
+ - lib/radiodan/adapter/mpd/ack.rb
193
+ - lib/radiodan/adapter/mpd/connection.rb
194
+ - lib/radiodan/adapter/mpd/playlist_parser.rb
195
+ - lib/radiodan/adapter/mpd/response.rb
110
196
  - lib/radiodan/builder.rb
111
- - lib/radiodan/content.rb
197
+ - lib/radiodan/em_additions.rb
112
198
  - lib/radiodan/event_binding.rb
113
199
  - lib/radiodan/logging.rb
114
- - lib/radiodan/middleware/mpd.rb
115
200
  - lib/radiodan/middleware/panic.rb
116
201
  - lib/radiodan/middleware/touch_file.rb
117
202
  - lib/radiodan/player.rb
118
- - lib/radiodan/state.rb
203
+ - lib/radiodan/playlist.rb
204
+ - lib/radiodan/playlist_sync.rb
205
+ - lib/radiodan/track.rb
119
206
  - lib/radiodan/version.rb
120
207
  - radiodan.gemspec
208
+ - spec/lib/builder_spec.rb
209
+ - spec/lib/event_binding_spec.rb
210
+ - spec/lib/logging_spec.rb
211
+ - spec/lib/player_spec.rb
212
+ - spec/lib/playlist_parser_spec.rb
213
+ - spec/lib/playlist_spec.rb
214
+ - spec/lib/playlist_sync_spec.rb
215
+ - spec/lib/track_spec.rb
216
+ - spec/spec_helper.rb
121
217
  homepage: https://github.com/pixelblend/radiodan
122
218
  licenses: []
123
219
  post_install_message:
@@ -130,17 +226,31 @@ required_ruby_version: !ruby/object:Gem::Requirement
130
226
  - - ! '>='
131
227
  - !ruby/object:Gem::Version
132
228
  version: '0'
229
+ segments:
230
+ - 0
231
+ hash: 1572483849052610918
133
232
  required_rubygems_version: !ruby/object:Gem::Requirement
134
233
  none: false
135
234
  requirements:
136
235
  - - ! '>='
137
236
  - !ruby/object:Gem::Version
138
237
  version: '0'
238
+ segments:
239
+ - 0
240
+ hash: 1572483849052610918
139
241
  requirements: []
140
242
  rubyforge_project:
141
243
  rubygems_version: 1.8.23
142
244
  signing_key:
143
245
  specification_version: 3
144
246
  summary: Web-enabled radio that plays to my schedule.
145
- test_files: []
146
- has_rdoc:
247
+ test_files:
248
+ - spec/lib/builder_spec.rb
249
+ - spec/lib/event_binding_spec.rb
250
+ - spec/lib/logging_spec.rb
251
+ - spec/lib/player_spec.rb
252
+ - spec/lib/playlist_parser_spec.rb
253
+ - spec/lib/playlist_spec.rb
254
+ - spec/lib/playlist_sync_spec.rb
255
+ - spec/lib/track_spec.rb
256
+ - spec/spec_helper.rb