Posted by Mike
Thu, 19 Nov 2009 18:19:00 GMT
Here are a couple of Shoulda macros that I’ve been using. One is to validate that partials are rendered in a view and the other is to validate globbed routes.
should_render_partial
As the name the name implies this macro validates that a partial has been rendered. The macro was born out of the need to test partials being rendered in an implementation of the Presenter Pattern that I wrote. The presenter I wrote was for Appstatz.com a site my friend Shane Vitarana created for tracking iPhone application sales and downloads. The graphs on the site are displayed with the Bluff JavaScript graphing library. The data used by Bluff in each kind of graph was rendered with a composition of different partials. The Presenter Pattern that was implemented was driving which partials were to be rendered based on the state of the application and thus tests were written to validate the implementation of the pattern is acting as expected.
Using should_render_partial takes absolute or relative paths as strings or symbols as its argument and is as easy as this example
class FoosControllerTest < ActionController::TestCase
context "a beautiful Bluff graph" do
setup do
@foo = Factory :foo
get :show, :id => @foo.id
end
should_render_partial 'layouts/_logo'
should_render_partial :_data
should_render_partial :_summary
end
end
The code for should_render_partial is listed below and a Gist of the code is listed at http://gist.github.com/237938
# shoulda validation that a partial has been rendered by a view
class Test::Unit::TestCase
def self.should_render_partial(partial)
should "render partial #{partial.inspect}" do
assert_template :partial => partial.to_s
end
end
end
Shoulda loads macros from the test/shoulda_macros/ directory therefore add the macro code to a file in that directory.
should_route_glob
Again, as the name implies should_route_glob tests that if there is a globbing route specified in the config/routes.rb then it is acting as expected. Globbed routes should be the last route mapping in the config/routes.rb file as it will greedily respond to all requests. This kind of routing is used in content management systems and I’ve also seen it used in specialized 404 handlers. For instance if an application is ported to Rails, adding a final controller route that accepts all requests would be useful to track down legacy requests. These requests, their URI and parameters, would be stored in a table so they can be inspected later. Using this technique one can easily find legacy routes that are not be handled by the new controllers, or unexpected routes that are exposed from buggy Ajax requests or odd user input, etc.
The routing (implying a controller named Foo) and its functional test are listed below.
ActionController::Routing::Routes.draw do |map|
# GET /a/b/c will be exposed to the action as an array in params[:path] and it
# will have already been delimited by the '/' character in the requested path
map.any '*path', :controller => 'foos', :action => 'index'
end
The test code is as follows.
class FoosControllerTest < ActionController::TestCase
should_route_glob :get, '/a/b/c', :action => 'show', :path => 'a/b/c'.split('/')
end
The code for should_route_glob is listed below and a Gist of the code is listed at http://gist.github.com/237987 This code may be a bit verbose as it appears that (as of 11/18/2009) Shoulda is handling globbed routes better. Add a comment if you improve this should_route_glob macro. Shoulda loads macros from the test/shoulda_macros/ directory therefore add the code to a file in that directory.
class Test::Unit::TestCase
def self.should_route_glob(method, path, options)
unless options[:controller]
options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
end
options[:controller] = options[:controller].to_s
options[:action] = options[:action].to_s
populated_path = path.dup
options.each do |key, value|
options[key] = value if value.respond_to? :to_param
populated_path.gsub!(key.inspect, value.to_s)
end
should_name = "route #{method.to_s.upcase} #{populated_path} to/from #{options.inspect}"
should should_name do
assert_routing({:method => method, :path => populated_path}, options)
end
end
end
Posted in Rails, Ruby, Shoulda | Tags rails, ruby, shoulda | no comments | no trackbacks
Posted by Mike
Tue, 01 Sep 2009 06:10:00 GMT
I just published a minor point release of the MMS2R Gem version 2.3.0 (http://mms2r.rubyforge.org/). If you were not aware, MMS2R is really just a generic multi-part mail processor. If you have a Ruby application ( Rails, Sinatra, Camping, etc.) and it is processing attachments out of email and/or MMS data, then MMS2R is the gem you should be using. MMS2R has many convenience methods to fetch the most likely image attachment, text attachment, etc. It now gives access to any JPEG or TIFF's exif data using the exifr (http://exifr.rubyforge.org/) reader gem. For instance, MMS2R uses the exif data to detect if the source of the message is from a smartphone like an iPhone or BlackBerry, it could be used for other logic as well.
Back in the summer of 2007 I almost wrote a twitpic.com app using MMS2R, but I couldn't make time for myself to do so. MMS2R would have processed the email extracting images that I had taken with my phone, I would then have posted those to S3 referenced with tiny url links (using Camping Hurl http://github.com/monde/hurl/) into my Twitter feed. I had written MMS2R even earlier than that time, but the emphasis has always been to make it easy to get at MMS data so that it can be used easily in all kinds of applications, social applications in particular.
There are two places to start looking for ideas on how to use MMS2R in a Rails application as I've just described. The first is the PeepCode book Luke Francl (http://justlooking.recursion.org/) and I wrote about it: "Receiving Email With Ruby"
http://peepcode.com/products/mms2r-pdf
Another is a recent Rails Magazine article by By Jason Seifer (http://jasonseifer.com/) is titled "Receiving E-Mail With Rails" http://railsmagazine.com/articles/3
There are a number of startups and web sites listed on the MMS2R RubyForge page (http://mms2r.rubyforge.org/) that are using the Gem in their application stack. One of those is Luke's FanChatter (http://www.fanchatter.com/). At the beginning of the summer Fan Chatter received startup funding from Y Combinator (http://ycombinator.com/). So if you use MMS2R in your social Rails application, it might improve your chances of being funded by Y Combinator. Congratulations Luke.
Posted in MMS2R, Rails, Ruby | Tags mms2r, rails, ruby | no comments | no trackbacks
Posted by Mike
Wed, 30 Jul 2008 17:50:00 GMT
Kids that smoke pot grow up to be short adults
Like kids that start smoking pot before the age of 13 stunting their growth, almost every Java programmer has an aspect of their OO programming skills stunted. Namely the OO principle of “Favor ‘object composition’ over ‘class inheritance’.” from the GofF book about design patterns . Because you can’t do that naturally in Java one becomes heavily dependent on class inheritance and your ability to solve problems elegantly in Ruby is extremely disabled when first using the language.
Example
What’s up Java Guy?:
arr = [1, 2, 3,]
if arr.size > 0
#do something
end
How’s it hang’n OO dude?:
arr = [1, 2, 3,]
if !arr.empty?
#do something
# fyi, in ActiveRecord there is arr.any?
end
The Fundamental Idea
Start looking at querying objects for their state instead of pulling their state out of them. When you start doing this you’ll come up on situations where the object is not providing a query method that you need. That is your entry point into the power of Ruby because you’ll start to learn how to open up classes and objects using various Ruby techniques to create the query method needed for the situation.
In the above code there is a comment that ActiveRecord defines #any? for its collections. See the definition of any? in association_collection.rb . Essentially #any? is just !arr.empty? The point being that Ruby didn’t provide an #any? method for collections so it was defined in ActiveRecord. There is no reason that you shouldn’t be doing the same in your code when you need a query method for your situation.
ReihH describes the query method pattern at depth in Ruby Patterns: Query Method and was the inspiration for this post.
Resources
Once you start applying the query pattern in your code you’ll want to follow up by understanding the following posts.
Posted in Java, Rails, Ruby | Tags java, rails, ruby | no comments | no trackbacks
Posted by Mike
Fri, 05 Jun 2009 07:49:00 GMT
Here is a screen shot of my current environment for programming Rails.

Layout
I’m on Linux and using Gnome as my desktop. On the left hand side is a gnome terminal with autotest running and on the right hand side is gvim. Notice that gvim is split into two horizontal windows the upper is dedicated to the functional code and the lower is dedicated to spec/test code. btw, I’m also using tpope’s rails.vim plugin in gvim as well.
I learned this particular style of having autotest and gvim with functional and testing code all viewable in one location from Eric Hodel Its great, everything is in one place, autotest gives immediate feedback when I’ve broken my code and my functional code and testing code are viewable together.
script it
I wrote a script called railsvim that when called with a rails project directory will open the gnome terminal and gvim in this configuration centered on my desktop. That way I don’t have to place and size all the windows by hand saving me time, e.g.
railsvim ~/projects/superfu
The script is hosted on
gist if you like to copy it:
railsvim . Looking at a copy of the script below you will find that that gnome terminal is opened with three tabs, one for script/server, one for script/console, and one for autotest which has focus by default since its last tab created.
#!/bin/bash
DIR="${1}"
if [ ! -d "${DIR}" ]; then
echo "call me with a directory, e.g.:"
echo "${0} /some/path/to/dir"
exit 1
fi
gnome-terminal --geometry=130x35+345+250 \
--window --working-directory=${DIR} -t "script server" -e "ruby script/server" \
--tab --working-directory=${DIR} -t "script console" -e "ruby script/console" \
--tab --working-directory=${DIR} -t "autotest" -x autotest &
gvim -c ":wincmd s" -geometry 120x60+1285+0 ${DIR} &
You’ll have to play with the geometry settings for the gnome terminal and gvim to customize the placements for your desktop.
resources
My railsvim script:
Hacking/automating the Linux desktop with wmctrl and others:
tpope (“TextMate may be the latest craze for developing Ruby on Rails applications, but Vim is forever”) rails.vim plugin for powerful vim and rails coding integration
If you have textmate envy here’s how to turn your gvim into a ghetto with their kind of font:
Posted in Rails, Ruby, vim | Tags rails, ruby, vim | 1 comment | no trackbacks
Posted by Mike
Wed, 04 Jun 2008 08:00:00 GMT
Last month before RailsConf Luke Francl and I published "MMS2R : Making email useful" on PeepCode. Its a PDF book so kill all the trees that you can buying it. The book is awesome because of the diversity of experience that Luke brings to the book and Geoffrey Grosenbach is a fabulous editor.
We cover a wide range of experience dealing with MMS in Rails and other applications. An overview is:
- Introduction (protocol, mobile networks, gateways, etc.)
- A Brief History (MMS integrated with web apps, etc.)
- Processing MMS
- Working with ActionMailer (e.g. Rails, daemonizing Rails, IMAP & POP fetching)
- Testing (Test::Unit & RSpec)
- Advanced Topics
MMS2R handles more than just MMS
You may not be aware of this but MMS are just multi-part MIME encoded email. And Luke likes to say that MMS2R is good for email in general not just MMS. MMS2R pulls apart multipart email in an intelligent manner and gives you access to its content in an easy fashion. It writes each part decoded to temporary files and provides a duck typed CGI File so that it is easily integrated with attachment_fu.
Pimp my WWR
I put a lot work into MMS2R so that its easy to access user generated content in an intelligent fashion. Recommend me on Working With Rails if you’ve benefited from this experience and thank you in advance!

Friends of MMS2R
MMS2R and our book would not have been possible without the help of these awesome people from the open source community:
Posted in Books, MMS2R, Nuby Rails, Rails, Ruby | Tags actionmailer, mms2r, rails, ruby | no comments | no trackbacks
Posted by Mike
Sun, 24 Feb 2008 07:51:00 GMT
One of the coolest small Rails apps is Ozimodo
http://ozimodo.rubyforge.org/ , a Rails based tumblelog
Micro blogging and non-traditional forms of communication are helping to evolve how we’ll be communicating in the future. Its list of contributors is a veritable who’s who in the Rails community.
Here’s an enumeration of aspects that make Ozimodo great in the current context
Read more...
Posted in Ozimodo, Rails, Ruby, web2.0 | Tags ozimodo, rails, ruby, tumblelog | 2 comments | no trackbacks
Posted by Mike
Fri, 08 Feb 2008 18:56:00 GMT
impostor version 0.0.1 has been released!
Makes automatic posts to the following forum applications:
- Web Wiz Forums (WWF) 7.9
- Web Wiz Forums (WWF) 8.0
- PHP Bullitin Board (phpBB) 2.0 (2.0.22)
SYNOPSIS:
# config yaml has options specefic to wwf79, wwf80, phpbb2, etc.
# read the impostor docs for options to the kind of forum in use
# config can be keyed by symbols or strings
config = YAML::load_file('conf/impostor.yml')
post = WWW::Impostor.new(config)
message = %q{hello world is to application
programmers as tea pots are to graphics programmers}
# your application stores forum and topic ids
post.post(forum=5,topic=10,message)
# make a new topic
subject = "about programmers..."
post.new_topic(forum=7,subject,message)
post.logout
Changes:
0.0.1 / 2008-02-02
by Mike Mondragon
http://impostor.rubyforge.org/
Posted in Gems, imPOSTor, Ruby | Tags gems, imPOSTor, ruby | no comments | no trackbacks
Posted by Mike
Fri, 01 Feb 2008 23:26:00 GMT
Dave Myron of Contentfree wrote a great Gem that he’s
named Blackbook. The Gem is hosted in the
Contentfree collection on Ruby
Forge. Blackbook imports
contacts from a number of sources and currently supports AOL Mail, GMail, Hotmail,
Yahoo! Mail, and contacts from CSV file. Blackbook exports the contacts that have
been collected as XML and VCard formatted text or as an Array of Hashes
with :name and :email keys.
Read more...
Posted in Blackbook, Gems, Ruby | Tags blackbook, gem, ruby | 16 comments | no trackbacks
Posted by Mike
Thu, 24 Jan 2008 20:18:00 GMT
When I first started programming Ruby I lurked on the Seattle.rb mailing list and then gathered the courage to finally attend a meeting. At the time I had written a Perl script that did the basics of what MMS2R does and it was lucky for me that Aaron Patterson who coincidently maintains WWW::Mechanize was also a member of Seattle.rb. My Perl script was using Perl’s original version of WWW::Mechanize to scrape pictures from MMS that were sent by mobile subscribers to Sprint.
I knew that it would be a great experience to me if I converted the Perl script into a Gem. I would be contributing to the Ruby community, I would be learning how to author a Gem, and I would improve on my coding and testing abilities.
A testing problem I was perplexed with was how should I test my code that reaches out to Sprint’s content servers to scrape images? The other cellular carriers actually deliver their images mime-encoded in the MMS payload so testing them in a closed environment is simple enough with a fixture.
Read more...
Posted in Ruby, Seattle.rb | Tags ruby, seattle.rb, tdd, testing | 3 comments | no trackbacks
Posted by Mike
Wed, 23 Jan 2008 22:15:00 GMT
mms2r version 2.0.0 has been released!
Upcoming!
DESCRIPTION:
MMS2R is a library that decodes the parts of an MMS message to disk while
stripping out advertising injected by the mobile carriers. MMS messages are
multipart email and the carriers often inject branding into these messages. Use
MMS2R if you want to get at the real user generated content from a MMS without
having to deal with the cruft from the carriers.
If MMS2R is not aware of a particular carrier no extra processing is done to the
MMS other than decoding and consolidating its media.
Contact the author to add additional carriers to be processed by the library.
Suggestions and patches appreciated and welcomed!
Corpus of carriers currently processed by MMS2R:
- Alltel: message.alltel.com
- AT&T/Cingular/Legacy: mms.att.net, txt.att.net, mmode.com, mms.mycingular.com,
cingularme.com
- Dobson/Cellular One: mms.dobson.net
- Helio: mms.myhelio.com
- Hutchison 3G UK Ltd: mms.three.co.uk
- LUXGSM S.A.: mms.luxgsm.lu
- NetCom (Norway): mms.netcom.no
- Nextel: messaging.nextel.com
- O2 Germany: mms.o2online.de
- Orange & Regional Oranges: orangemms.net, mmsemail.orange.pl, orange.fr
- PXT New Zealand: pxt.vodafone.net.nz
- Sprint: pm.sprint.com, messaging.sprintpcs.com
- T-Mobile: tmomail.net
- Verizon: vzwpix.com, vtext.com
Changes:
1.2.0 / 2008-01-23 (Skwisgaar Skwigelf – fastest guitarist alive)
- added support for pxt.vodafone.net.nz PXT New Zealand
- added support for mms.o2online.de O2 Germany
- added support for orangemms.net Orange UK
- added support for txt.att.net AT&T
- added support for mms.luxgsm.lu LUXGSM S.A.
- added support for mms.netcom.no NetCom (Norway)
- added support for mms.three.co.uk Hutchison 3G UK Ltd
- removed deprecated #get_number use #number
- removed deprecated #get_subject use #subject
- removed deprecated #get_body use #body
- removed deprecated #get_media use #default_media
- removed deprecated #get_text use #default_text
- removed deprecated #get_attachment use #attachment
- fixed error when Sprint content server responds 500
- better yaml configs
- moved TMail dependency from Rails ActionMailer SVN to ‘official’ Gem
- ::new greedily processes MMS unless otherwise specified as an initialize
option :process => :lazy
- logger moved to initialize option :logger => some_logger
- testing using mocks and stubs instead of duck raped Net::HTTP
- fixed typo in name of method #attachement to #attachment
- fixed broken downloading of Sprint videos
Posted in Gems, MMS2R, Ruby | Tags gems, mms2r, ruby | 3 comments | no trackbacks