From 2e37effd7203cad84459661e11db2be44586cb4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?=
Date: Sat, 17 Oct 2009 12:54:03 -0300
Subject: Unify class_inheritable_accessor and extlib_inheritable_accessor and
allow responder to be set in the class level.
---
.../lib/action_controller/metal/mime_responds.rb | 9 +++----
actionpack/test/controller/mime_responds_test.rb | 8 +++++++
.../core_ext/class/inheritable_attributes.rb | 28 ++++++++++++----------
.../active_support/core_ext/object/duplicable.rb | 8 ++++++-
4 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index 3026067868..468c5f4fae 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -3,7 +3,8 @@ module ActionController #:nodoc:
extend ActiveSupport::Concern
included do
- class_inheritable_reader :mimes_for_respond_to
+ extlib_inheritable_accessor :responder, :mimes_for_respond_to, :instance_writer => false
+ self.responder = ActionController::Responder
clear_respond_to
end
@@ -46,7 +47,7 @@ module ActionController #:nodoc:
# Clear all mimes in respond_to.
#
def clear_respond_to
- write_inheritable_attribute(:mimes_for_respond_to, ActiveSupport::OrderedHash.new)
+ self.mimes_for_respond_to = ActiveSupport::OrderedHash.new
end
end
@@ -221,10 +222,6 @@ module ActionController #:nodoc:
end
end
- def responder
- ActionController::Responder
- end
-
protected
# Collect mimes declared in the class method respond_to valid for the
diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb
index a79648396c..b070f925d4 100644
--- a/actionpack/test/controller/mime_responds_test.rb
+++ b/actionpack/test/controller/mime_responds_test.rb
@@ -760,6 +760,14 @@ class RespondWithControllerTest < ActionController::TestCase
assert_equal "Resource name is david", @response.body
end
+ def test_using_resource_with_responder
+ RespondWithController.responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" }
+ get :using_resource
+ assert_equal "Resource name is david", @response.body
+ ensure
+ RespondWithController.responder = ActionController::Responder
+ end
+
def test_not_acceptable
@request.accept = "application/xml"
get :using_defaults
diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
index 8bac2dff19..d8e9768a5e 100644
--- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
@@ -10,16 +10,19 @@ end
# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
class Class # :nodoc:
def class_inheritable_reader(*syms)
+ options = syms.extract_options!
syms.each do |sym|
next if sym.is_a?(Hash)
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
- def self.#{sym} # def self.after_add
- read_inheritable_attribute(:#{sym}) # read_inheritable_attribute(:after_add)
- end # end
-
- def #{sym} # def after_add
- self.class.#{sym} # self.class.after_add
- end # end
+ def self.#{sym} # def self.after_add
+ read_inheritable_attribute(:#{sym}) # read_inheritable_attribute(:after_add)
+ end # end
+ #
+ #{" #
+ def #{sym} # def after_add
+ self.class.#{sym} # self.class.after_add
+ end # end
+ " unless options[:instance_reader] == false } # # the reader above is generated unless options[:instance_reader] == false
EOS
end
end
@@ -156,7 +159,7 @@ class Class
# moving on). In particular, this makes the return value of this function
# less useful.
def extlib_inheritable_reader(*ivars)
- instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
+ options = ivars.extract_options!
ivars.each do |ivar|
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -164,10 +167,10 @@ class Class
return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
ivar = superclass.#{ivar}
return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
- @#{ivar} = ivar && !ivar.is_a?(Module) && !ivar.is_a?(Numeric) && !ivar.is_a?(TrueClass) && !ivar.is_a?(FalseClass) ? ivar.dup : ivar
+ @#{ivar} = ivar.duplicable? ? ivar.dup : ivar
end
RUBY
- unless instance_reader == false
+ unless options[:instance_reader] == false
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{ivar}
self.class.#{ivar}
@@ -190,14 +193,15 @@ class Class
# @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
# class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
def extlib_inheritable_writer(*ivars)
- instance_writer = ivars.pop[:writer] if ivars.last.is_a?(Hash)
+ options = ivars.extract_options!
+
ivars.each do |ivar|
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def self.#{ivar}=(obj)
@#{ivar} = obj
end
RUBY
- unless instance_writer == false
+ unless options[:instance_writer] == false
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{ivar}=(obj) self.class.#{ivar} = obj end
RUBY
diff --git a/activesupport/lib/active_support/core_ext/object/duplicable.rb b/activesupport/lib/active_support/core_ext/object/duplicable.rb
index 1722726ca2..a2d4d50076 100644
--- a/activesupport/lib/active_support/core_ext/object/duplicable.rb
+++ b/activesupport/lib/active_support/core_ext/object/duplicable.rb
@@ -1,6 +1,6 @@
class Object
# Can you safely .dup this object?
- # False for nil, false, true, symbols, numbers, and class objects; true otherwise.
+ # False for nil, false, true, symbols, numbers, class and module objects; true otherwise.
def duplicable?
true
end
@@ -41,3 +41,9 @@ class Class #:nodoc:
false
end
end
+
+class Module #:nodoc:
+ def duplicable?
+ false
+ end
+end
--
cgit v1.2.3
From cb873026898badc5c3dc61a95a08051cf218251f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?=
Date: Sat, 17 Oct 2009 13:03:28 -0300
Subject: Bring agnosticism to error_messages_for.
---
.../lib/action_view/helpers/active_model_helper.rb | 16 +-
actionpack/lib/action_view/locale/en.yml | 4 +-
.../test/template/active_model_helper_i18n_test.rb | 42 +++
.../test/template/active_model_helper_test.rb | 314 +++++++++++++++++++++
.../template/active_record_helper_i18n_test.rb | 51 ----
.../test/template/active_record_helper_test.rb | 314 ---------------------
6 files changed, 368 insertions(+), 373 deletions(-)
create mode 100644 actionpack/test/template/active_model_helper_i18n_test.rb
create mode 100644 actionpack/test/template/active_model_helper_test.rb
delete mode 100644 actionpack/test/template/active_record_helper_i18n_test.rb
delete mode 100644 actionpack/test/template/active_record_helper_test.rb
diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb
index 7cc1e48572..3c398fe4da 100644
--- a/actionpack/lib/action_view/helpers/active_model_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_model_helper.rb
@@ -202,8 +202,8 @@ module ActionView
end
objects.compact!
-
count = objects.inject(0) {|sum, object| sum + object.errors.count }
+
unless count.zero?
html = {}
[:id, :class].each do |key|
@@ -216,16 +216,20 @@ module ActionView
end
options[:object_name] ||= params.first
- I18n.with_options :locale => options[:locale], :scope => [:activerecord, :errors, :template] do |locale|
+ I18n.with_options :locale => options[:locale], :scope => [:activemodel, :errors, :template] do |locale|
header_message = if options.include?(:header_message)
options[:header_message]
else
- object_name = options[:object_name].to_s.gsub('_', ' ')
- object_name = I18n.t(options[:object_name].to_s, :default => object_name, :scope => [:activerecord, :models], :count => 1)
- locale.t :header, :count => count, :model => object_name
+ locale.t :header, :count => count, :model => options[:object_name].to_s.gsub('_', ' ')
end
+
message = options.include?(:message) ? options[:message] : locale.t(:body)
- error_messages = objects.sum {|object| object.errors.full_messages.map {|msg| content_tag(:li, ERB::Util.html_escape(msg)) } }.join
+
+ error_messages = objects.sum do |object|
+ object.errors.full_messages.map do |msg|
+ content_tag(:li, ERB::Util.html_escape(msg))
+ end
+ end.join
contents = ''
contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank?
diff --git a/actionpack/lib/action_view/locale/en.yml b/actionpack/lib/action_view/locale/en.yml
index 84d94fd700..5e2a92b89a 100644
--- a/actionpack/lib/action_view/locale/en.yml
+++ b/actionpack/lib/action_view/locale/en.yml
@@ -102,7 +102,7 @@
minute: "Minute"
second: "Seconds"
- activerecord:
+ activemodel:
errors:
template:
header:
@@ -114,4 +114,4 @@
support:
select:
# default value for :prompt => true in FormOptionsHelper
- prompt: "Please select"
\ No newline at end of file
+ prompt: "Please select"
diff --git a/actionpack/test/template/active_model_helper_i18n_test.rb b/actionpack/test/template/active_model_helper_i18n_test.rb
new file mode 100644
index 0000000000..2465444fc5
--- /dev/null
+++ b/actionpack/test/template/active_model_helper_i18n_test.rb
@@ -0,0 +1,42 @@
+require 'abstract_unit'
+
+class ActiveModelHelperI18nTest < Test::Unit::TestCase
+ include ActionView::Context
+ include ActionView::Helpers::ActiveModelHelper
+
+ attr_reader :request
+
+ def setup
+ @object = stub :errors => stub(:count => 1, :full_messages => ['full_messages'])
+ @object.stubs :to_model => @object
+ @object.stubs :class => stub(:model_name => stub(:human => ""))
+
+ @object_name = 'book_seller'
+ @object_name_without_underscore = 'book seller'
+
+ stubs(:content_tag).returns 'content_tag'
+
+ I18n.stubs(:t).with(:'header', :locale => 'en', :scope => [:activemodel, :errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved"
+ I18n.stubs(:t).with(:'body', :locale => 'en', :scope => [:activemodel, :errors, :template]).returns 'There were problems with the following fields:'
+ end
+
+ def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message
+ I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activemodel, :errors, :template], :count => 1, :model => '').never
+ error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en')
+ end
+
+ def test_error_messages_for_given_no_header_option_it_translates_header_message
+ I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activemodel, :errors, :template], :count => 1, :model => '').returns 'header message'
+ error_messages_for(:object => @object, :locale => 'en')
+ end
+
+ def test_error_messages_for_given_a_message_option_it_does_not_translate_message
+ I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activemodel, :errors, :template]).never
+ error_messages_for(:object => @object, :message => 'message', :locale => 'en')
+ end
+
+ def test_error_messages_for_given_no_message_option_it_translates_message
+ I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activemodel, :errors, :template]).returns 'There were problems with the following fields:'
+ error_messages_for(:object => @object, :locale => 'en')
+ end
+end
diff --git a/actionpack/test/template/active_model_helper_test.rb b/actionpack/test/template/active_model_helper_test.rb
new file mode 100644
index 0000000000..3e01ae78c3
--- /dev/null
+++ b/actionpack/test/template/active_model_helper_test.rb
@@ -0,0 +1,314 @@
+require 'abstract_unit'
+
+class ActiveModelHelperTest < ActionView::TestCase
+ tests ActionView::Helpers::ActiveModelHelper
+
+ silence_warnings do
+ class Post < Struct.new(:title, :author_name, :body, :secret, :written_on)
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+ end
+
+ class User < Struct.new(:email)
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+ end
+
+ class Column < Struct.new(:type, :name, :human_name)
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+ end
+ end
+
+ class DirtyPost
+ class Errors
+ def empty?
+ false
+ end
+
+ def count
+ 1
+ end
+
+ def full_messages
+ ["Author name can't be empty"]
+ end
+
+ def [](field)
+ ["can't be empty"]
+ end
+ end
+
+ def errors
+ Errors.new
+ end
+ end
+
+ def setup_post
+ @post = Post.new
+ def @post.errors
+ Class.new {
+ def [](field)
+ case field.to_s
+ when "author_name"
+ ["can't be empty"]
+ when "body"
+ ['foo']
+ else
+ []
+ end
+ end
+ def empty?() false end
+ def count() 1 end
+ def full_messages() [ "Author name can't be empty" ] end
+ }.new
+ end
+
+ def @post.new_record?() true end
+ def @post.to_param() nil end
+
+ def @post.column_for_attribute(attr_name)
+ Post.content_columns.select { |column| column.name == attr_name }.first
+ end
+
+ silence_warnings do
+ def Post.content_columns() [ Column.new(:string, "title", "Title"), Column.new(:text, "body", "Body") ] end
+ end
+
+ @post.title = "Hello World"
+ @post.author_name = ""
+ @post.body = "Back to the hill and over it again!"
+ @post.secret = 1
+ @post.written_on = Date.new(2004, 6, 15)
+ end
+
+ def setup_user
+ @user = User.new
+ def @user.errors
+ Class.new {
+ def [](field) field == "email" ? ['nonempty'] : [] end
+ def empty?() false end
+ def count() 1 end
+ def full_messages() [ "User email can't be empty" ] end
+ }.new
+ end
+
+ def @user.new_record?() true end
+ def @user.to_param() nil end
+
+ def @user.column_for_attribute(attr_name)
+ User.content_columns.select { |column| column.name == attr_name }.first
+ end
+
+ silence_warnings do
+ def User.content_columns() [ Column.new(:string, "email", "Email") ] end
+ end
+
+ @user.email = ""
+ end
+
+ def protect_against_forgery?
+ @protect_against_forgery ? true : false
+ end
+ attr_accessor :request_forgery_protection_token, :form_authenticity_token
+
+ def setup
+ super
+ setup_post
+ setup_user
+
+ @response = ActionController::TestResponse.new
+
+ @controller = Object.new
+ def @controller.url_for(options)
+ options = options.symbolize_keys
+
+ [options[:action], options[:id].to_param].compact.join('/')
+ end
+ end
+
+ def test_generic_input_tag
+ assert_dom_equal(
+ %(), input("post", "title")
+ )
+ end
+
+ def test_text_area_with_errors
+ assert_dom_equal(
+ %(),
+ text_area("post", "body")
+ )
+ end
+
+ def test_text_field_with_errors
+ assert_dom_equal(
+ %(),
+ text_field("post", "author_name")
+ )
+ end
+
+ def test_form_with_string
+ assert_dom_equal(
+ %(
),
+ form("post")
+ )
+
+ silence_warnings do
+ class << @post
+ def new_record?() false end
+ def to_param() id end
+ def id() 1 end
+ end
+ end
+
+ assert_dom_equal(
+ %(),
+ form("post")
+ )
+ end
+
+ def test_form_with_protect_against_forgery
+ @protect_against_forgery = true
+ @request_forgery_protection_token = 'authenticity_token'
+ @form_authenticity_token = '123'
+ assert_dom_equal(
+ %(),
+ form("post")
+ )
+ end
+
+ def test_form_with_method_option
+ assert_dom_equal(
+ %(),
+ form("post", :method=>'get')
+ )
+ end
+
+ def test_form_with_action_option
+ output_buffer << form("post", :action => "sign")
+ assert_select "form[action=sign]" do |form|
+ assert_select "input[type=submit][value=Sign]"
+ end
+ end
+
+ def test_form_with_date
+ silence_warnings do
+ def Post.content_columns() [ Column.new(:date, "written_on", "Written on") ] end
+ end
+
+ assert_dom_equal(
+ %(),
+ form("post")
+ )
+ end
+
+ def test_form_with_datetime
+ silence_warnings do
+ def Post.content_columns() [ Column.new(:datetime, "written_on", "Written on") ] end
+ end
+ @post.written_on = Time.gm(2004, 6, 15, 16, 30)
+
+ assert_dom_equal(
+ %(),
+ form("post")
+ )
+ end
+
+ def test_error_for_block
+ assert_dom_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post")
+ assert_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post", :class => "errorDeathByClass", :id => "errorDeathById", :header_tag => "h1")
+ assert_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post", :class => nil, :id => "errorDeathById", :header_tag => "h1")
+ assert_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post", :class => "errorDeathByClass", :id => nil, :header_tag => "h1")
+ end
+
+ def test_error_messages_for_escapes_html
+ @dirty_post = DirtyPost.new
+ assert_dom_equal %(1 error prohibited this dirty post from being saved
There were problems with the following fields:
- Author name can't be <em>empty</em>
), error_messages_for("dirty_post")
+ end
+
+ def test_error_messages_for_handles_nil
+ assert_equal "", error_messages_for("notthere")
+ end
+
+ def test_error_message_on_escapes_html
+ @dirty_post = DirtyPost.new
+ assert_dom_equal "can't be <em>empty</em>
", error_message_on(:dirty_post, :author_name)
+ end
+
+ def test_error_message_on_handles_nil
+ assert_equal "", error_message_on("notthere", "notthere")
+ end
+
+ def test_error_message_on
+ assert_dom_equal "can't be empty
", error_message_on(:post, :author_name)
+ end
+
+ def test_error_message_on_no_instance_variable
+ other_post = @post
+ assert_dom_equal "can't be empty
", error_message_on(other_post, :author_name)
+ end
+
+ def test_error_message_on_with_options_hash
+ assert_dom_equal "beforecan't be emptyafter
", error_message_on(:post, :author_name, :css_class => 'differentError', :prepend_text => 'before', :append_text => 'after')
+ end
+
+ def test_error_messages_for_many_objects
+ assert_dom_equal %(2 errors prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
- User email can't be empty
), error_messages_for("post", "user")
+
+ # reverse the order, error order changes and so does the title
+ assert_dom_equal %(2 errors prohibited this user from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for("user", "post")
+
+ # add the default to put post back in the title
+ assert_dom_equal %(2 errors prohibited this post from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for("user", "post", :object_name => "post")
+
+ # symbols work as well
+ assert_dom_equal %(2 errors prohibited this post from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :object_name => :post)
+
+ # any default works too
+ assert_dom_equal %(2 errors prohibited this monkey from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :object_name => "monkey")
+
+ # should space object name
+ assert_dom_equal %(2 errors prohibited this chunky bacon from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :object_name => "chunky_bacon")
+
+ # hide header and explanation messages with nil or empty string
+ assert_dom_equal %(- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :header_message => nil, :message => "")
+
+ # override header and explanation messages
+ header_message = "Yikes! Some errors"
+ message = "Please fix the following fields and resubmit:"
+ assert_dom_equal %(#{header_message}
#{message}
- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :header_message => header_message, :message => message)
+ end
+
+ def test_error_messages_for_non_instance_variable
+ actual_user = @user
+ actual_post = @post
+ @user = nil
+ @post = nil
+
+ #explicitly set object
+ assert_dom_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post", :object => actual_post)
+
+ #multiple objects
+ assert_dom_equal %(2 errors prohibited this user from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for("user", "post", :object => [actual_user, actual_post])
+
+ #nil object
+ assert_equal '', error_messages_for('user', :object => nil)
+ end
+
+ def test_error_messages_for_model_objects
+ error = error_messages_for(@post)
+ assert_dom_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
),
+ error
+
+ error = error_messages_for(@user, @post)
+ assert_dom_equal %(2 errors prohibited this user from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
),
+ error
+ end
+
+ def test_form_with_string_multipart
+ assert_dom_equal(
+ %(),
+ form("post", :multipart => true)
+ )
+ end
+end
diff --git a/actionpack/test/template/active_record_helper_i18n_test.rb b/actionpack/test/template/active_record_helper_i18n_test.rb
deleted file mode 100644
index 047f81be29..0000000000
--- a/actionpack/test/template/active_record_helper_i18n_test.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-require 'abstract_unit'
-
-class ActiveRecordHelperI18nTest < Test::Unit::TestCase
- include ActionView::Context
- include ActionView::Helpers::ActiveModelHelper
-
- attr_reader :request
-
- def setup
- @object = stub :errors => stub(:count => 1, :full_messages => ['full_messages'])
- @object.stubs :to_model => @object
- @object.stubs :class => stub(:model_name => stub(:human => ""))
-
- @object_name = 'book_seller'
- @object_name_without_underscore = 'book seller'
-
- stubs(:content_tag).returns 'content_tag'
-
- I18n.stubs(:t).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved"
- I18n.stubs(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:'
- end
-
- def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message
- I18n.expects(:translate).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').never
- error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en')
- end
-
- def test_error_messages_for_given_no_header_option_it_translates_header_message
- I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns 'header message'
- I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
- error_messages_for(:object => @object, :locale => 'en')
- end
-
- def test_error_messages_for_given_a_message_option_it_does_not_translate_message
- I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).never
- I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
- error_messages_for(:object => @object, :message => 'message', :locale => 'en')
- end
-
- def test_error_messages_for_given_no_message_option_it_translates_message
- I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:'
- I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
- error_messages_for(:object => @object, :locale => 'en')
- end
-
- def test_error_messages_for_given_object_name_it_translates_object_name
- I18n.expects(:t).with(:header, :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => @object_name_without_underscore).returns "1 error prohibited this #{@object_name_without_underscore} from being saved"
- I18n.expects(:t).with(@object_name, :default => @object_name_without_underscore, :count => 1, :scope => [:activerecord, :models]).once.returns @object_name_without_underscore
- error_messages_for(:object => @object, :locale => 'en', :object_name => @object_name)
- end
-end
diff --git a/actionpack/test/template/active_record_helper_test.rb b/actionpack/test/template/active_record_helper_test.rb
deleted file mode 100644
index c149070f2a..0000000000
--- a/actionpack/test/template/active_record_helper_test.rb
+++ /dev/null
@@ -1,314 +0,0 @@
-require 'abstract_unit'
-
-class ActiveRecordHelperTest < ActionView::TestCase
- tests ActionView::Helpers::ActiveModelHelper
-
- silence_warnings do
- class Post < Struct.new(:title, :author_name, :body, :secret, :written_on)
- extend ActiveModel::Naming
- include ActiveModel::Conversion
- end
-
- class User < Struct.new(:email)
- extend ActiveModel::Naming
- include ActiveModel::Conversion
- end
-
- class Column < Struct.new(:type, :name, :human_name)
- extend ActiveModel::Naming
- include ActiveModel::Conversion
- end
- end
-
- class DirtyPost
- class Errors
- def empty?
- false
- end
-
- def count
- 1
- end
-
- def full_messages
- ["Author name can't be empty"]
- end
-
- def [](field)
- ["can't be empty"]
- end
- end
-
- def errors
- Errors.new
- end
- end
-
- def setup_post
- @post = Post.new
- def @post.errors
- Class.new {
- def [](field)
- case field.to_s
- when "author_name"
- ["can't be empty"]
- when "body"
- ['foo']
- else
- []
- end
- end
- def empty?() false end
- def count() 1 end
- def full_messages() [ "Author name can't be empty" ] end
- }.new
- end
-
- def @post.new_record?() true end
- def @post.to_param() nil end
-
- def @post.column_for_attribute(attr_name)
- Post.content_columns.select { |column| column.name == attr_name }.first
- end
-
- silence_warnings do
- def Post.content_columns() [ Column.new(:string, "title", "Title"), Column.new(:text, "body", "Body") ] end
- end
-
- @post.title = "Hello World"
- @post.author_name = ""
- @post.body = "Back to the hill and over it again!"
- @post.secret = 1
- @post.written_on = Date.new(2004, 6, 15)
- end
-
- def setup_user
- @user = User.new
- def @user.errors
- Class.new {
- def [](field) field == "email" ? ['nonempty'] : [] end
- def empty?() false end
- def count() 1 end
- def full_messages() [ "User email can't be empty" ] end
- }.new
- end
-
- def @user.new_record?() true end
- def @user.to_param() nil end
-
- def @user.column_for_attribute(attr_name)
- User.content_columns.select { |column| column.name == attr_name }.first
- end
-
- silence_warnings do
- def User.content_columns() [ Column.new(:string, "email", "Email") ] end
- end
-
- @user.email = ""
- end
-
- def protect_against_forgery?
- @protect_against_forgery ? true : false
- end
- attr_accessor :request_forgery_protection_token, :form_authenticity_token
-
- def setup
- super
- setup_post
- setup_user
-
- @response = ActionController::TestResponse.new
-
- @controller = Object.new
- def @controller.url_for(options)
- options = options.symbolize_keys
-
- [options[:action], options[:id].to_param].compact.join('/')
- end
- end
-
- def test_generic_input_tag
- assert_dom_equal(
- %(), input("post", "title")
- )
- end
-
- def test_text_area_with_errors
- assert_dom_equal(
- %(),
- text_area("post", "body")
- )
- end
-
- def test_text_field_with_errors
- assert_dom_equal(
- %(),
- text_field("post", "author_name")
- )
- end
-
- def test_form_with_string
- assert_dom_equal(
- %(),
- form("post")
- )
-
- silence_warnings do
- class << @post
- def new_record?() false end
- def to_param() id end
- def id() 1 end
- end
- end
-
- assert_dom_equal(
- %(),
- form("post")
- )
- end
-
- def test_form_with_protect_against_forgery
- @protect_against_forgery = true
- @request_forgery_protection_token = 'authenticity_token'
- @form_authenticity_token = '123'
- assert_dom_equal(
- %(),
- form("post")
- )
- end
-
- def test_form_with_method_option
- assert_dom_equal(
- %(),
- form("post", :method=>'get')
- )
- end
-
- def test_form_with_action_option
- output_buffer << form("post", :action => "sign")
- assert_select "form[action=sign]" do |form|
- assert_select "input[type=submit][value=Sign]"
- end
- end
-
- def test_form_with_date
- silence_warnings do
- def Post.content_columns() [ Column.new(:date, "written_on", "Written on") ] end
- end
-
- assert_dom_equal(
- %(),
- form("post")
- )
- end
-
- def test_form_with_datetime
- silence_warnings do
- def Post.content_columns() [ Column.new(:datetime, "written_on", "Written on") ] end
- end
- @post.written_on = Time.gm(2004, 6, 15, 16, 30)
-
- assert_dom_equal(
- %(),
- form("post")
- )
- end
-
- def test_error_for_block
- assert_dom_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post")
- assert_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post", :class => "errorDeathByClass", :id => "errorDeathById", :header_tag => "h1")
- assert_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post", :class => nil, :id => "errorDeathById", :header_tag => "h1")
- assert_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post", :class => "errorDeathByClass", :id => nil, :header_tag => "h1")
- end
-
- def test_error_messages_for_escapes_html
- @dirty_post = DirtyPost.new
- assert_dom_equal %(1 error prohibited this dirty post from being saved
There were problems with the following fields:
- Author name can't be <em>empty</em>
), error_messages_for("dirty_post")
- end
-
- def test_error_messages_for_handles_nil
- assert_equal "", error_messages_for("notthere")
- end
-
- def test_error_message_on_escapes_html
- @dirty_post = DirtyPost.new
- assert_dom_equal "can't be <em>empty</em>
", error_message_on(:dirty_post, :author_name)
- end
-
- def test_error_message_on_handles_nil
- assert_equal "", error_message_on("notthere", "notthere")
- end
-
- def test_error_message_on
- assert_dom_equal "can't be empty
", error_message_on(:post, :author_name)
- end
-
- def test_error_message_on_no_instance_variable
- other_post = @post
- assert_dom_equal "can't be empty
", error_message_on(other_post, :author_name)
- end
-
- def test_error_message_on_with_options_hash
- assert_dom_equal "beforecan't be emptyafter
", error_message_on(:post, :author_name, :css_class => 'differentError', :prepend_text => 'before', :append_text => 'after')
- end
-
- def test_error_messages_for_many_objects
- assert_dom_equal %(2 errors prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
- User email can't be empty
), error_messages_for("post", "user")
-
- # reverse the order, error order changes and so does the title
- assert_dom_equal %(2 errors prohibited this user from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for("user", "post")
-
- # add the default to put post back in the title
- assert_dom_equal %(2 errors prohibited this post from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for("user", "post", :object_name => "post")
-
- # symbols work as well
- assert_dom_equal %(2 errors prohibited this post from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :object_name => :post)
-
- # any default works too
- assert_dom_equal %(2 errors prohibited this monkey from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :object_name => "monkey")
-
- # should space object name
- assert_dom_equal %(2 errors prohibited this chunky bacon from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :object_name => "chunky_bacon")
-
- # hide header and explanation messages with nil or empty string
- assert_dom_equal %(- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :header_message => nil, :message => "")
-
- # override header and explanation messages
- header_message = "Yikes! Some errors"
- message = "Please fix the following fields and resubmit:"
- assert_dom_equal %(#{header_message}
#{message}
- User email can't be empty
- Author name can't be empty
), error_messages_for(:user, :post, :header_message => header_message, :message => message)
- end
-
- def test_error_messages_for_non_instance_variable
- actual_user = @user
- actual_post = @post
- @user = nil
- @post = nil
-
- #explicitly set object
- assert_dom_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
), error_messages_for("post", :object => actual_post)
-
- #multiple objects
- assert_dom_equal %(2 errors prohibited this user from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
), error_messages_for("user", "post", :object => [actual_user, actual_post])
-
- #nil object
- assert_equal '', error_messages_for('user', :object => nil)
- end
-
- def test_error_messages_for_model_objects
- error = error_messages_for(@post)
- assert_dom_equal %(1 error prohibited this post from being saved
There were problems with the following fields:
- Author name can't be empty
),
- error
-
- error = error_messages_for(@user, @post)
- assert_dom_equal %(2 errors prohibited this user from being saved
There were problems with the following fields:
- User email can't be empty
- Author name can't be empty
),
- error
- end
-
- def test_form_with_string_multipart
- assert_dom_equal(
- %(),
- form("post", :multipart => true)
- )
- end
-end
--
cgit v1.2.3
From 03c5a0e5c4c9888c54265d6ef97136854e0ff9e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?=
Date: Sat, 17 Oct 2009 15:54:58 -0300
Subject: Make app generatoor specs green once again.
---
railties/lib/rails/generators/rails/app/templates/Gemfile | 6 +++---
railties/test/generators/app_generator_test.rb | 11 +++++++++--
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index abe8c1556c..3966c0f70d 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -1,9 +1,9 @@
# Gemfile is where you list all of your application's dependencies
#
-gem "rails", "<%= Rails::VERSION::STRING %>"
+<%= "# " if options.freeze? %>gem "rails", "<%= Rails::VERSION::STRING %>"
#
# Bundling edge rails:
-# gem "rails", "<%= Rails::VERSION::STRING %>", :git => "git://github.com/rails/rails.git"
+<%= "# " unless options.freeze? %>gem "rails", "<%= Rails::VERSION::STRING %>", :git => "git://github.com/rails/rails.git"
# Specify gemcutter as a gem source
# source "http://gemcutter.org"
@@ -18,4 +18,4 @@ gem "rails", "<%= Rails::VERSION::STRING %>"
# gem "rspec", :only => :test
# only :test do
# gem "webrat"
-# end
\ No newline at end of file
+# end
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 5d6a9f6de9..20f2a24e6d 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -114,11 +114,18 @@ class AppGeneratorTest < GeneratorsTestCase
generator(:freeze => true, :database => "sqlite3").expects(:run).
with("rake rails:freeze:edge", :verbose => false)
silence(:stdout){ generator.invoke }
- assert_file 'config/environment.rb', /# RAILS_GEM_VERSION/
+
+ assert_file 'Gemfile' do |content|
+ flag = %(gem "rails", "#{Rails::VERSION::STRING}", :git => "git://github.com/rails/rails.git")
+ assert_match /^#{Regexp.escape(flag)}$/, content
+
+ flag = %(# gem "rails", "#{Rails::VERSION::STRING}")
+ assert_match /^#{Regexp.escape(flag)}$/, content
+ end
end
def test_template_from_dir_pwd
- FileUtils.cd(RAILS_ROOT)
+ FileUtils.cd(Rails.root)
assert_match /It works from file!/, run_generator(["-m", "lib/template.rb"])
end
--
cgit v1.2.3
From 1f9d234a6b567e68d97e71da6f19bd126e7f7058 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?=
Date: Sat, 17 Oct 2009 15:56:44 -0300
Subject: By default use ActiveModel API in controller generators, unless
otherwise specified [#3123 status:resolved]
---
railties/lib/rails/generators/active_model.rb | 18 ++++++----
railties/lib/rails/generators/active_record.rb | 34 ------------------
railties/lib/rails/generators/resource_helpers.rb | 17 +++------
.../scaffold_controller_generator_test.rb | 41 +++++++++++++++++++---
4 files changed, 53 insertions(+), 57 deletions(-)
diff --git a/railties/lib/rails/generators/active_model.rb b/railties/lib/rails/generators/active_model.rb
index 1a849a0e02..fe6321af30 100644
--- a/railties/lib/rails/generators/active_model.rb
+++ b/railties/lib/rails/generators/active_model.rb
@@ -32,7 +32,7 @@ module Rails
# GET index
def self.all(klass)
- raise NotImplementedError
+ "#{klass}.all"
end
# GET show
@@ -40,34 +40,38 @@ module Rails
# PUT update
# DELETE destroy
def self.find(klass, params=nil)
- raise NotImplementedError
+ "#{klass}.find(#{params})"
end
# GET new
# POST create
def self.build(klass, params=nil)
- raise NotImplementedError
+ if params
+ "#{klass}.new(#{params})"
+ else
+ "#{klass}.new"
+ end
end
# POST create
def save
- raise NotImplementedError
+ "#{name}.save"
end
# PUT update
def update_attributes(params=nil)
- raise NotImplementedError
+ "#{name}.update_attributes(#{params})"
end
# POST create
# PUT update
def errors
- raise NotImplementedError
+ "#{name}.errors"
end
# DELETE destroy
def destroy
- raise NotImplementedError
+ "#{name}.destroy"
end
end
end
diff --git a/railties/lib/rails/generators/active_record.rb b/railties/lib/rails/generators/active_record.rb
index c03ea59c1b..babad33db3 100644
--- a/railties/lib/rails/generators/active_record.rb
+++ b/railties/lib/rails/generators/active_record.rb
@@ -18,39 +18,5 @@ module ActiveRecord
end
end
end
-
- class ActiveModel < Rails::Generators::ActiveModel #:nodoc:
- def self.all(klass)
- "#{klass}.all"
- end
-
- def self.find(klass, params=nil)
- "#{klass}.find(#{params})"
- end
-
- def self.build(klass, params=nil)
- if params
- "#{klass}.new(#{params})"
- else
- "#{klass}.new"
- end
- end
-
- def save
- "#{name}.save"
- end
-
- def update_attributes(params=nil)
- "#{name}.update_attributes(#{params})"
- end
-
- def errors
- "#{name}.errors"
- end
-
- def destroy
- "#{name}.destroy"
- end
- end
end
end
diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb
index d4b0d4b945..0385581083 100644
--- a/railties/lib/rails/generators/resource_helpers.rb
+++ b/railties/lib/rails/generators/resource_helpers.rb
@@ -1,3 +1,5 @@
+require 'rails/generators/active_model'
+
module Rails
module Generators
# Deal with controller names on scaffold and add some helpers to deal with
@@ -47,20 +49,11 @@ module Rails
raise "You need to have :orm as class option to invoke orm_class and orm_instance"
end
- active_model = "#{options[:orm].to_s.classify}::Generators::ActiveModel"
-
- # If the orm was not loaded, try to load it at "generators/orm",
- # for example "generators/active_record" or "generators/sequel".
begin
- klass = active_model.constantize
- rescue NameError
- require "rails/generators/#{options[:orm]}"
+ "#{options[:orm].to_s.classify}::Generators::ActiveModel".constantize
+ rescue NameError => e
+ Rails::Generators::ActiveModel
end
-
- # Try once again after loading the file with success.
- klass ||= active_model.constantize
- rescue Exception => e
- raise Error, "Could not load #{active_model}, skipping controller. Error: #{e.message}."
end
end
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index f555725eb8..02155c295c 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -2,6 +2,11 @@ require 'abstract_unit'
require 'generators/generators_test_helper'
require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
+module Unknown
+ module Generators
+ end
+end
+
class ScaffoldControllerGeneratorTest < GeneratorsTestCase
def test_controller_skeleton_is_created
@@ -97,10 +102,38 @@ class ScaffoldControllerGeneratorTest < GeneratorsTestCase
assert_no_file "app/views/layouts/users.html.erb"
end
- def test_error_is_shown_if_orm_does_not_provide_interface
- error = capture(:stderr){ run_generator ["User", "--orm=unknown"] }
- assert_equal "Could not load Unknown::Generators::ActiveModel, skipping controller. " <<
- "Error: no such file to load -- rails/generators/unknown.\n", error
+ def test_default_orm_is_used
+ run_generator ["User", "--orm=unknown"]
+
+ assert_file "app/controllers/users_controller.rb" do |content|
+ assert_match /class UsersController < ApplicationController/, content
+
+ assert_instance_method content, :index do |m|
+ assert_match /@users = User\.all/, m
+ end
+ end
+ end
+
+ def test_customized_orm_is_used
+ klass = Class.new(Rails::Generators::ActiveModel) do
+ def self.all(klass)
+ "#{klass}.find(:all)"
+ end
+ end
+
+ Unknown::Generators.const_set(:ActiveModel, klass)
+ run_generator ["User", "--orm=unknown"]
+
+ assert_file "app/controllers/users_controller.rb" do |content|
+ assert_match /class UsersController < ApplicationController/, content
+
+ assert_instance_method content, :index do |m|
+ assert_match /@users = User\.find\(:all\)/, m
+ assert_no_match /@users = User\.all/, m
+ end
+ end
+ ensure
+ Unknown::Generators.send :remove_const, :ActiveModel
end
protected
--
cgit v1.2.3