Hi, I am working on a testing framework for the software that my company writes. Our product is web based and After I run a RESTful request I want to process the results. I want to be able to have activerecord type validations in each command class so that after it is run the results are automatically tested against all the "validations". However, I am not sure how to do this. My code looks like this (simplified to show the important parts).
class CodesecureCommand
def execute
result = RestClient.post("http://#{codesecure.host_name_port}#{path}", post_data)
return parse(result) #parse simple returns a Hpricot document
end
end
class RunScan < CodesecureCommand
#What I have now
#I have to override the execute function so that it calls the local success method
#to see if it failed or not.
def execute()
result = super()
if success(result)
return true
else
end
end
def success(result)
result.search('div.transaction-message') do |message|
if message.innerHTML.scan(/Configure abuse setting for domain users successfully\./).length == 1
return true
end
end
end
#What I would like is to be able to call execute (without having to override it).
#then after it runs it calls back to this class to check
#if the regex matches the command was successful and returns true
test_success /regex/
#if test_success fails then these are called
#the idea being that I can use the regex to identify errors that happened then
#report them to the user
identify_error /regex/, "message"
identify_error /regex/, "message"
end
end
What I want is that after the execute method is called the test_success and identify_error are automatically called like the validations in activerecord. Can anybody tell me how to do this? Thanks
-
Without having looked much at your code, here's my take on implementing validation class methods:
module Validations def self.included(base) base.extend ClassMethods end def validate errors.clear self.class.validations.each {|validation| validation.call(self) } end def valid? validate errors.blank? end def errors @errors ||= {} end module ClassMethods def validations @validations ||= [] end def validates_presence_of(*attributes) validates_attributes(*attributes) do |instance, attribute, value, options| instance.errors[attribute] = "cant't be blank" if value.blank? end end def validates_format_of(*attributes) validates_attributes(*attributes) do |instance, attribute, value, options| instance.errors[attribute] = "is invalid" unless value =~ options[:with] end end def validates_attributes(*attributes, &proc) options = attributes.extract_options! validations << Proc.new { |instance| attributes.each {|attribute| proc.call(instance, attribute, instance.__send__(attribute), options) } } end end end
It assumes that ActiveSupport is around, which it is in a Rails environment. You might want to extend it to allow multiple errors per attribute, with
instance.errors[attribute] << "the message"
, but I left out obscurities like that in order to keep this short sample as simple as possible.Here's a short usage example:
class MyClass include Validations attr_accessor :foo validates_presence_of :foo validates_format_of :foo, :with => /^[a-z]+$/ end a = MyClass.new puts a.valid? # => false a.foo = "letters" puts a.valid? # => true a.foo = "Oh crap$(!)*#" puts a.valid? # => false
Josh Moore : Thanks for the answer that is what I am looking for thanks. One question, what does it require ActiveSupport? thanks.August Lilleaas : It uses `Hash#blank?` (in the `valid?` method). But that's about it, heh. Shouldn't be too hard to drop active_support. I just assumed it was already there, because you're in the rails context anyways.The Wicked Flea : It also uses Array#extract_options!, but that's simple enough to duplicate/extract.August Lilleaas : Yes indeed, could have been `options = attributes.last.is_a?(Hash) ? attributes.pop : {}`. -
You want Validatable:
sudo gem install validatable
class Person include Validatable validates_presence_of :name attr_accessor :name end
Also, Validatable does not have a dependency on ActiveSupport.
0 comments:
Post a Comment