Dynamic RSpec tests using plain old Ruby
Just happened to stumble upon the following article at caboo.se: Handy dynamic rspec tip.
I immediately found a way of simplifying a test case that involves testing that an ever increasing number of videos can be transcoded:
1 require File.dirname(__FILE__) + '/helper' 2 require File.dirname(__FILE__) + '/../lib/transcoder.rb' 3 4 context "Transcoder" do 5 6 Dir.glob('videos/*').each do |video| 7 it "should support #{video}" do 8 Transcoder.convert(video, "site/#{video}.flv")[:file_size].should > 0 9 end 10 end 11 end
You can also use it to test model validations:
1 require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') 2 3 4 describe "Product" do 5 @@valid_product_attributes = { 6 :name => 'WTF', 7 :description => 'LOL', 8 :price => '10.0', 9 :tax => '22.0' } 10 11 12 before(:each) do 13 14 end 15 16 it "should create a new instance given valid attributes" do 17 Product.create!(@@valid_product_attributes) 18 end 19 20 @@valid_product_attributes.each do |name, value| 21 it "should not allow blank #{name}" do 22 lambda do 23 Product.create!(@@valid_product_attributes.except(name)) 24 end.should raise_error(ActiveRecord::RecordInvalid) 25 end 26 end 27 end
How to extract video metadata with mplayer and Ruby
You can easily extract video metadata into a hash with mplayer and Ruby:
1 class Metadata 2 3 def self.get(file) 4 command = "mplayer -vo null -ao null -frames 0 -identify #{file}" 5 metadata = nil 6 7 Open3.popen3(command) do |input, output, error| 8 metadata = output.readlines.grep(/ID_.*/).collect {|name| name[3..name.length].split('=')} 9 metadata = metadata.inject({}) {|hash, (key, value)| hash[key.to_sym] = value.chomp; hash} 10 end 11 12 return metadata 13 end 14 15 end
Then in an RSpec test do:
1 it "should support 3gp" do 2 metadata = Metadata.get("videos/sony_ericsson_k850i.3gp") 3 4 metadata[:DEMUXER].should == 'mov' 5 metadata[:VIDEO_FORMAT].should == 's263' 6 metadata[:VIDEO_WIDTH].should == '176' 7 metadata[:VIDEO_HEIGHT].should == '144' 8 end
Note to self: metadata.demuxer would perhaps be a slightly better syntax.
How to extract a thumbnail from a video file with mplayer
1 mplayer 123.avi -ss 1 -nosound -vo jpeg:outdir=. -frames 2
We use the -ss switch to jump to the first second of the video; specify the time in either seconds or hh:mm:ss. We tell mplayer that we want two frames with the -frames switch.
Make sure jpeg is in the list of supported video output formats:
1 mplayer -vo help
How to use RSpec and ZenTest in a standalone Ruby project
First install the RSpec and ZenTest gem:
1 $ sudo gem install rspec zentest
Next create the spec folder:
1 $ cd project_folder 2 $ mkdir spec
Save the following to spec/helper.rb:
1 $LOAD_PATH.unshift File.dirname(__FILE__) + '/..' 2 3 require 'rubygems' 4 require 'spec' 5 #require 'spec/rake/spectask' not needed, because ZenTest supports rspec now
Now create spec/transcoder_spec.rb, and add the following test to it:
1 require File.dirname(__FILE__) + '/helper' 2 require File.dirname(__FILE__) + '/../transcoder.rb' 3 4 context "Transcoder" do 5 setup do 6 # Setup your stuff here 7 end 8 9 it "should support 3gp format" do 10 Transcoder.convert("me_and_you.3gp").should == true 11 end 12 end
Let’s not forget the class we’re testing, put this code in lib/transcoder.rb:
1 class Transcoder 2 def initialize 3 end 4 5 def self.convert(file) 6 return true 7 end 8 end
Note that autotest automatically looks for your code in the lib folder.
Now run the test with the zentest command:
1 autotest
Change your files and autotest will run the test again.
Tip: Read Getting started with Autotest – Continuous Testing and Setting up autotest to use Growl on OSX for more information on how to increase your productivity.
A simple Jabber/XMPP bot that uses the Jabber:Simple library
First install Jabber::Simple:
1 $sudo gem install xmpp4r-simple -y
On OSX you might get this error when installing xmpp4r-simple and the rdoc dependency:
1 make 2 gcc -I. -I/usr/local/lib/ruby/1.8/i686-darwin8.10.3 -I/usr/local/lib/ruby/1.8/i686-darwin8.10.3 -I. -fno-common -g -O2 -fno-common -pipe -fno-common -c callsite.c 3 gcc -I. -I/usr/local/lib/ruby/1.8/i686-darwin8.10.3 -I/usr/local/lib/ruby/1.8/i686-darwin8.10.3 -I. -fno-common -g -O2 -fno-common -pipe -fno-common -c rcovrt.c 4 cc -dynamic -bundle -undefined suppress -flat_namespace -L"/usr/local/lib" -o rcovrt.bundle callsite.o rcovrt.o -lruby -lpthread -ldl -lobjc 5 /usr/bin/ld: /usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libpthread.dylib unknown flags (type) of section 6 (__TEXT,__dof_plockstat) in load command 0 6 /usr/bin/ld: /usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libdl.dylib unknown flags (type) of section 6 (__TEXT,__dof_plockstat) in load command 0 7 /usr/bin/ld: /usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libobjc.dylib load command 9 unknown cmd field 8 /usr/bin/ld: /usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libSystem.dylib unknown flags (type) of section 6 (__TEXT,__dof_plockstat) in load command 0 9 /usr/bin/ld: /usr/lib/libSystem.B.dylib unknown flags (type) of section 6 (__TEXT,__dof_plockstat) in load command 0 10 collect2: ld returned 1 exit status 11 make: *** [rcovrt.bundle] Error 1
Simply install XCode 3 to make the error go away, then run this code to start the bot—warning the bot will execute the message body, for example “ls -la”, on the system:
1 require 'rubygems' 2 require 'xmpp4r-simple' 3 4 include Jabber 5 #Jabber::debug = true 6 7 jid = 'user@server.com' 8 pass = 'password' 9 10 jabber = Simple.new(jid, pass) 11 12 loop do 13 messages = jabber.received_messages 14 messages.each do |message| 15 body = message.body if message.type == :chat 16 17 process = IO.popen(body) 18 result = process.readlines 19 20 jabber.deliver('some.user@gmail.com', result) 21 end 22 23 sleep 1 24 end
To use GTalk from another domain than gmail, you need to edit the Jabber::Simple source code…