Cooked this one up this morning… It will iterate through `svn st | grep \?` and ask for confirmation before adding to your subversion project. Of course, all the cool kids are using git these days anyways ;) Shouldn’t be hard to modify for that.
namespace :svn do
desc "Add files not under (sub)version control"
task :add do
files = `svn st | grep \?`.map{|f| f.gsub(/\?\s+(.+)\n/){$1} }
puts "No new files to add." and return if files.empty?
files.each do |file|
print "... #{file} [Yn]"
`svn add #{file}` unless STDIN.gets =~ /^n/i
end
end
end
I’m working on a project that does some graphing, I and needed to do a linear best fit. A quick google search didn’t find the ruby code snippet I was looking for, so I converted one from PHP. ( Original nasty looking quasi-OO PHP source ) Sorry, no unit tests :)
class LinearRegression
attr_accessor :slope, :offset
def initialize dx, dy=nil
@size = dx.size
dy,dx = dx,axis() unless dy # make 2D if given 1D
raise "arguments not same length!" unless @size == dy.size
sxx = sxy = sx = sy = 0
dx.zip(dy).each do |x,y|
sxy += x*y
sxx += x*x
sx += x
sy += y
end
@slope = ( @size * sxy - sx*sy ) / ( @size * sxx - sx * sx )
@offset = (sy - @slope*sx) / @size
end
def fit
return axis.map{|data| predict(data) }
end
def predict( x )
y = @slope * x + @offset
end
def axis
(0...@size).to_a
end
end
An issue came up yesterday that involved an strange nil error, where an attribute was being delegated to a nil association.
I recalled reading this ticket opened by court3nay from caboo.se and thought it might come in handy for others if I put it in the blogosphere.
The ticket ended up being closed because it was deemed unnecessary. Someone with the moniker “protocool” (presumably trevor at http://protocool.com/) shared the final solution which works out of the box with no patches. It goes something like this:
delegate :some_method, :to => '(some_association or return nil)'
The cool thing about this solution, over the proposed patch, is that you can do whatever you like (rather than simply return nil), such as return a default value or raise a custom exception.
I recently cooked these up, thought someone else might find them handy. Now you can say date.first_of_month, date.first_of_year, etc.
module DateExtensions
def first_of_week
self - self.wday
end
def first_of_month
self - self.day+1
end
def first_of_quarter
(self << (self.month%3 - 1 )%3) - self.day+1
end
def first_of_year
(self << self.month-1) - self.day+1
end
end
Date.send :include, DateExtensions
Addendum: oops, looks like there are already similar methods in Rails’ ActiveSupport:
beginning_of_* rather than first_of_*
However, begining_of_week assumes Monday is the first day of the week, while my version assumes Sunday is the first day.
Here are my tests:
require File.dirname(__FILE__) + '/../test_helper'
class DateExtensionsTest < Test::Rails::TestCase
def test_first_of_week
day = Date.new( 2008, 1, 1 )
w = day.first_of_week
# sunday is first day of week
assert_equal 0, w.wday
assert_equal 30, w.day
end
def test_first_of_month
day = Date.new( 2008, 1, 15 )
assert_equal 1, day.first_of_month.day
end
def test_first_of_year
day = Date.new( 2008, 5, 27 )
y = day.first_of_year
assert_equal 1, y.month
assert_equal 1, y.day
end
def test_first_of_quarter_q1
[1,2,3].each do |month|
day = Date.new( 2008, month, 13 )
q = day.first_of_quarter
assert_equal 1, q.day
assert_equal 1, q.month
end
end
def test_first_of_quarter_q2
[4,5,6].each do |month|
day = Date.new( 2008, month, 13 )
q = day.first_of_quarter
assert_equal 1, q.day
assert_equal 4, q.month
end
end
def test_first_of_quarter_q3
[7,8,9].each do |month|
day = Date.new( 2008, month, 13 )
q = day.first_of_quarter
assert_equal 1, q.day
assert_equal 7, q.month
end
end
def test_first_of_quarter_q4
[10,11,12].each do |month|
day = Date.new( 2008, month, 13 )
q = day.first_of_quarter
assert_equal 1, q.day
assert_equal 10, q.month
end
end
end
I just came across this cool tip from Tom Preston-Werner of rubyisawesome.com. Basically, if you end a mysql commandline query with \G instead of a semicolon, you’ll get a nicely formatted query that is suitable for pasting into a YAML file.
But what if you are not using mysql? We have a project with postgres. There’s probably a psql command to do something similar, but there is also a database agnostic way: Just use the rails console! :)
>> puts User.find(:all).to_yaml
---
- !ruby/object:User
attributes:
status: unverified
salt: L52b2pxGCL
can_invite: "0"
hashed_password: L50/yIQjPCBiU
is_admin: "0"
id: "478674008"
first_name: Mickey
last_name: Mouse
watchlist_by_email: "0"
created_at: 2008-01-30 15:34:26
email: mickey@mouse.com
I’ve been playing with block helpers for some time now, and I love them for their semantic goodness and clarity.
I know that Rails 2 has an assert_email method, which plays nicely with assert_select assert_select_email method.
However, as far as I could tell, this doesn’t allow you to assert any of the headers such as to, from, etc.
Enter assert_emails_sent:
def test_send_crash_data
device_id = 2
assert_email_sent :to => AdminNotifier::CLIENT_CRASH_EMAIL,
:from => AdminNotifier::SYSTEM_EMAIL,
:subject => "Application crashed.",
:body => /device id #{device_id} crashed.+whoops I crashed/ do
AdminNotifier.deliver_send_crash_data('whoops I crashed', device_id)
end
end
- One cool feature is that the values of :to and :from will be automagically sent #email, so you can just say :to => @user, as long as @user.responds_to?(:email).
- Another bonus feature is that you can use either strings or regexps.
grab the code here.
Recently I’ve been refactoring legacy Test::Unit code to use shoulda. Sometimes you can’t factor out repetitive stuff into a context, but you still want to be DRY. Below is an example case of refactoring into a custom should. Note that you need to use class variables, and that the self.should_* method needs to be defined before it’s actually used, since shoulda is built upon metaprogramming which gets evaluated at the class level.
...
def self.should_request sym
sym = sym.to_s
context "when requesting #{sym}" do
setup do
get :download, {:id => @@podcast.id, :type => sym}, @@session
end
should "ask for a device" do
assert_match /Please select a device to download content/, @response.body
end
should "increment the message count when sent #add_to_device" do
assert_difference 'Message.count( :conditions => "device_id = 1")', @@podcast.episodes.size do
xhr :post, :add_to_device, {:id => 1, :type => 'all', :podcast_id => @@podcast.id}, @@session
end
end
end
end
context "A valid account" do
setup do
@account = accounts(:accounts_002)
@@session = {:account_id => @account.id}
@account.devices << Device.find(1)
@@podcast = podcasts(:joe_cartoon)
@@session.merge!({:podcast_episodes => @@podcast.episodes})
end
should_request :all
should_request :latest
should_request :episode
end
...
NameMyPuppy has been a fun personal project of mine. It is a way for friends and family to collaborate to help you name your puppy. You can upload and describe your puppy and then send out invitations to friends and family. They can suggest names and vote on their favorite names. You can also make your puppy posting public so anyone on the site can suggest and vote on names to get even more people voting. Happy naming!
I was suffering with a problem running tests inside of textmate on a Rails 2 project, until I found this comment by David Vrensk at the bottom of this blog post by Rob Sanheim:
Posted by David Vrensk 18 January 2008 @ 9am
I think the easiest solution can be gleaned from the TM ticket that you link to (http://macromates.com/ticket/show?ticket_id=F4DA8B03). I just modify test/test_helper.rb in my current projects so that it starts with
$:.reject! { |e| e.include? ‘TextMate’ }
No patching the distros, and svn still works the way it should.
We hosted the SF Ruby Meetup last night, which was a smashing success. It was fun to have 50+ Ruby geeks crammed into our office. :)
Here are the slides from my presentation about Shoulda.
I like to use factory test helpers to generate attributes which I then pass to ActiveRecord. The default output is expected to be valid (hence the usage with create-bang below). If you want to override any of the defaults, you can simply use Hash#merge.
Here’s an example, using shoulda. It should be pretty clear how it can be applied to vanilla Test::Unit (or the testing framework du jour ;).
## I put this in test_helper.rb so I can use it across all tests. ## You could put it in the actual derived test class as well. def valid_user_attrs( unique = DateTime.now ) { :email => "{unique.hash.abs}@example.com", :first_name => "dummy", :last_name => "user_#{unique}", :profile_attributes => valid_profile_attrs } end def valid_profile_attrs ... end## Here’s the actual test caseclass UserTest < Test::Rails::TestCase context "Two Users" do setup do @user = User.create!( valid_user_attrs ) @user2 = User.create!( valid_user_attrs.merge( :email => "dummy123@dummy.com" ) ) end should "not be friends" do assert !@user.friends.include?( @user2 ) assert !@user2.friends.include?( @user ) end end end
In a previous post, I posted a monkey patch to enhance the behavior of fixtures. I converted it into a plugin format for convenience and testing purposes. I am still aiming to submit it as a patch to Rails 2.0. I’d appreciate any feedback!
get it here:
svn export --username=public svn://internautdesign.com/public/plugins/friendly_fixtures vendor/plugins/friendly_fixtures
from the README:
FriendlyFixtures
This plugin is a simple extension to add some cool features to the fixtures macro in Test::Unit. It is intended for Rails 2.0, but works with 1.2.3 as well.
It enables you to:- load dependent models, which are found by object introspection on a model’s ActiveRecord associations.
- assert that all the loaded fixtures are valid. This can be very helpful in finding bugs.
Example Usage:
class SomeTest < Test::Unit::TestCase
fixtures :user, :dependencies => true, :validate => true
end
I recently wrote a functional test for an AJAX callback action. I wanted to assert that the RJS replaced some text with a particular string. This string is generated by a view helper. To keep this flexibility, I wanted to call the helper from the test.
It turns out to be quite simple. All you have to do is mix-in the helper to your TestCase class, like so:
class CompanyControllerTest < Test::Rails::TestCase
include CompanyHelper
...
end
In a previous post, I mentioned Gabriel Gironda’s snippet showing how to use view helpers in a controller. Calling view-specific helpers from the controller is a particularly useful technique in AJAX callback methods where you need to replace some HTML. The alternative is rendering a partial, which I felt was cumbersome and overkill if you just need to replace a single string of text.
However, the above technique doesn’t work out of the box if you need to use a custom helper that you have written in your app/helpers directory tree. The trick is to use the extend method to mix-in your custom helper modules.
Here is an example, where I extend the help singleton object with the CompanyHelper module, in order to be able to the text_for_action and text_for_notice methods.
def ajax_add_to_portfolio
help.extend ::CompanyHelper
raise "Company doesn't exist!" unless @company
kind = params[:category]
raise help.text_for_action( kind )+" already performed!" if @company.in_portfolio?( @current_user, kind )
@current_user.portfolio_items.create!( :company_id => params[:id], :category => kind )
action_text = help.text_for_action( kind, :past_tense => true )
notice_text = help.text_for_notice( kind )
render :update do |page|
page.flash_then_fade :success, action_text
page.replace_html kind, notice_text
end
rescue Exception => e
handle_exception e
end
I just cooked up some flexible zebra striping for prototype. I call it ...drumroll please… ProtoStripe!
badum-ching! ;)
// protostripe.js
Event.observe( window, 'DOMContentLoaded', function() {
$$('.striped').each( function(e) {
Selector.findChildElements(e, ['tr','li']).each( function(e, idx) {
e.addClassName( idx % 2 == 1 ? 'odd' : 'even');
});
});
});
Just include it in your HTML header, and any tables or lists with class=”striped” will have their appropriate children decorated with “odd” and “even” CSS classes. Unobtrusive JavaScript rocks! :)
