Permalink
Browse files

Rely on ActiveModel for translation and error messages.

  • Loading branch information...
1 parent 72beecb commit c37949dd8a85c04ee978124dc7886e934a61eb28 @josevalim josevalim committed Dec 27, 2009
Showing with 45 additions and 174 deletions.
  1. +4 −3 lib/mail_form.rb
  2. +10 −20 lib/mail_form/base.rb
  3. +0 −59 lib/mail_form/errors.rb
  4. +30 −6 test/base_test.rb
  5. +0 −85 test/errors_test.rb
  6. +1 −1 test/notifier_test.rb
View
@@ -1,6 +1,6 @@
+require 'active_model'
require 'mail_form/base'
require 'mail_form/dsl'
-require 'mail_form/errors'
require 'mail_form/notifier'
class MailForm
@@ -25,8 +25,9 @@ class MailForm
headers({})
sender {|c| c.email }
- subject{|c| c.class.human_name }
+ subject{|c| c.class.model_name.human }
template 'default'
end
-MailForm::Notifier.template_root = File.join(File.dirname(__FILE__), '..', 'views')
+I18n.load_path.unshift File.expand_path('mail_form/locales/en.yml', File.dirname(__FILE__))
+MailForm::Notifier.template_root = File.expand_path('../views', File.dirname(__FILE__))
View
@@ -1,4 +1,9 @@
class MailForm
+ extend ActiveModel::Naming
+ extend ActiveModel::Translation
+ include ActiveModel::Validations
+ include ActiveModel::Conversion
+
attr_accessor :request
# Initialize assigning the parameters given as hash (just as in ActiveRecord).
@@ -93,34 +98,19 @@ def deliver(run_validations=true)
end
alias :save :deliver
- # Add a human attribute name interface on top of I18n. If email is received as
- # attribute, it will look for a translated name on:
- #
- # mail_form:
- # attributes:
- # email: E-mail
- #
- def self.human_attribute_name(attribute, options={})
- I18n.translate("attributes.#{attribute}", options.merge(:default => attribute.to_s.humanize, :scope => [:mail_form]))
+ def self.i18n_scope
+ :mail_form
end
- # Add a human name interface on top of I18n. If you have a model named
- # MailForm, it will search for the localized name on:
- #
- # mail_form:
- # models:
- # contact_form: Contact form
- #
- def self.human_name(options={})
- underscored = self.name.demodulize.underscore
- I18n.translate("models.#{underscored}", options.merge(:default => underscored.humanize, :scope => [:mail_form]))
+ def self.lookup_ancestors
+ super - [MailForm]
end
# Return the errors in this form. The object returned as the same API as the
# ActiveRecord one.
#
def errors
- @errors ||= MailForm::Errors.new(self)
+ @errors ||= ActiveModel::Errors.new(self)
end
end
@@ -1,59 +0,0 @@
-# Provides an Errors class similar with ActiveRecord ones.
-#
-# class ContactForm < MailForm
-# attributes :name, :validate => true
-# attributes :email, :validate => /^([^@]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
-# attributes :message
-# attributes :nickname, :captcha => true
-# end
-#
-# When validating an attribute name as above, it will search for messages in
-# the following order:
-#
-# mail_form.messages.name
-# mail_form.messages.blank
-#
-# When validating email, it will search for:
-#
-# mail_form.messages.name
-# mail_form.messages.invalid
-#
-# If the message is not available, it will output: "can't be blank" in the first
-# case and "is invalid" in the second.
-#
-class MailForm
- class Errors < Hash
-
- def initialize(base, *args)
- @base = base
- super(*args)
- end
-
- alias :add :store
- alias :count :size
- alias :get :[]
-
- def on(attribute)
- attribute = attribute.to_sym
- return nil unless get(attribute)
-
- generate_message_for(attribute, get(attribute))
- end
- alias :[] :on
-
- def full_messages
- map do |attribute, message|
- next if message.nil?
- attribute = attribute.to_sym
- "#{@base.class.human_attribute_name(attribute)} #{generate_message_for(attribute, message)}"
- end.compact.reverse
- end
-
- protected
-
- def generate_message_for(attribute, message)
- I18n.t(attribute, :default => [ message, DEFAULT_MESSAGES[message] ], :scope => [:mail_form, :messages])
- end
-
- end
-end
View
@@ -37,8 +37,9 @@ def test_is_not_valid_when_validatable_attributes_are_blank
assert !form.valid?
assert form.invalid?
- assert_equal(2, form.errors.count)
- assert_equal({:email=>:blank, :name=>:blank}, form.errors)
+ assert_equal 2, form.errors.count
+ assert_equal ["can't be blank"], form.errors[:email]
+ assert_equal ["can't be blank"], form.errors[:name]
end
def test_is_not_valid_when_validatable_regexp_does_not_match
@@ -47,7 +48,7 @@ def test_is_not_valid_when_validatable_regexp_does_not_match
assert form.invalid?
assert_equal(1, form.errors.count)
- assert_equal({:email=>:invalid}, form.errors)
+ assert_equal ["is invalid"], form.errors[:email]
end
def test_is_valid_when_validatable_attributes_are_valid
@@ -86,23 +87,46 @@ def test_deliver_is_true_when_is_not_spam_and_valid
end
def test_human_name_returns_a_humanized_name
- assert_equal 'Contact form', ContactForm.human_name
+ assert_equal 'Contact form', ContactForm.model_name.human
end
def test_human_name_can_be_localized
I18n.backend.store_translations(:en, :mail_form => { :models => { :contact_form => 'Formulário de contato' } })
- assert_equal 'Formulário de contato', ContactForm.human_name
+ assert_equal 'Formulário de contato', ContactForm.model_name.human
end
def test_human_attribute_name_returns_a_humanized_attribute
assert_equal 'Message', ContactForm.human_attribute_name(:message)
end
def test_human_attribute_name_can_be_localized
- I18n.backend.store_translations(:en, :mail_form => { :attributes => { :message => 'Mensagem' } })
+ I18n.backend.store_translations(:en, :mail_form => { :attributes => { :contact_form => { :message => 'Mensagem' } } })
assert_equal 'Mensagem', ContactForm.human_attribute_name(:message)
end
+ def test_activemodel_linked_errors
+ form = ContactForm.new(:email => 'not_valid')
+ form.valid?
+ assert_equal ["can't be blank"], form.errors[:name]
+ assert_equal ["is invalid"], form.errors[:email]
+ assert_equal [], form.errors[:message]
+ end
+
+ def test_activemodel_errors_lookups_model_keys
+ I18n.backend.store_translations(:en, :mail_form => { :errors => { :models => { :contact_form =>
+ { :attributes => { :email => { :invalid => 'fill in the email' },
+ :name => { :blank => 'fill in the name' } }
+ }
+ }}})
+
+ form = ContactForm.new(:email => 'not_valid')
+ form.valid?
+
+ assert_equal ["fill in the name"], form.errors[:name]
+ assert_equal ["fill in the email"], form.errors[:email]
+ assert_equal [], form.errors[:message]
+ end
+
def teardown
I18n.reload!
end
View
@@ -1,85 +0,0 @@
-require File.dirname(__FILE__) + '/test_helper'
-
-class MailFormErrorsTest < ActiveSupport::TestCase
-
- def test_errors_respond_to_some_hash_methods
- assert ContactForm.new.errors.respond_to?(:each)
- assert ContactForm.new.errors.respond_to?(:each_pair)
- assert ContactForm.new.errors.respond_to?(:size)
- end
-
- def test_count_is_an_alias_to_size
- errors = ContactForm.new.errors
- assert_equal errors.size, errors.count
- end
-
- def test_on_returns_the_message_in_the_given_attribute
- form = ContactForm.new(:email => 'not_valid')
- form.valid?
- assert_equal "can't be blank", form.errors.on(:name)
- assert_equal "is invalid", form.errors.on(:email)
- assert_equal nil, form.errors.on(:message)
- end
-
- def test_on_returns_a_default_localized_message_in_the_given_attribute
- I18n.backend.store_translations(:en, :mail_form => { :messages => { :invalid => 'is not valid', :blank => 'should be filled' } })
-
- form = ContactForm.new(:email => 'not_valid')
- form.valid?
-
- assert_equal "should be filled", form.errors.on(:name)
- assert_equal "is not valid", form.errors.on(:email)
- assert_equal nil, form.errors.on(:message)
- end
-
- def test_on_returns_an_attribute_localized_message_in_the_given_attribute
- I18n.backend.store_translations(:en, :mail_form => { :messages => { :email => 'fill in the email', :name => 'fill in the name' } })
-
- form = ContactForm.new(:email => 'not_valid')
- form.valid?
-
- assert_equal "fill in the name", form.errors.on(:name)
- assert_equal "fill in the email", form.errors.on(:email)
- assert_equal nil, form.errors.on(:message)
- end
-
- def test_array_like_option_acts_as_an_alias_for_on
- form = ContactForm.new(:email => 'not_valid')
- form.valid?
- assert_equal "can't be blank", form.errors[:name]
- assert_equal form.errors.on(:name), form.errors[:name]
- assert_equal "is invalid", form.errors[:email]
- assert_equal form.errors.on(:email), form.errors[:email]
- assert_equal nil, form.errors[:message]
- end
-
- def test_get_returns_the_real_value_in_the_given_attribute
- form = ContactForm.new(:email => 'not_valid')
- form.valid?
- assert_equal :blank, form.errors.get(:name)
- assert_equal :invalid, form.errors.get(:email)
- assert_equal nil, form.errors.get(:message)
- end
-
- def test_full_messages
- form = ContactForm.new(:email => 'not_valid')
- form.valid?
-
- assert form.errors.full_messages.include?("Name can't be blank")
- assert form.errors.full_messages.include?("Email is invalid")
- end
-
- def test_full_localized_messages
- I18n.backend.store_translations(:en, :mail_form => { :messages => { :email => 'is not valid', :blank => 'should be filled' }, :attributes => { :email => 'E-mail' } })
-
- form = ContactForm.new(:email => 'not_valid')
- form.valid?
-
- assert form.errors.full_messages.include?("Name should be filled")
- assert form.errors.full_messages.include?("E-mail is not valid")
- end
-
- def teardown
- I18n.reload!
- end
-end
@@ -83,7 +83,7 @@ def test_body_contains_attributes_names
end
def test_body_contains_localized_attributes_names
- I18n.backend.store_translations(:en, :mail_form => { :attributes => { :message => 'Sent message' } })
+ I18n.backend.store_translations(:en, :mail_form => { :attributes => { :contact_form => { :message => 'Sent message' } } })
@form.deliver
assert_match /Sent message:/, ActionMailer::Base.deliveries.first.body
assert_no_match /Message:/, ActionMailer::Base.deliveries.first.body

0 comments on commit c37949d

Please sign in to comment.