rvideo 0.8.0

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.
Files changed (45) hide show
  1. data/ENV +100 -0
  2. data/ENV2 +129 -0
  3. data/History.txt +3 -0
  4. data/License.txt +20 -0
  5. data/Manifest.txt +44 -0
  6. data/README.txt +91 -0
  7. data/RULES +11 -0
  8. data/Rakefile +163 -0
  9. data/config/boot.rb +16 -0
  10. data/lib/rvideo.rb +19 -0
  11. data/lib/rvideo/errors.rb +21 -0
  12. data/lib/rvideo/inspector.rb +486 -0
  13. data/lib/rvideo/reporter.rb +176 -0
  14. data/lib/rvideo/reporter/views/index.html.erb +27 -0
  15. data/lib/rvideo/reporter/views/report.css +27 -0
  16. data/lib/rvideo/reporter/views/report.html.erb +81 -0
  17. data/lib/rvideo/reporter/views/report.js +9 -0
  18. data/lib/rvideo/tools/abstract_tool.rb +79 -0
  19. data/lib/rvideo/tools/ffmpeg.rb +111 -0
  20. data/lib/rvideo/tools/flvtool2.rb +45 -0
  21. data/lib/rvideo/transcoder.rb +113 -0
  22. data/lib/rvideo/version.rb +9 -0
  23. data/scripts/txt2html +67 -0
  24. data/setup.rb +1585 -0
  25. data/spec/files/kites.mp4 +0 -0
  26. data/spec/fixtures/ffmpeg_builds.yml +28 -0
  27. data/spec/fixtures/files.yml +374 -0
  28. data/spec/fixtures/recipes.yml +6 -0
  29. data/spec/integrations/files/files.yml +361 -0
  30. data/spec/integrations/formats_spec.rb +287 -0
  31. data/spec/integrations/inspection_spec.rb +15 -0
  32. data/spec/integrations/recipes_spec.rb +0 -0
  33. data/spec/integrations/rvideo_spec.rb +17 -0
  34. data/spec/integrations/transcoding_spec.rb +9 -0
  35. data/spec/spec.opts +1 -0
  36. data/spec/spec_helper.rb +11 -0
  37. data/spec/units/abstract_tool_spec.rb +112 -0
  38. data/spec/units/ffmpeg_spec.rb +703 -0
  39. data/spec/units/flvtool2_spec.rb +314 -0
  40. data/spec/units/inspector_spec.rb +41 -0
  41. data/spec/units/transcoder_spec.rb +140 -0
  42. data/website/index.html +219 -0
  43. data/website/index.txt +142 -0
  44. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  45. metadata +94 -0
@@ -0,0 +1,314 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ module RVideo
4
+ module Tools
5
+
6
+ describe Flvtool2 do
7
+ before do
8
+ setup_flvtool2_spec
9
+ end
10
+
11
+ it "should initialize with valid arguments" do
12
+ @flvtool2.class.should == Flvtool2
13
+ end
14
+
15
+ it "should have the correct tool_command" do
16
+ @flvtool2.tool_command.should == 'flvtool2'
17
+ end
18
+
19
+ it "should call parse_result on execute, with a result string" do
20
+ @flvtool2.should_receive(:parse_result).once.with /\AERROR: No such file or directory/
21
+ @flvtool2.execute
22
+ end
23
+
24
+ it "should mixin AbstractTool" do
25
+ Flvtool2.included_modules.include?(AbstractTool::InstanceMethods).should be_true
26
+ end
27
+
28
+ it "should set supported options successfully" do
29
+ @flvtool2.options[:temp_file].should == @options[:temp_file]
30
+ @flvtool2.options[:output_file].should == @options[:output_file]
31
+ end
32
+
33
+ end
34
+
35
+ describe Flvtool2, " when parsing a result" do
36
+ before do
37
+ setup_flvtool2_spec
38
+ end
39
+
40
+ it "should set metadata if called with -P option" do
41
+ @flvtool2.send(:parse_result, @metadata_result).should be_true
42
+ @flvtool2.raw_metadata.should == @metadata_result
43
+ end
44
+
45
+ it "should succeed but not set metadata without -P option" do
46
+ @flvtool2.send(:parse_result,"").should be_true
47
+ end
48
+ end
49
+
50
+ context Flvtool2, " result parsing should raise an exception" do
51
+
52
+ setup do
53
+ setup_flvtool2_spec
54
+ end
55
+
56
+ specify "when not passed a command" do
57
+ lambda {
58
+ @flvtool2.send(:parse_result, @helptext)
59
+ }.should raise_error(TranscoderError::InvalidCommand, /flvtool2 help text/)
60
+ end
61
+
62
+ specify "when passed an invalid input file" do
63
+ lambda {
64
+ @flvtool2.send(:parse_result, @non_flv_input)
65
+ }.should raise_error(TranscoderError::InvalidFile, "input must be a valid FLV file")
66
+ end
67
+
68
+ specify "when input file not found" do
69
+ lambda {
70
+ @flvtool2.send(:parse_result, @no_input_file)
71
+ }.should raise_error(TranscoderError::InputFileNotFound, /^ERROR: No such file or directory/)
72
+ end
73
+
74
+ specify "when receiving unexpected results" do
75
+ lambda {
76
+ @flvtool2.send(:parse_result, @unexpected_results)
77
+ }.should raise_error(TranscoderError::UnexpectedResult, /ffmpeg/i)
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ def setup_flvtool2_spec
84
+ @options = {:temp_file => "foo", :output_file => "bar"}
85
+ @command = "flvtool2 -U $temp_file$ $output_file$"
86
+ @flvtool2 = RVideo::Tools::Flvtool2.new(@command, @options)
87
+
88
+ @helptext = "FLVTool2 1.0.6
89
+ Copyright (c) 2005-2007 Norman Timmler (inlet media e.K., Hamburg, Germany)
90
+ Get the latest version from http://www.inlet-media.de/flvtool2
91
+ This program is published under the BSD license.
92
+
93
+ Usage: flvtool2 [-ACDPUVaciklnoprstvx]... [-key:value]... in-path|stdin [out-path|stdout]
94
+
95
+ If out-path is omitted, in-path will be overwritten.
96
+ In-path can be a single file, or a directory. If in-path is a directory,
97
+ out-path has to be likewise, or can be omitted. Directory recursion
98
+ is controlled by the -r switch. You can use stdin and stdout keywords
99
+ as in- and out-path for piping or redirecting.
100
+
101
+ Chain commands like that: -UP (updates FLV file than prints out meta data)
102
+
103
+ Commands:
104
+ -A Adds tags from -t tags-file
105
+ -C Cuts file using -i inpoint and -o outpoint
106
+ -D Debugs file (writes a lot to stdout)
107
+ -H Helpscreen will be shown
108
+ -P Prints out meta data to stdout
109
+ -U Updates FLV with an onMetaTag event
110
+
111
+ Switches:
112
+ -a Collapse space between cutted regions
113
+ -c Compatibility mode calculates some onMetaTag values different
114
+ -key:value Key-value-pair for onMetaData tag (overwrites generated values)
115
+ -i timestamp Inpoint for cut command in miliseconds
116
+ -k Keyframe mode slides onCuePoint(navigation) tags added by the
117
+ add command to nearest keyframe position
118
+ -l Logs FLV stream reading to stream.log in current directory
119
+ -n Number of tag to debug
120
+ -o timestamp Outpoint for cut command in miliseconds
121
+ -p Preserve mode only updates FLVs that have not been processed
122
+ before
123
+ -r Recursion for directory processing
124
+ -s Simulation mode never writes FLV data to out-path
125
+ -t path Tagfile (MetaTags written in XML)
126
+ -v Verbose mode
127
+ -x XML mode instead of YAML mode
128
+
129
+ REPORT BUGS at http://projects.inlet-media.de/flvtool2
130
+ Powered by Riva VX, http://rivavx.com"
131
+
132
+ @non_flv_input = "ERROR: IO is not a FLV stream. Wrong signature.
133
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flv/stream.rb:393:in `read_header'
134
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flv/stream.rb:57:in `initialize'
135
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:272:in `new'
136
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:272:in `open_stream'
137
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:238:in `process_files'
138
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:225:in `each'
139
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:225:in `process_files'
140
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:44:in `execute!'
141
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2.rb:168:in `execute!'
142
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2.rb:228
143
+ ERROR: /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
144
+ ERROR: /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:27:in `require'
145
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/bin/flvtool2:2
146
+ ERROR: /opt/local/bin/flvtool2:18:in `load'
147
+ ERROR: /opt/local/bin/flvtool2:18"
148
+
149
+ @no_input_file = "ERROR: No such file or directory - /Users/jon/code/spinoza/rvideo/foobar
150
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:259:in `initialize'
151
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:259:in `open'
152
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:259:in `open_stream'
153
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:238:in `process_files'
154
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:225:in `each'
155
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:225:in `process_files'
156
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2/base.rb:44:in `execute!'
157
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2.rb:168:in `execute!'
158
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/lib/flvtool2.rb:228
159
+ ERROR: /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
160
+ ERROR: /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:27:in `require'
161
+ ERROR: /opt/local/lib/ruby/gems/1.8/gems/flvtool2-1.0.6/bin/flvtool2:2
162
+ ERROR: /opt/local/bin/flvtool2:18:in `load'
163
+ ERROR: /opt/local/bin/flvtool2:18"
164
+
165
+ @unexpected_results = "FFmpeg version CVS, Copyright (c) 2000-2004 Fabrice Bellard
166
+ Mac OSX universal build for ffmpegX
167
+ configuration: --enable-memalign-hack --enable-mp3lame --enable-gpl --disable-vhook --disable-ffplay --disable-ffserver --enable-a52 --enable-xvid --enable-faac --enable-faad --enable-amr_nb --enable-amr_wb --enable-pthreads --enable-x264
168
+ libavutil version: 49.0.0
169
+ libavcodec version: 51.9.0
170
+ libavformat version: 50.4.0
171
+ built on Apr 15 2006 04:58:19, gcc: 4.0.1 (Apple Computer, Inc. build 5250)
172
+
173
+ Seems that stream 1 comes from film source: 600.00 (600/1) -> 59.75 (239/4)
174
+ Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'jobjob2.mov':
175
+ Duration: 00:01:09.0, start: 0.000000, bitrate: 28847 kb/s
176
+ Stream #0.0(eng): Audio: aac, 44100 Hz, stereo
177
+ Stream #0.1(eng), 59.75 fps(r): Video: dvvideo, yuv411p, 720x480
178
+ Stream mapping:
179
+ Stream #0.1 -> #0.0
180
+ Stream #0.0 -> #0.1
181
+ Press [q] to stop encoding"
182
+
183
+ @metadata_result = "---
184
+ /Users/jon/code/spinoza/rvideo/temp.flv:
185
+ hasKeyframes: true
186
+ cuePoints:
187
+ audiodatarate: 64.8512825785226
188
+ hasVideo: true
189
+ stereo: false
190
+ canSeekToEnd: false
191
+ framerate: 30
192
+ audiosamplerate: 44000
193
+ videocodecid: 2
194
+ datasize: 992710
195
+ lasttimestamp: 19.453
196
+ audiosamplesize: 16
197
+ audiosize: 165955
198
+ hasAudio: true
199
+ audiodelay: 0
200
+ videosize: 825165
201
+ metadatadate: Fri Sep 14 13:25:58 GMT-0500 2007
202
+ metadatacreator: inlet media FLVTool2 v1.0.6 - http://www.inlet-media.de/flvtool2
203
+ lastkeyframetimestamp: 19.219
204
+ height: 240
205
+ filesize: 998071
206
+ hasMetadata: true
207
+ keyframes:
208
+ times:
209
+ - 0
210
+ - 0.4
211
+ - 0.801
212
+ - 1.201
213
+ - 1.602
214
+ - 2.002
215
+ - 2.402
216
+ - 2.803
217
+ - 3.203
218
+ - 3.604
219
+ - 4.004
220
+ - 4.404
221
+ - 4.805
222
+ - 5.205
223
+ - 5.606
224
+ - 6.006
225
+ - 6.406
226
+ - 6.807
227
+ - 7.207
228
+ - 7.608
229
+ - 8.008
230
+ - 8.408
231
+ - 8.809
232
+ - 9.209
233
+ - 9.61
234
+ - 10.01
235
+ - 10.41
236
+ - 10.811
237
+ - 11.211
238
+ - 11.612
239
+ - 12.012
240
+ - 12.412
241
+ - 12.813
242
+ - 13.213
243
+ - 13.614
244
+ - 14.014
245
+ - 14.414
246
+ - 14.815
247
+ - 15.215
248
+ - 15.616
249
+ - 16.016
250
+ - 16.416
251
+ - 16.817
252
+ - 17.217
253
+ - 17.618
254
+ - 18.018
255
+ - 18.418
256
+ - 18.819
257
+ - 19.219
258
+ filepositions:
259
+ - 1573
260
+ - 24627
261
+ - 56532
262
+ - 90630
263
+ - 137024
264
+ - 185134
265
+ - 225110
266
+ - 262990
267
+ - 291508
268
+ - 330947
269
+ - 370739
270
+ - 398621
271
+ - 426203
272
+ - 448515
273
+ - 468895
274
+ - 488660
275
+ - 508208
276
+ - 523991
277
+ - 541463
278
+ - 558463
279
+ - 572248
280
+ - 590480
281
+ - 604788
282
+ - 620959
283
+ - 632658
284
+ - 645806
285
+ - 655949
286
+ - 668266
287
+ - 684172
288
+ - 697064
289
+ - 713306
290
+ - 728607
291
+ - 746615
292
+ - 760836
293
+ - 774867
294
+ - 790766
295
+ - 804779
296
+ - 821676
297
+ - 843681
298
+ - 857278
299
+ - 873427
300
+ - 888404
301
+ - 900958
302
+ - 914336
303
+ - 927537
304
+ - 941037
305
+ - 958188
306
+ - 974841
307
+ - 988796
308
+ audiocodecid: 2
309
+ videodatarate: 336.705289672544
310
+ duration: 19.486
311
+ hasCuePoints: false
312
+ width: 320
313
+ ..."
314
+ end
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ module RVideo
4
+ describe Inspector do
5
+ it "should raise an error if ffmpeg cannot be found" do
6
+ lambda {
7
+ file = Inspector.new(:file => "#{TEST_FILE_PATH}/kites.mp4", :ffmpeg_binary => "ffmpeg-nonexistant")
8
+ }.should raise_error(RuntimeError, /^ffmpeg could not be found/)
9
+ end
10
+
11
+ it "should raise an error if it doesn't recognize a file format" do
12
+ unrecognized_format(:text)
13
+ end
14
+
15
+ def unrecognized_format(format)
16
+ file = Inspector.new(:raw_response => files(format))
17
+ file.unknown_format?.should be_true
18
+ end
19
+ end
20
+
21
+ describe Inspector, " parsing ffmpeg info" do
22
+
23
+ it "should read ffmpeg build data successfully (with a darwinports build)" do
24
+ file = Inspector.new(:raw_response => ffmpeg('darwinports'))
25
+ file.ffmpeg_configuration.should == "--prefix=/opt/local --prefix=/opt/local --disable-vhook --mandir=/opt/local/share/man --extra-cflags=-DHAVE_LRINTF --extra-ldflags=-d -L/opt/local/lib --enable-gpl --enable-mp3lame --enable-libogg --enable-vorbis --enable-faac --enable-faad --enable-xvid --enable-x264 --enable-a52 --enable-dts"
26
+ file.ffmpeg_version.should == "SVN-r6399"
27
+ file.ffmpeg_libav.should == ["libavutil version: 49.0.1", "libavcodec version: 51.16.0", "libavformat version: 50.5.0"]
28
+ file.ffmpeg_build.should == "built on Mar 29 2007 17:18:04, gcc: 4.0.1 (Apple Computer, Inc. build 5367)"
29
+ file.raw_metadata.should =~ /^Input #/
30
+ end
31
+
32
+ it "should read ffmpeg build data successfully (with a compiled build)" do
33
+ file = Inspector.new(:raw_response => ffmpeg(:osx_intel_1))
34
+ file.ffmpeg_configuration.should == "--enable-memalign-hack --enable-mp3lame --enable-gpl --disable-vhook --disable-ffplay --disable-ffserver --enable-a52 --enable-xvid --enable-faac --enable-faad --enable-amr_nb --enable-amr_wb --enable-pthreads --enable-x264"
35
+ file.ffmpeg_version.should == "CVS"
36
+ file.ffmpeg_libav.should == ["libavutil version: 49.0.0", "libavcodec version: 51.9.0", "libavformat version: 50.4.0"]
37
+ file.ffmpeg_build.should == "built on Apr 15 2006 04:58:19, gcc: 4.0.1 (Apple Computer, Inc. build 5250)"
38
+ file.raw_metadata.should =~ /^Input #/
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,140 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ def setup_spec
4
+ @options = {:input_file => "foo", :output_file => "bar", :resolution => "baz"}
5
+ @simple_avi = "ffmpeg -i $input_file$ -ar 44100 -ab 64 -vcodec xvid -acodec mp3 -r 29.97 -s $resolution$ -y $output_file$"
6
+ @transcoder = RVideo::Transcoder.new
7
+ @mock_original_file = mock(:original)
8
+ @mock_original_file.stub!(:raw_response)
9
+ RVideo::Inspector.stub!(:new).and_return(@mock_original_file)
10
+ end
11
+
12
+ module RVideo
13
+
14
+ describe Transcoder, " when the execute method receives valid parameters" do
15
+ before do
16
+ setup_spec
17
+ @transcoder.stub!(:check_integrity).and_return(true)
18
+ end
19
+
20
+ it "should pass a string as-is, along with options" do
21
+ @transcoder.stub!(:parse_and_execute)
22
+ @simple_avi = "ffmpeg -i foo"
23
+ @transcoder.execute(@simple_avi, @options)
24
+ end
25
+
26
+ it "should store a Tool object at transcoder.executed_commands" do
27
+ @mock_ffmpeg = mock("ffmpeg")
28
+ Tools::AbstractTool.stub!(:assign).and_return(@mock_ffmpeg)
29
+ @mock_ffmpeg.should_receive(:execute)
30
+ @transcoder.execute(@simple_avi, @options)
31
+ @transcoder.executed_commands.size.should == 1
32
+ @transcoder.executed_commands.first.should == @mock_ffmpeg
33
+ end
34
+
35
+ end
36
+
37
+ describe Transcoder, " file integrity checks" do
38
+
39
+ before do
40
+ setup_spec
41
+ @transcoder.stub!(:parse_and_execute)
42
+ @mock_processed_file = mock("processed")
43
+ @mock_original_file.stub!(:duration).and_return 10
44
+ @mock_processed_file.stub!(:duration).and_return 10
45
+ @mock_processed_file.stub!(:invalid?).and_return false
46
+ Inspector.should_receive(:new).once.with(:file => "foo").and_return(@mock_original_file)
47
+ Inspector.should_receive(:new).once.with(:file => "bar").and_return(@mock_processed_file)
48
+ end
49
+
50
+ it "should call the inspector twice on a successful job, and should set @original and @processed" do
51
+ @transcoder.original.should be_nil
52
+ @transcoder.processed.should be_nil
53
+
54
+ @transcoder.execute(@simple_avi, @options)
55
+ @transcoder.original.should == @mock_original_file
56
+ @transcoder.processed.should == @mock_processed_file
57
+ end
58
+
59
+ it "should check integrity" do
60
+ @transcoder.should_receive(:check_integrity).once.and_return true
61
+ @transcoder.execute(@simple_avi, @options).should be_true
62
+ @transcoder.errors.should be_empty
63
+ end
64
+
65
+ it "should fail if output duration is more than 10% different than the original" do
66
+ @mock_original_file.should_receive(:duration).twice.and_return(10)
67
+ @mock_processed_file.should_receive(:duration).twice.and_return(13)
68
+ @transcoder.execute(@simple_avi, @options).should be_false
69
+ @transcoder.errors.should == ["Original file has a duration of 10, but processed file has a duration of 13"]
70
+ end
71
+
72
+ it "should fail if the processed file is invalid" do
73
+ @mock_processed_file.should_receive(:invalid?).and_return(true)
74
+ @transcoder.execute(@simple_avi, @options).should be_false
75
+ @transcoder.errors.should_not be_empty
76
+ end
77
+
78
+ end
79
+
80
+ describe Transcoder, "#parse_and_execute" do
81
+ before do
82
+ @options = {:input_file => "foo", :output_file => "bar", :resolution => "baz"}
83
+ @simple_avi = "ffmpeg -i $input_file$ -ar 44100 -ab 64 -vcodec xvid -acodec mp3 -r 29.97 -s $resolution$ -y $output_file$"
84
+ @mock_tool = mock("tool")
85
+ @mock_tool.stub!(:execute)
86
+ @transcoder = Transcoder.new
87
+ Inspector.stub!(:new)
88
+ end
89
+
90
+ it "should assign a command via AbstractTool.assign, and pass the right options" do
91
+ Tools::AbstractTool.should_receive(:assign).with(@simple_avi, @options).and_return(@mock_tool)
92
+ @transcoder.send(:parse_and_execute, @simple_avi, @options)
93
+ end
94
+
95
+ it "should call Tools::AbstractTool once with a one-line recipe" do
96
+ Tools::AbstractTool.should_receive(:assign).once.and_return(@mock_tool)
97
+ @transcoder.send(:parse_and_execute, @simple_avi, @options)
98
+ end
99
+
100
+ it "should call twice with a two-line recipe" do
101
+ two_line = "ffmpeg -i foo \n ffmpeg -i bar"
102
+ Tools::AbstractTool.should_receive(:assign).twice.and_return(@mock_tool)
103
+ @transcoder.send(:parse_and_execute, two_line, @options)
104
+ end
105
+
106
+ it "should call five times with a five-line recipe" do
107
+ five_line = "ffmpeg -i foo \n ffmpeg -i bar \n flvtool -i foo \n mp4box \n qt tools 8"
108
+ Tools::AbstractTool.should_receive(:assign).exactly(5).and_return(@mock_tool)
109
+ @transcoder.send(:parse_and_execute, five_line, @options)
110
+ end
111
+
112
+ it "should pass an exception from the abstract tool" do
113
+ Tools::AbstractTool.should_receive(:assign).and_raise(TranscoderError::UnexpectedResult)
114
+
115
+ lambda {
116
+ @transcoder.send(:parse_and_execute, @simple_avi, @options)
117
+ }.should raise_error(TranscoderError::UnexpectedResult)
118
+ end
119
+ end
120
+
121
+ describe Transcoder, " when the execute method receives invalid parameters" do
122
+ before do
123
+ setup_spec
124
+ end
125
+
126
+ it "should raise an exception when trying to call a tool that doesn't exist" do
127
+ lambda {
128
+ @transcoder.send(:parse_and_execute, "foo -i bar")
129
+ }.should raise_error(NameError, "uninitialized constant RVideo::Tools::Foo")
130
+ end
131
+
132
+ it "should raise an exception when the first argument is not a string" do
133
+ [String, 1, 1.0, true, nil, :foo].each do |obj|
134
+ lambda {
135
+ @transcoder.execute(obj)
136
+ }.should raise_error(ArgumentError, /first argument must either be/)
137
+ end
138
+ end
139
+ end
140
+ end