Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

John W. Long http://wiseheartdesign.com

« Newer Snippets
Older Snippets »
Showing 1-3 of 3 total  RSS 

Object#subclasses

Find every subclass of an object. Limit the query to direct descendants by setting direct to true.

require 'test/unit'

class Object
  def self.subclasses(direct = false)
    classes = []
    if direct
      ObjectSpace.each_object(Class) do |c|
        next unless c.superclass == self
        classes << c
      end
    else
      ObjectSpace.each_object(Class) do |c|
        next unless c.ancestors.include?(self) and (c != self)
        classes << c
      end
    end
    classes
  end
end

class TrackSubclassesTest < Test::Unit::TestCase

  class A; end
  class B < A; end
  class C < B; end
  class D < A; end
  class E; end
  class F < E; end
  
  def test_subclasses
    assert_equal [F], E.subclasses
    assert_equal [C], B.subclasses
    assert_equal [B, D], A.subclasses(true).sort_by { |c| c.name }
    assert_equal [B, C, D], A.subclasses.sort_by { |c| c.name }
  end
  
end

Rails and Vim

A simple command for opening related Rails project files in Vim:

#!/usr/bin/env ruby

if ARGV.empty?
  puts "usage: #{File.basename($0)} string" 
  puts "  Scans related Rails directories for " + 
         "files begining with string " 
  puts "  and opens them in vi." 
  exit
end

files = []
ignore = [/CVS$/]

# Find models or controllers that match args
ARGV.each do |arg|
  models = Dir["app/models/#{arg}*"]
  controllers = Dir["app/controllers/#{arg}*"]
  files += models + controllers
end

# Remove duplicates
files.sort!.uniq!

# Add unit tests for models
files.grep(%r{app/models/(.*?).rb}) do
  tests = Dir["test/unit/#{$1}_test.rb"]
  files += tests
end

# Add views and functional tests for controllers
files.grep(%r{app/controllers/(.*?)_controller.rb}) do
  views = Dir["app/views/#{$1}/*"]
  tests = Dir["test/functional/#{$1}_controller_test.rb"]
  files += views + tests
end

# Add views and fixtures for mailers
files.grep(%r{app/models/(.*?_mailer).rb}) do
  views = Dir["app/views/#{$1}/*"]
  fixtures = Dir["test/fixtures/#{$1}/*"]
  files += views + fixtures
end

# Again remove duplicates
files.sort!.uniq!

# Remove files that match ignore list
files.delete_if do |filename|
  result = false
  ignore.each do |i|
    if filename =~ i
      result = true
      break
    end
  end
  result
end

system "vi -o #{files.join(' ')}" 


Drop it in a file called "edit" in your path and you can open related rails files with a few key strokes:

# open AccountController and related tests and views:
edit account_c

# open AccountMailer and related tests, views, and fixtures:
edit account_m

# open everything related to accounts:
edit account


A detailed explanation here: http://wiseheartdesign.com/articles/2006/07/27/rails-and-vim/.

Testing Rails Validations

#
# Useful for testing Rails ActiveRecord validations. For more information see:
# http://wiseheartdesign.com/articles/2006/01/16/testing-rails-validations/
#
module ValidationTestHelper
  def assert_valid(field, message, *values)
    __model_check__
    values.each do |value|
      o = __setup_model__(field, value)
      if o.valid?
        assert_block { true }
      else
        messages = [o.errors[field]].flatten
        assert_block("unexpected invalid field <#{o.class}##{field}>, value: <#{value.inspect}>, errors: <#{o.errors[field].inspect}>.") { false }
      end
    end
  end
  
  def assert_invalid(field, message, *values)
    __model_check__
    values.each do |value|
      o = __setup_model__(field, value)
      if o.valid?
        assert_block("field <#{o.class}##{field}> should be invalid for value <#{value.inspect}> with message <#{message.inspect}>") { false }
      else
        messages = [o.errors[field]].flatten
        assert_block("field <#{o.class}##{field}> with value <#{value.inspect}> expected validation error <#{message.inspect}>, but got errors <#{messages.inspect}>") { messages.include?(message) }
      end
    end
  end
  
  def __model_check__
    raise "@model must be assigned in order to use validation assertions" if @model.nil?
    
    o = @model.dup
    raise "@model must be valid before calling a validation assertion, instead @model contained the following errors #{o.errors.instance_variable_get('@errors').inspect}" unless o.valid?
  end
  
  def __setup_model__(field, value)
    o = @model.dup
    attributes = o.instance_variable_get('@attributes')
    o.instance_variable_set('@attributes', attributes.dup)
    o.send("#{field}=", value)
    o
  end
end
« Newer Snippets
Older Snippets »
Showing 1-3 of 3 total  RSS