network_executive 0.0.1.alpha.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +15 -1
  3. data/README.md +9 -41
  4. data/Rakefile +38 -1
  5. data/app/assets/javascripts/application.js +13 -0
  6. data/app/assets/javascripts/network_executive/osd.js +46 -0
  7. data/app/assets/javascripts/network_executive/set_top_box.js +44 -0
  8. data/app/assets/stylesheets/network_executive/application.css +16 -0
  9. data/app/assets/stylesheets/network_executive/gui_components.css +17 -0
  10. data/app/assets/stylesheets/network_executive/normalize.css +500 -0
  11. data/app/assets/stylesheets/network_executive/osd.css +33 -0
  12. data/app/assets/stylesheets/network_executive/smpte.css +164 -0
  13. data/app/controllers/network_executive/application_controller.rb +4 -0
  14. data/app/controllers/network_executive/network_controller.rb +9 -0
  15. data/app/helpers/network_executive/network_helper.rb +7 -0
  16. data/app/models/network_executive/channel.rb +46 -0
  17. data/app/models/network_executive/channel_schedule.rb +13 -0
  18. data/app/models/network_executive/lineup.rb +66 -0
  19. data/app/models/network_executive/lineup_range.rb +34 -0
  20. data/app/models/network_executive/network.rb +10 -0
  21. data/app/models/network_executive/program.rb +39 -0
  22. data/app/models/network_executive/program_schedule.rb +148 -0
  23. data/app/models/network_executive/viewer.rb +76 -0
  24. data/app/views/network_executive/network/index.html.erb +39 -0
  25. data/config/routes.rb +7 -0
  26. data/lib/generators/network_executive/install_generator.rb +96 -0
  27. data/lib/generators/network_executive/templates/initializer.erb +5 -0
  28. data/lib/generators/network_executive/uninstall_generator.rb +20 -0
  29. data/lib/network_executive/configuration.rb +26 -0
  30. data/lib/network_executive/engine.rb +28 -0
  31. data/lib/network_executive/producer.rb +36 -0
  32. data/lib/network_executive/scheduling.rb +44 -0
  33. data/lib/network_executive/station/local_affiliate.rb +21 -0
  34. data/lib/network_executive/station.rb +11 -0
  35. data/lib/network_executive/version.rb +1 -1
  36. data/lib/network_executive.rb +18 -3
  37. data/network_executive.gemspec +9 -8
  38. data/spec/dummy/README.rdoc +261 -0
  39. data/spec/dummy/Rakefile +7 -0
  40. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  41. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  42. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  43. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  44. data/{lib/network_executive/templates/config/lineup.rb → spec/dummy/app/mailers/.gitkeep} +0 -0
  45. data/spec/dummy/app/models/.gitkeep +0 -0
  46. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  47. data/spec/dummy/config/application.rb +47 -0
  48. data/spec/dummy/config/boot.rb +10 -0
  49. data/spec/dummy/config/database.yml +25 -0
  50. data/spec/dummy/config/environment.rb +5 -0
  51. data/spec/dummy/config/environments/development.rb +37 -0
  52. data/spec/dummy/config/environments/production.rb +67 -0
  53. data/spec/dummy/config/environments/test.rb +37 -0
  54. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  55. data/spec/dummy/config/initializers/inflections.rb +15 -0
  56. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  57. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  58. data/spec/dummy/config/initializers/session_store.rb +8 -0
  59. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  60. data/spec/dummy/config/locales/en.yml +5 -0
  61. data/spec/dummy/config/routes.rb +3 -0
  62. data/spec/dummy/config.ru +4 -0
  63. data/spec/dummy/lib/assets/.gitkeep +0 -0
  64. data/spec/dummy/log/.gitkeep +0 -0
  65. data/spec/dummy/public/404.html +26 -0
  66. data/spec/dummy/public/422.html +26 -0
  67. data/spec/dummy/public/500.html +25 -0
  68. data/spec/dummy/public/favicon.ico +0 -0
  69. data/spec/dummy/script/rails +6 -0
  70. data/spec/generators/install_generator_spec.rb +129 -0
  71. data/spec/generators/uninstall_generator_spec.rb +39 -0
  72. data/spec/helpers/network_helper_spec.rb +7 -0
  73. data/spec/models/channel_schedule_spec.rb +29 -0
  74. data/spec/models/channel_spec.rb +55 -0
  75. data/spec/models/lineup_range_spec.rb +65 -0
  76. data/spec/models/lineup_spec.rb +95 -0
  77. data/spec/models/network_spec.rb +11 -0
  78. data/spec/models/program_schedule_spec.rb +399 -0
  79. data/spec/models/program_spec.rb +37 -0
  80. data/spec/models/viewer_spec.rb +210 -0
  81. data/spec/network_executive_spec.rb +15 -0
  82. data/spec/spec_helper.rb +27 -1
  83. data/spec/unit/configuration_spec.rb +3 -0
  84. data/spec/unit/producer_spec.rb +60 -0
  85. data/spec/unit/scheduling_spec.rb +106 -0
  86. data/spec/unit/station/local_affiliate_spec.rb +41 -0
  87. data/tasks/network_executive_tasks.rake +4 -0
  88. metadata +177 -40
  89. data/lib/network_executive/behaviors/file_system.rb +0 -73
  90. data/lib/network_executive/behaviors/terminal_output.rb +0 -84
  91. data/lib/network_executive/cli.rb +0 -29
  92. data/lib/network_executive/commands/application.rb +0 -64
  93. data/lib/network_executive/commands/server.rb +0 -48
  94. data/lib/network_executive/network.rb +0 -5
  95. data/lib/network_executive/templates/app/channels/.gitkeep +0 -1
  96. data/lib/network_executive/templates/config/my_network.rb +0 -5
  97. data/lib/network_executive/templates/my_network.ru +0 -4
  98. data/lib/network_executive/templates/public/.gitkeep +0 -1
  99. data/spec/commands/application_spec.rb +0 -58
  100. data/spec/commands/server_spec.rb +0 -15
@@ -0,0 +1,95 @@
1
+ describe NetworkExecutive::Lineup do
2
+
3
+ let(:show) do
4
+ show = double('show', program_name:'show 1')
5
+ end
6
+
7
+ let(:channel) do
8
+ channel = double('channel', display_name:'channel a').as_null_object
9
+
10
+ channel.stub(:whats_on?).and_yield( show ).and_return [ show ]
11
+
12
+ channel
13
+ end
14
+
15
+ let(:channels) do
16
+ [
17
+ channel
18
+ ]
19
+ end
20
+
21
+ before do
22
+ Timecop.freeze Time.now.change hour:12, min:0, sec:0
23
+
24
+ NetworkExecutive::Network.stub( :channels ).and_return channels
25
+ end
26
+
27
+ describe '#start_time' do
28
+ context 'the default value' do
29
+ subject { described_class.new.start_time }
30
+
31
+ it 'should default to now' do
32
+ subject.should eq Time.now
33
+ end
34
+ end
35
+
36
+ context 'an explicit value' do
37
+ let(:start) { Time.now.change hour:11, min:47, sec:54 }
38
+
39
+ subject { described_class.new( start ).start_time }
40
+
41
+ it 'should be rounded' do
42
+ subject.should eq Time.now.change hour:11, min:45, sec:0
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '#stop_time' do
48
+ context 'the default value' do
49
+ subject { described_class.new.stop_time }
50
+
51
+ it 'should default to 1.5hours from now' do
52
+ subject.should eq 1.5.hours.from_now
53
+ end
54
+ end
55
+
56
+ context 'an explicit value' do
57
+ let(:stop) { Time.now.change hour:13, min:47, sec:54 }
58
+
59
+ subject { described_class.new( nil, stop ).stop_time }
60
+
61
+ it 'should be rounded' do
62
+ subject.should eq Time.now.change hour:13, min:45, sec:0
63
+ end
64
+ end
65
+ end
66
+
67
+ describe '#channels' do
68
+ subject { described_class.new[:channels] }
69
+
70
+ it { should be_an Array }
71
+
72
+ it 'should contain a channel name' do
73
+ subject.first[:name].should == 'channel a'
74
+ end
75
+
76
+ it 'should contain an array of scheduled programs' do
77
+ subject.first[:schedule].should be_an Array
78
+ end
79
+
80
+ it 'should transform the program name' do
81
+ show.should_receive :program_name
82
+
83
+ subject
84
+ end
85
+
86
+ it 'should ask the channel what is on' do
87
+ args = [ Time.now, 1.5.hours.from_now, kind_of(Hash) ]
88
+
89
+ channels.first.should_receive(:whats_on?).with( *args )
90
+
91
+ subject
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,11 @@
1
+ describe NetworkExecutive::Network do
2
+
3
+ it 'should maintain a collection of channels' do
4
+ described_class.channels.should be_a Array
5
+ end
6
+
7
+ it 'should maintain a collection of programs' do
8
+ described_class.programming.should be_a Array
9
+ end
10
+
11
+ end
@@ -0,0 +1,399 @@
1
+ describe NetworkExecutive::ProgramSchedule do
2
+
3
+ describe 'without a program name' do
4
+ it 'should raise a ProgramNameError' do
5
+ expect{ described_class.new(:day) }.to raise_error NetworkExecutive::ProgramNameError
6
+ end
7
+ end
8
+
9
+ describe 'a 24-7 program' do
10
+ subject { described_class.new(:day, play:'my_show') }
11
+
12
+ its(:commercials?) { should be_true }
13
+
14
+ it 'should run at the beginning of the day' do
15
+ Timecop.freeze Time.now.beginning_of_day
16
+
17
+ subject.should include Time.now
18
+ end
19
+
20
+ it 'should run at the middle of the day' do
21
+ Timecop.freeze Time.now.change hours:12
22
+
23
+ subject.should include Time.now
24
+ end
25
+
26
+ it 'should run at the end of the day' do
27
+ Timecop.freeze Time.now.end_of_day
28
+
29
+ subject.should include Time.now
30
+ end
31
+ end
32
+
33
+ describe 'a weekly, 24-hour program' do
34
+ subject { described_class.new(:thursday, play:'my_show') }
35
+
36
+ it 'should run at the beginning of Thursday' do
37
+ Timecop.freeze Time.now.beginning_of_week + 3.days
38
+
39
+ subject.should include Time.now
40
+ end
41
+
42
+ it 'should run at the middle of Thursday' do
43
+ Timecop.freeze( (Time.now.beginning_of_week + 3.days).change hour:12 )
44
+
45
+ subject.should include Time.now
46
+ end
47
+
48
+ it 'should run at the end of Thursday' do
49
+ Timecop.freeze Time.now.end_of_week - 3.days
50
+
51
+ subject.should include Time.now
52
+ end
53
+
54
+ it 'should not run on Monday' do
55
+ Timecop.freeze Time.now.beginning_of_week
56
+
57
+ subject.should_not include Time.now
58
+ end
59
+ end
60
+
61
+ describe 'a show between 11am and 1pm' do
62
+ describe 'continuously' do
63
+ subject { described_class.new(:day, play:'my_show', between:'11am and 1pm') }
64
+
65
+ it 'should run at 11am' do
66
+ Timecop.freeze Time.now.change hour:11, min:0, sec:0
67
+
68
+ subject.should include Time.now
69
+ end
70
+
71
+ it 'should run at 12pm' do
72
+ Timecop.freeze Time.now.change hour:12
73
+
74
+ subject.should include Time.now
75
+ end
76
+
77
+ it 'should run at 12:59:59pm' do
78
+ Timecop.freeze Time.now.change hour:12, min:59, sec:59
79
+
80
+ subject.should include Time.now
81
+ end
82
+
83
+ it 'should not run at 1pm' do
84
+ Timecop.freeze Time.now.change hour:13
85
+
86
+ subject.should_not include Time.now
87
+ end
88
+
89
+ it 'should not run before 11am' do
90
+ Timecop.freeze Time.now.change hour:10, min:59, sec:59
91
+
92
+ subject.should_not include Time.now
93
+ end
94
+
95
+ it 'should not run after 1pm' do
96
+ Timecop.freeze Time.now.change hour:13, min:0, sec:1
97
+
98
+ subject.should_not include Time.now
99
+ end
100
+ end
101
+
102
+ describe 'for the first 20mins of each hour' do
103
+ subject { described_class.new(:day, play:'my_show', between:'11am and 1pm', for_the_first: '20mins', of:'each hour') }
104
+
105
+ it 'should run at 11am' do
106
+ Timecop.freeze Time.now.change hour:11, min:0, sec:0
107
+
108
+ subject.should include Time.now
109
+ end
110
+
111
+ it 'should run at 11:19:59am' do
112
+ Timecop.freeze Time.now.change hour:11, min:19, sec:59
113
+
114
+ subject.should include Time.now
115
+ end
116
+
117
+ it 'should not run at 11:20pm' do
118
+ Timecop.freeze Time.now.change hour:11, min:20, sec:0
119
+
120
+ subject.should_not include Time.now
121
+ end
122
+
123
+ it 'should run at 12pm' do
124
+ Timecop.freeze Time.now.change hour:12, min:0, sec:0
125
+
126
+ subject.should include Time.now
127
+ end
128
+
129
+ it 'should run at 12:19:59am' do
130
+ Timecop.freeze Time.now.change hour:12, min:19, sec:59
131
+
132
+ subject.should include Time.now
133
+ end
134
+
135
+ it 'should not run at 12:20pm' do
136
+ Timecop.freeze Time.now.change hour:12, min:20, sec:0
137
+
138
+ subject.should_not include Time.now
139
+ end
140
+ end
141
+
142
+ describe 'the last 20mins of each hour' do
143
+ subject { described_class.new(:day, play:'my_show', between:'11am and 1pm', for_the_last: '20mins', of:'each hour') }
144
+
145
+ it 'should not run at 11am' do
146
+ Timecop.freeze Time.now.change hour:11, min:0, sec:0
147
+
148
+ subject.should_not include Time.now
149
+ end
150
+
151
+ it 'should run at 11:40am' do
152
+ Timecop.freeze Time.now.change hour:11, min:40, sec:0
153
+
154
+ subject.should include Time.now
155
+ end
156
+
157
+ it 'should run at 11:59:59am' do
158
+ Timecop.freeze Time.now.change hour:11, min:59, sec:59
159
+
160
+ subject.should include Time.now
161
+ end
162
+
163
+ it 'should not run at 12pm' do
164
+ Timecop.freeze Time.now.change hour:12, min:0, sec:0
165
+
166
+ subject.should_not include Time.now
167
+ end
168
+
169
+ it 'should run at 12:40pm' do
170
+ Timecop.freeze Time.now.change hour:12, min:40, sec:0
171
+
172
+ subject.should include Time.now
173
+ end
174
+
175
+ it 'should not run at 12:59:59pm' do
176
+ Timecop.freeze Time.now.change hour:12, min:59, sec:59
177
+
178
+ subject.should include Time.now
179
+ end
180
+
181
+ it 'should not run at 1pm' do
182
+ Timecop.freeze Time.now.change hour:13, min:0, sec:0
183
+
184
+ subject.should_not include Time.now
185
+ end
186
+ end
187
+ end
188
+
189
+ describe 'a show that runs for' do
190
+ describe 'the first' do
191
+ describe '15mins' do
192
+ describe 'of each hour' do
193
+ describe 'continuously' do
194
+ subject { described_class.new(:day, play:'my_show', for_the_first:'15mins', of:'each hour') }
195
+
196
+ it 'should not run at 12:59:59am' do
197
+ Timecop.freeze Time.now.change hour:12, min:59, sec:59
198
+
199
+ subject.should_not include Time.now
200
+ end
201
+
202
+ it 'should run at 1:00am' do
203
+ Timecop.freeze Time.now.change hour:1, min:0, sec:0
204
+
205
+ subject.should include Time.now
206
+ end
207
+
208
+ it 'should run at 1:14:59am' do
209
+ Timecop.freeze Time.now.change hour:1, min:14, sec:59
210
+
211
+ subject.should include Time.now
212
+ end
213
+
214
+ it 'should not run at 1:15am' do
215
+ Timecop.freeze Time.now.change hour:1, min:15, sec:0
216
+
217
+ subject.should_not include Time.now
218
+ end
219
+ end
220
+
221
+ describe 'starting at 2pm' do
222
+ subject { described_class.new(:day, play:'my_show', for_the_first:'15mins', of:'each hour', starting_at:'2pm') }
223
+
224
+ it 'should not run at 1pm' do
225
+ Timecop.freeze Time.now.change hour:13, min:0, sec:0
226
+
227
+ subject.should_not include Time.now
228
+ end
229
+
230
+ it 'should run at 2pm' do
231
+ Timecop.freeze Time.now.change hour:14, min:0, sec:0
232
+
233
+ subject.should include Time.now
234
+ end
235
+
236
+ it 'should run at 2:14:59pm' do
237
+ Timecop.freeze Time.now.change hour:14, min:14, sec:59
238
+
239
+ subject.should include Time.now
240
+ end
241
+
242
+ it 'should not run at 2:15pm' do
243
+ Timecop.freeze Time.now.change hour:14, min:15, sec:0
244
+
245
+ subject.should_not include Time.now
246
+ end
247
+
248
+ it 'should not run at 10:59:59pm' do
249
+ Timecop.freeze Time.now.change hour:22, min:59, sec:59
250
+
251
+ subject.should_not include Time.now
252
+ end
253
+
254
+ it 'should run at 11pm' do
255
+ Timecop.freeze Time.now.change hour:23, min:0, sec:0
256
+
257
+ subject.should include Time.now
258
+ end
259
+
260
+ it 'should not run at 11:15pm' do
261
+ Timecop.freeze Time.now.change hour:23, min:15, sec:0
262
+
263
+ subject.should_not include Time.now
264
+ end
265
+ end
266
+
267
+ describe 'ending at 2pm' do
268
+ subject { described_class.new(:day, play:'my_show', for_the_first:'15mins', of:'each hour', ending_at:'2pm') }
269
+
270
+ it 'should run at 12am' do
271
+ Timecop.freeze Time.now.change hour:0, min:0, sec:0
272
+
273
+ subject.should include Time.now
274
+ end
275
+
276
+ it 'should run at 12:14:59am' do
277
+ Timecop.freeze Time.now.change hour:0, min:14, sec:59
278
+
279
+ subject.should include Time.now
280
+ end
281
+
282
+ it 'should not run at 12:15am' do
283
+ Timecop.freeze Time.now.change hour:0, min:15, sec:0
284
+
285
+ subject.should_not include Time.now
286
+ end
287
+
288
+ it 'should run at 1am' do
289
+ Timecop.freeze Time.now.change hour:1, min:0, sec:0
290
+
291
+ subject.should include Time.now
292
+ end
293
+
294
+ it 'should not run at 2pm' do
295
+ Timecop.freeze Time.now.change hour:14, min:0, sec:0
296
+
297
+ subject.should_not include Time.now
298
+ end
299
+ end
300
+ end
301
+
302
+ describe 'of every hour' do
303
+ subject { described_class.new(:day, play:'my_show', for_the_first:'15mins', of:'every hour') }
304
+
305
+ it 'should not run at 12:59:59am' do
306
+ Timecop.freeze Time.now.change hour:12, min:59, sec:59
307
+
308
+ subject.should_not include Time.now
309
+ end
310
+
311
+ it 'should run at 1:00am' do
312
+ Timecop.freeze Time.now.change hour:1, min:0, sec:0
313
+
314
+ subject.should include Time.now
315
+ end
316
+
317
+ it 'should run at 1:14:59am' do
318
+ Timecop.freeze Time.now.change hour:1, min:14, sec:59
319
+
320
+ subject.should include Time.now
321
+ end
322
+
323
+ it 'should not run at 1:15am' do
324
+ Timecop.freeze Time.now.change hour:1, min:15, sec:0
325
+
326
+ subject.should_not include Time.now
327
+ end
328
+ end
329
+ end
330
+ end
331
+
332
+ describe 'the last' do
333
+ describe '15mins' do
334
+ describe 'of each hour' do
335
+ subject { described_class.new(:day, play:'my_show', for_the_last:'15mins', of:'each hour') }
336
+
337
+ it 'should not run at 1:44:59am' do
338
+ Timecop.freeze Time.now.change hour:1, min:44, sec:59
339
+
340
+ subject.should_not include Time.now
341
+ end
342
+
343
+ it 'should run at 1:45am' do
344
+ Timecop.freeze Time.now.change hour:1, min:45, sec:0
345
+
346
+ subject.should include Time.now
347
+ end
348
+
349
+ it 'should run at 1:59:59am' do
350
+ Timecop.freeze Time.now.change hour:1, min:59, sec:59
351
+
352
+ subject.should include Time.now
353
+ end
354
+
355
+ it 'should not run at 2am' do
356
+ Timecop.freeze Time.now.change hour:2, min:0, sec:0
357
+
358
+ subject.should_not include Time.now
359
+ end
360
+ end
361
+
362
+ describe 'of every hour' do
363
+ subject { described_class.new(:day, play:'my_show', for_the_last:'15mins', of:'every hour') }
364
+
365
+ it 'should not run at 1:44:59am' do
366
+ Timecop.freeze Time.now.change hour:1, min:44, sec:59
367
+
368
+ subject.should_not include Time.now
369
+ end
370
+
371
+ it 'should run at 1:45am' do
372
+ Timecop.freeze Time.now.change hour:1, min:45, sec:0
373
+
374
+ subject.should include Time.now
375
+ end
376
+
377
+ it 'should run at 1:59:59am' do
378
+ Timecop.freeze Time.now.change hour:1, min:59, sec:59
379
+
380
+ subject.should include Time.now
381
+ end
382
+
383
+ it 'should not run at 2am' do
384
+ Timecop.freeze Time.now.change hour:2, min:0, sec:0
385
+
386
+ subject.should_not include Time.now
387
+ end
388
+ end
389
+ end
390
+ end
391
+ end
392
+
393
+ describe 'a commercial-free show' do
394
+ subject { described_class.new(:day, play:'my_show', commercial_free:true) }
395
+
396
+ its(:commercials?) { should be_false }
397
+ end
398
+
399
+ end
@@ -0,0 +1,37 @@
1
+ describe NetworkExecutive::Program do
2
+
3
+ let(:klass) do
4
+ Class.new described_class
5
+ end
6
+
7
+ before do
8
+ stub_const 'MyProgram', klass
9
+ end
10
+
11
+ subject { MyProgram.new }
12
+
13
+ its(:name) { should == 'my_program' }
14
+ its(:url) { should == '' }
15
+ its(:play) { should == %q[{"name":"my_program","url":""}] }
16
+
17
+ describe '#as_json' do
18
+ subject { MyProgram.new.as_json }
19
+
20
+ it { should include( name:'my_program' ) }
21
+ it { should include( url: '' ) }
22
+ end
23
+
24
+ describe '.find_by_name' do
25
+ it 'should find a program by name' do
26
+ NetworkExecutive::Network.programming.should_receive( :find )
27
+
28
+ described_class.find_by_name 'foo'
29
+ end
30
+ end
31
+
32
+ describe '.inherited' do
33
+ it 'should register the program with the Network' do
34
+ NetworkExecutive::Network.programming.first.should be_a described_class
35
+ end
36
+ end
37
+ end