# A mixin for Test::Unit classes to ease AR testing
#
# Use in your test class by adding
#
# include ARTestHelper
#
# Written by Nicholas Seckar aka Ulysses
module ARTestHelper
module InstanceMethods
# Access the temporary instance to test.
# In my setup method, I store a new, valid instance in an instance variable such as @p.
#
# The ivar is the first character of the class (@p for Page, @u for User), and usually has an
# attr_reader for it.
#
# This method should return that instance so that the validation checker can access it.
def instance
instance_variable_get("@#{self.class.name[0, 1].downcase}")
end
end
module ClassMethods
# Test that the named associations can be loaded
# Catches errors such as missing tables, classes, etc.
# Only use one directive per test-case
#
# Example: check_associations %w(friends downloads links)
def check_associations(*names)
define_method "test_associations" do
assert(instance.save, 'Must be able to save instance!') if instance.new_record?
names.flatten.each do |assoc|
v = instance.send assoc
v.each { } if v.respond_to?(:each) # Load collections by using each
end
end
end
# Check the validations for the named field
#
# Example:
#
# check_validations_for :email do
# invalid nil, "can't be blank"
# invalid 'boo', /not .* valid .* email/
# valid 'fakeuser@host.com'
# end
def check_validations_for(field, &checks)
define_method("test_validations_for_#{field}") do
ValidationChecker.new(field, checks, self, instance).run
end
end
end
class ValidationChecker < Struct.new(:field_name, :proc, :testcase, :instance)
# Assign the given value to the instance
def assign(value)
instance.send "#{field_name}=", value
end
# Ensure that this value is invalid.
# If a message is supplied, it will be matched against the validation error message.
# The message is matched using === so you can use Regexp's.
def invalid(value, message = nil)
assign value
assert ! instance.valid?, "expected #{field_name} = #{value.inspect} to be invalid"
return unless message
found_msg = instance.errors.on(field_name)
assert message === found_msg, "\nexpected error message: #{message.inspect}\nfound: #{found_msg.inspect}"
end
# Ensure that the given value is valid.
def valid(value)
assign value
assert instance.valid?, "expected #{field_name} = #{value.inspect} to be valid"
assert instance.save # Make sure the database agree's with the validations
end
# Run the validation tests
def run
assert(instance.valid?, "Initial object ought to be valid!")
instance_eval(&proc)
end
def assert
end
undef_method :assert # Use the testcase's method
# Forward missing methods to the testcase if possible
def method_missing(sel, *args)
testcase.respond_to?(sel) ? testcase.send(sel, *args) : super(sel, *args)
end
end
def self.append_features(cls)
cls.send :include, InstanceMethods
class << cls
include ClassMethods
end
end
end
# for creating sets of data for tables generally. it enables you to
# take an array and create sections with it.
#
# a = [1,2,3,4,5,6,7,8,9,10]
# b = array_chop(a,3)
# b.inspect
# "[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]"
def array_chop( data, num )
res = Array.new
buf = data.to_a.reverse
( data.size / num ).times do |row|
tmp = Array.new
num.times do |col|
tmp << buf.pop
end
res << tmp
end
res << buf unless buf.size == 0
res
end
# config/environment.rb
require "#{RAILS_ROOT}/app/overrides/all"
# app/overrides/all.rb
Dir[ File.dirname( __FILE__ ) + "/**/*.rb" ].each { |file| require( file ) }
# app/overrides/active_record.rb
module ActiveRecord
class Errors
# ONLY RETURN THE 1ST ERROR FOR EACH ATTRIBUTE
def first_messages
list = []
first_messages = []
@errors.each_key do |attr|
@errors[ attr ].each do |msg|
next if msg.nil?
if attr == 'base'
unless list.include? attr
first_messages << msg
list << attr
end
else
unless list.include? attr
first_messages << @base.class.human_attribute_name( attr ) + ' ' + msg
list << attr
end
end
end
end
return first_messages
end
end
end
#!/usr/bin/env ruby
curl = `which curl 2>/dev/null`.chomp
validator = 'http://jigsaw.w3.org/css-validator/validator'
# All warnings, CSS2, all mediums
options = 'warning=2&profile=css2&usermedium=all'
base = File.expand_path("#{File.dirname(__FILE__)}/../../public/stylesheets")
# Got curl?
raise "Curl not found" if curl.empty?
# Get path to stylesheets
if ARGV.size > 0
base = ARGV.shift
end
# All css files or just one?
glob = base =~ /css$/ ? base : "#{base}/*.css"
# Do files
Dir.glob(glob) do |file|
next unless File.exists?( file )
errors, warnings = [ ], [ ]
# Send the css file to the validator
results = `#{curl} -s -F "file=@#{file}" -F "#{options}" #{validator}`
# Validator couldn't find the file
#
# OR the file didn't have _any_ valid css content before
# the errors <- little gotcha
#
results.grep(/No style sheet found/) do |line|
STDERR << "#{$&}\n"
exit
end
# Add new lines to <li></li> tags so grep can find them easier
results.gsub!(/\n/,'').gsub!(/<li>/,"\n<li>").gsub!(/<\/li>/,"</li>\n")
results.grep(/<li>.*<\/li>/) do |line|
# collect errors
line.grep(/<span class='error'>/) do |error|
errors << error.gsub!(/(<p>|<\/p>)/,"\n").gsub!(/<(.|\n)*?>/, '')
end
end
# collect warnings
results.grep(/<span class='warning'>/) do |line|
warnings << line.gsub!(/<(.|\n)*?>/, '')
end
# Dump information to STDERR
STDERR << "CSS File #{file}:\n\n"
{ 'Errors' => errors, 'Warnings' => warnings }.each do |k,v|
if v.empty?
STDERR << "No #{k.downcase} found\n---------------\n\n"
else
STDERR << "#{k} found:\n-------------\n\n"
v.each {|line| STDERR << line}
end
end
end
# Used to alternate row colors in a table
def alt( s = '', s2 = '2' )
@alt_state = true if @alt_state.nil?
@alt_state = !@alt_state
@alt_state ? s2 : s
end
require "date"
require "date2"
class DateCalc
######################################################
# Returns the date for a specified day on a numbered
# week as a date object. Such as finding the 3rd Wed
# in March, 2006.
#
# example: nth_weekday(2005,1,2,0)
# (2nd Sunday in January 2005) -> Jan 8th, 2005
#
# Returns: Date object
######################################################
def nth_weekday(year,month,week,day)
test_date = Date.new(year,month,1)
last_day = Date.new(test_date.year, test_date.month, -1).day
first_weekday = test_date.wday
offset = first_weekday - (day % 7)
weeks = (last_day) / 7
test_date + (week * 7) - offset
end
end