Posts Tagged ‘Ruby’

Timecop: Freeze Time in Ruby for Better Testing

Wednesday, November 19th, 2008 by John Trupiano

This past weekend I released v0.1.0 of the Timecop gem. Timecop makes it dead simple to travel through or freeze time for the sake of creating a predictable and ultimately testable scenario.

The gem is derived from a plugin I wrote a while back to achieve more or less the same functionality for an extremely time-sensitive application. My goals for the gem included:

  1. Drop-in-ability: The primary goal is to allow your app to continue to use Time.now, Date.today and DateTime.now as normal within your application. No overloading of functions with optional arguments (a la today=Date.today) just so you can write test cases.
  2. Environment independence: I wanted the gem to work (a) w/ rails (ActiveSupport actually), (b) w/ plain ruby when the ‘date’ library has been loaded, and (c) w/ plain ruby when the ‘date’ library had not been loaded.
  3. Library independence: I could have utilized mocha to achieve the mocking functionality found under the hood, but because I wanted this to work with plain vanilla ruby, libraries like mocha are out.
  4. Short-term time travel: I wanted to expose the ability to temporarily change the concept of “now.” This is particularly helpful when writing tests where time needs to pass.
  5. Long-range time travel: I wanted to expose the ability to change the concept of “now” for an indeterminate period of time. This is particularly helpful when setting up a rails test environment along with the test data.
  6. Nested time travel: I wanted to provide the ability to nest traveling, allowing the state to be kept within each block (we’ll see an example later).

The gem is hosted on RubyForge and can be installed by simply running:

sudo gem install timecop

(more…)

Watch Multiple Logs in a Single Terminal

Wednesday, November 12th, 2008 by Nick Gauthier

Have you ever opened 4 terminal windows, SSHed each one into a server, and ran tail on all of them to watch 4 log files?

Have you ever had a terminal window open whose sole purpose was to run “tail my_log” over and over again to look at the output of a file?

It’s a pain, isn’t it?

Introducing “Watch Me” a simple ruby script that allows you to watch multiple log files simultaneously.

go from this:

Before Watch Me

Using multiple terminals to watch logs

to this:

Using WatchMe to watch logs

Using WatchMe to watch logs

(more…)

Benchmark Ruby Code with R, rsruby and better-benchmark

Wednesday, October 8th, 2008 by John Trupiano

I’ve found myself on a benchmarking kick these last couple of weeks. Sometime last week, I dug up the better-benchmark library written by Pistos. Pistos’ library is basically just a wrapper for the rsruby gem, which is more or less an interface to R (similar to what rmagick is to ImageMagick).

Combining these tools together, we can do some pretty nifty code performance analysis in very few lines of code, e.g.

require 'rubygems'
require 'better-benchmark'
 
result = Benchmark.compare_realtime(:iterations => 10) { |iteration|
  save_the_world()
}.with { |iteration|
  save_the_world_and_save_the_girl()
}
Benchmark.report_on result

I have forked better-benchmark and wrapped the library up into a RubyGem.

(more…)

Using ActiveRecord’s to_xml to produce custom xml including deep level associations

Wednesday, September 10th, 2008 by Glenn Gentzke

ActiveRecord provides a powerful method to all its records called to_xml. Most web developers using RoR should be familiar with its usage and hopefully use it for their simple xml production needs. But what do you do when you need to produce xml that is selective, includes associations, or contains custom tags? There are many ways to manipulate to_xml’s output and I’ll explain a few below.
(more…)

Merging Adobe PDF’s and generating a table of contents on the fly using ruby

Monday, July 21st, 2008 by Joseph Jakuta

So let’s say you have some random PDFs and what you want is one PDF that includes all of the original PDF files and a table of contents listing all of the files and the proper page numbers. Well in Ruby it is not too hard to put this together. There are a wealth of plugins, gems, and other ruby software available for manipulating and creating PDFs (a thorough list can be found here - http://wiki.rubyonrails.org/rails/pages/HowtoGeneratePDFs). To get this project up and running we are going to use two PDF::Writer (http://rubyforge.org/projects/ruby-pdf/) and PDFTK (http://www.accesspdf.com/pdftk/) - though if you want to get fancier and also include text, html, or xml documents you can use PDF::Htmldoc (http://htmldoc.rubyforge.org/) which requires Htmldoc to be installed. Before I do get started though, I also have give thanks to George Anderson over at Benevolent Code who wrote a lot of similar code on the project which provided me with some great examples.

(more…)

Advanced Model Based searches in rails

Monday, July 21st, 2008 by Scott Davis

After watching a railscast episode on advanced searching I thought I would give it a try. So I came up with a slightly modified version that would handle my search.

Model

class ExportSearch
 
  def timecards
    find_cards
  end
 
  def users(u)
    @u = u
  end
 
  def projects(p)
    @p = p
  end
 
  def tasks(t)
    @t = t
  end
 
  def dates(date1, date2)
    @d1 = date1
    @d2 = date2
  end
 
  def clients(c)
    @c = c
  end
 
private
 
  def find_cards
    TimeCard.find(:all, :conditions => conditions, :include => {:task => :project}, :order => :date)
  end
 
  def projects_conditions
    ["tasks.project_id IN (?)", @p] unless @p.blank?
  end
 
  def client_conditions
    ["projects.client_id IN (?)", @c] unless @c.blank?
  end
 
  def date_conditions
    ["date BETWEEN ? AND ?", @d1, @d2] unless (@d1.blank? || @d2.blank?)
  end
 
  def task_conditions
    ["task_id IN (?)", @t] unless @t.blank?
  end
 
  def users_conditions
    ["user_id IN (?)", @u] unless @u.blank?
  end
 
  def conditions
    [conditions_clauses.join(' AND '), *conditions_options]
  end
 
  def conditions_clauses
    conditions_parts.map { |condition| condition.first }
  end
 
  def conditions_options
    conditions_parts.map { |condition| condition[1..-1] }.flatten
  end
 
  def conditions_parts
    private_methods(false).grep(/_conditions$/).map { |m| send(m) }.compact
  end
end

Controller

    search = ExportSearch.new
    search.users(params[:export][:users].join(',')) unless params[:export][:users].blank?
    search.tasks(params[:export][:tasks].join(',')) unless params[:export][:tasks].blank?
    search.projects(params[:export][:projects].join(',')) unless params[:export][:projects].blank?
    search.dates(start_date, end_date)
 
    @time_cards = search.timecards