From 13867a3f5f3e2248660a942956985a4eacacb283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 30 Apr 2010 18:40:24 +0200 Subject: Use %{} syntax in I18n (faster) instead of {{}}. --- actionpack/lib/action_view/helpers/form_helper.rb | 6 ++--- actionpack/lib/action_view/locale/en.yml | 28 +++++++++++------------ activemodel/lib/active_model/errors.rb | 2 +- activemodel/lib/active_model/locale/en.yml | 18 +++++++-------- activerecord/lib/active_record/locale/en.yml | 4 ++-- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index d3604925e8..b2470edf00 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1165,13 +1165,13 @@ module ActionView # submit button label, otherwise, it uses "Update Post". # # Those labels can be customized using I18n, under the helpers.submit key and accept - # the {{model}} as translation interpolation: + # the %{model} as translation interpolation: # # en: # helpers: # submit: - # create: "Create a {{model}}" - # update: "Confirm changes to {{model}}" + # create: "Create a %{model}" + # update: "Confirm changes to %{model}" # # It also searches for a key specific for the given object: # diff --git a/actionpack/lib/action_view/locale/en.yml b/actionpack/lib/action_view/locale/en.yml index 187e010e30..9004e52c5b 100644 --- a/actionpack/lib/action_view/locale/en.yml +++ b/actionpack/lib/action_view/locale/en.yml @@ -102,37 +102,37 @@ half_a_minute: "half a minute" less_than_x_seconds: one: "less than 1 second" - other: "less than {{count}} seconds" + other: "less than %{count} seconds" x_seconds: one: "1 second" - other: "{{count}} seconds" + other: "%{count} seconds" less_than_x_minutes: one: "less than a minute" - other: "less than {{count}} minutes" + other: "less than %{count} minutes" x_minutes: one: "1 minute" - other: "{{count}} minutes" + other: "%{count} minutes" about_x_hours: one: "about 1 hour" - other: "about {{count}} hours" + other: "about %{count} hours" x_days: one: "1 day" - other: "{{count}} days" + other: "%{count} days" about_x_months: one: "about 1 month" - other: "about {{count}} months" + other: "about %{count} months" x_months: one: "1 month" - other: "{{count}} months" + other: "%{count} months" about_x_years: one: "about 1 year" - other: "about {{count}} years" + other: "about %{count} years" over_x_years: one: "over 1 year" - other: "over {{count}} years" + other: "over %{count} years" almost_x_years: one: "almost 1 year" - other: "almost {{count}} years" + other: "almost %{count} years" prompts: year: "Year" month: "Month" @@ -148,7 +148,7 @@ # Default translation keys for submit FormHelper submit: - create: 'Create {{model}}' - update: 'Update {{model}}' - submit: 'Save {{model}}' + create: 'Create %{model}' + update: 'Update %{model}' + submit: 'Save %{model}' diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index e6c86c7843..14afc5265f 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -223,7 +223,7 @@ module ActiveModel else attr_name = attribute.to_s.gsub('.', '_').humanize attr_name = @base.class.human_attribute_name(attribute, :default => attr_name) - options = { :default => "{{attribute}} {{message}}", :attribute => attr_name } + options = { :default => "%{attribute} %{message}", :attribute => attr_name } messages.each do |m| full_messages << I18n.t(:"errors.format", options.merge(:message => m)) diff --git a/activemodel/lib/active_model/locale/en.yml b/activemodel/lib/active_model/locale/en.yml index d05c04967c..602a530dc0 100644 --- a/activemodel/lib/active_model/locale/en.yml +++ b/activemodel/lib/active_model/locale/en.yml @@ -1,7 +1,7 @@ en: errors: # The default format use in full error messages. - format: "{{attribute}} {{message}}" + format: "%{attribute} %{message}" # The values :model, :attribute and :value are always available for interpolation # The value :count is available when applicable. Can be used for pluralization. @@ -13,15 +13,15 @@ en: accepted: "must be accepted" empty: "can't be empty" blank: "can't be blank" - too_long: "is too long (maximum is {{count}} characters)" - too_short: "is too short (minimum is {{count}} characters)" - wrong_length: "is the wrong length (should be {{count}} characters)" + too_long: "is too long (maximum is %{count} characters)" + too_short: "is too short (minimum is %{count} characters)" + wrong_length: "is the wrong length (should be %{count} characters)" not_a_number: "is not a number" not_an_integer: "must be an integer" - greater_than: "must be greater than {{count}}" - greater_than_or_equal_to: "must be greater than or equal to {{count}}" - equal_to: "must be equal to {{count}}" - less_than: "must be less than {{count}}" - less_than_or_equal_to: "must be less than or equal to {{count}}" + greater_than: "must be greater than %{count}" + greater_than_or_equal_to: "must be greater than or equal to %{count}" + equal_to: "must be equal to %{count}" + less_than: "must be less than %{count}" + less_than_or_equal_to: "must be less than or equal to %{count}" odd: "must be odd" even: "must be even" diff --git a/activerecord/lib/active_record/locale/en.yml b/activerecord/lib/active_record/locale/en.yml index 810359fef3..9d5cb54180 100644 --- a/activerecord/lib/active_record/locale/en.yml +++ b/activerecord/lib/active_record/locale/en.yml @@ -9,7 +9,7 @@ en: errors: messages: taken: "has already been taken" - record_invalid: "Validation failed: {{errors}}" + record_invalid: "Validation failed: %{errors}" # Append your own errors here or at the model/attributes scope. # You can define own errors for models or model attributes. @@ -18,7 +18,7 @@ en: # For example, # models: # user: - # blank: "This is a custom blank message for {{model}}: {{attribute}}" + # blank: "This is a custom blank message for %{model}: %{attribute}" # attributes: # login: # blank: "This is a custom blank message for User login" -- cgit v1.2.3 From 35598db01a2d754df96b23c20050c1a96c999c76 Mon Sep 17 00:00:00 2001 From: Marius Nuennerich Date: Sat, 1 May 2010 14:40:02 +0200 Subject: repair the activesupport message encryptor tests for me, do so in the same way as jeremy did with message verifier [#4517 state:committed] Signed-off-by: Jeremy Kemper --- activesupport/test/message_encryptor_test.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index 2fba62bdd6..684b931176 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -1,4 +1,12 @@ require 'abstract_unit' + +begin + require 'openssl' + OpenSSL::Digest::SHA1 +rescue LoadError, NameError + $stderr.puts "Skipping MessageEncryptor test: broken OpenSSL install" +else + require 'active_support/time' class MessageEncryptorTest < Test::Unit::TestCase @@ -45,3 +53,5 @@ class MessageEncryptorTest < Test::Unit::TestCase ActiveSupport::Base64.encode64s(bits) end end + +end -- cgit v1.2.3 From a61a6d206b1d37747c3f907487db4bc0952c7b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 1 May 2010 22:38:57 +0200 Subject: Speed up I18n helpers in views and add entry to CHANGELOG. --- actionpack/lib/action_view/helpers/translation_helper.rb | 10 +++------- activesupport/CHANGELOG | 2 ++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index 89c1b4a275..086ad261c8 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -20,7 +20,7 @@ module ActionView options[:raise] = true translation = I18n.translate(scope_key_by_partial(key), options) translation = (translation.respond_to?(:join) ? translation.join : translation) - if html_safe_translation_key? key + if html_safe_translation_key?(key) translation.html_safe else translation @@ -53,12 +53,8 @@ module ActionView end def html_safe_translation_key?(key) - last_key = if key.is_a? Array - key.last - else - key.to_s.split('.').last - end - (last_key == "html") || (last_key.ends_with? "_html") + key = key.is_a?(Array) ? key.last : key.to_s + key =~ /(\b|_|\.)html$/ end end end diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index f24a1b1c6c..0652a20035 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.0.0 [beta 4/release candidate] (unreleased)* +* Deprecate {{}} as interpolation syntax for I18n in favor of %{} [José Valim] + * Array#to_xml is more powerful and able to handle the same types as Hash#to_xml #4490 [Neeraj Singh] * Harmonize the caching API and refactor the backends. #4452 [Brian Durand] -- cgit v1.2.3 From 8b1b273c21a2f1a6eeccca5fbe0303679c2d707d Mon Sep 17 00:00:00 2001 From: Cezary Baginski Date: Sat, 1 May 2010 19:21:31 +0200 Subject: AR: fixed postgres transaction tests [#4519 state:commited] Signed-off-by: Jeremy Kemper --- .../lib/active_record/connection_adapters/postgresql_adapter.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 74fed4ad62..6389094b8a 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -490,12 +490,8 @@ module ActiveRecord execute "ROLLBACK" end - if defined?(PGconn::PQTRANS_IDLE) - # The ruby-pg driver supports inspecting the transaction status, - # while the ruby-postgres driver does not. - def outside_transaction? - @connection.transaction_status == PGconn::PQTRANS_IDLE - end + def outside_transaction? + @connection.transaction_status == PGconn::PQTRANS_IDLE end def create_savepoint -- cgit v1.2.3 From 6433c939c1314ddf92c9986bb8664e568ca22d11 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 2 May 2010 00:40:31 +0200 Subject: edit pass in the transactions preamble rdoc --- activerecord/lib/active_record/transactions.rb | 55 +++++++++++++++----------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index 796dd99f02..1a195fbb81 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -31,10 +31,10 @@ module ActiveRecord # mary.deposit(100) # end # - # This example will only take money from David and give to Mary if neither - # +withdrawal+ nor +deposit+ raises an exception. Exceptions will force a - # ROLLBACK that returns the database to the state before the transaction was - # begun. Be aware, though, that the objects will _not_ have their instance + # This example will only take money from David and give it to Mary if neither + # +withdrawal+ nor +deposit+ raise an exception. Exceptions will force a + # ROLLBACK that returns the database to the state before the transaction + # began. Be aware, though, that the objects will _not_ have their instance # data returned to their pre-transactional state. # # == Different Active Record classes in a single transaction @@ -44,16 +44,16 @@ module ActiveRecord # that class. This is because transactions are per-database connection, not # per-model. # - # In this example a Balance record is transactionally saved even - # though transaction is called on the Account class: + # In this example a +balance+ record is transactionally saved even + # though +transaction+ is called on the +Account+ class: # # Account.transaction do # balance.save! # account.save! # end # - # Note that the +transaction+ method is also available as a model instance - # method. For example, you can also do this: + # The +transaction+ method is also available as a model instance method. + # For example, you can also do this: # # balance.transaction do # balance.save! @@ -62,9 +62,9 @@ module ActiveRecord # # == Transactions are not distributed across database connections # - # A transaction acts on a single database connection. If you have + # A transaction acts on a single database connection. If you have # multiple class-specific databases, the transaction will not protect - # interaction among them. One workaround is to begin a transaction + # interaction among them. One workaround is to begin a transaction # on each class whose models you alter: # # Student.transaction do @@ -74,16 +74,22 @@ module ActiveRecord # end # end # - # This is a poor solution, but full distributed transactions are beyond + # This is a poor solution, but fully distributed transactions are beyond # the scope of Active Record. # - # == Save and destroy are automatically wrapped in a transaction + # == +save+ and +destroy+ are automatically wrapped in a transaction # - # Both Base#save and Base#destroy come wrapped in a transaction that ensures - # that whatever you do in validations or callbacks will happen under the - # protected cover of a transaction. So you can use validations to check for - # values that the transaction depends on or you can raise exceptions in the - # callbacks to rollback, including after_* callbacks. + # Both +save+ and +destroy+ come wrapped in a transaction that ensures + # that whatever you do in validations or callbacks will happen under its + # protected cover. So you can use validations to check for values that + # the transaction depends on or you can raise exceptions in the callbacks + # to rollback, including after_* callbacks. + # + # As a consequence changes to the database are not seen outside your connection + # until the operation is complete. For example, if you try to update the index + # of a search engine in +after_save+ the indexer won't see the updated record. + # The +after_commit+ callback is the only one that is triggered once the update + # is committed. See below. # # == Exception handling and rolling back # @@ -91,14 +97,14 @@ module ActiveRecord # be propagated (after triggering the ROLLBACK), so you should be ready to # catch those in your application code. # - # One exception is the ActiveRecord::Rollback exception, which will trigger + # One exception is the ActiveRecord::Rollback exception, which will trigger # a ROLLBACK when raised, but not be re-raised by the transaction block. # - # *Warning*: one should not catch ActiveRecord::StatementInvalid exceptions - # inside a transaction block. StatementInvalid exceptions indicate that an + # *Warning*: one should not catch ActiveRecord::StatementInvalid exceptions + # inside a transaction block. ActiveRecord::StatementInvalid exceptions indicate that an # error occurred at the database level, for example when a unique constraint # is violated. On some database systems, such as PostgreSQL, database errors - # inside a transaction causes the entire transaction to become unusable + # inside a transaction cause the entire transaction to become unusable # until it's restarted from the beginning. Here is an example which # demonstrates the problem: # @@ -120,11 +126,12 @@ module ActiveRecord # # ignored until end of transaction block" # end # - # One should restart the entire transaction if a StatementError occurred. + # One should restart the entire transaction if an + # ActiveRecord::StatementInvalid occurred. # # == Nested transactions # - # #transaction calls can be nested. By default, this makes all database + # +transaction+ calls can be nested. By default, this makes all database # statements in the nested transaction block become part of the parent # transaction. For example: # @@ -139,7 +146,7 @@ module ActiveRecord # User.find(:all) # => empty # # It is also possible to requires a sub-transaction by passing - # :requires_new => true. If anything goes wrong, the + # :requires_new => true. If anything goes wrong, the # database rolls back to the beginning of the sub-transaction # without rolling back the parent transaction. For example: # -- cgit v1.2.3 From 1b898cc946f69808d5fa0db922ba100fb8ffcfe3 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 2 May 2010 00:47:09 +0200 Subject: say something about after_(commit|rollback) in callbacks.rb, the fact that their implementation is elsewhere is not important for rdoc purposes --- activerecord/lib/active_record/callbacks.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 98c14e6eb0..7ebeb6079e 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -17,8 +17,13 @@ module ActiveRecord # * (-) create # * (5) after_create # * (6) after_save + # * (7) after_commit # - # That's a total of eight callbacks, which gives you immense power to react and prepare for each state in the + # Also, an after_rollback callback can be configured to be triggered whenever a rollback is issued. + # Check out ActiveRecord::Transactions for more details about after_commit and + # after_rollback. + # + # That's a total of ten callbacks, which gives you immense power to react and prepare for each state in the # Active Record lifecycle. The sequence for calling Base#save for an existing record is similar, except that each # _on_create callback is replaced by the corresponding _on_update callback. # -- cgit v1.2.3 From 7aaabea5175be4b01697684e7573b422629206e6 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 2 May 2010 01:12:31 +0200 Subject: let Date.yesterday and Date.tomorrow be based on Date.current rather than Date.today --- activesupport/lib/active_support/core_ext/date/calculations.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 9d2ad2bbcf..fef49e1003 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -7,12 +7,12 @@ class Date class << self # Returns a new Date representing the date 1 day ago (i.e. yesterday's date). def yesterday - ::Date.today.yesterday + ::Date.current.yesterday end # Returns a new Date representing the date 1 day after today (i.e. tomorrow's date). def tomorrow - ::Date.today.tomorrow + ::Date.current.tomorrow end # Returns Time.zone.today when config.time_zone is set, otherwise just returns Date.today. -- cgit v1.2.3 From 1b33a151b2da4f8d24a981e0fbaa008352c41aa0 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 2 May 2010 01:36:10 +0200 Subject: revises tests for Date.yesterday and Date.tomorrow --- activesupport/test/core_ext/date_ext_test.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index 23c9bc7fb1..4ff714cabc 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -176,13 +176,13 @@ class DateExtCalculationsTest < Test::Unit::TestCase end def test_yesterday_constructor - assert_equal Date.today - 1, Date.yesterday + assert_equal Date.current - 1, Date.yesterday end def test_tomorrow_constructor - assert_equal Date.today + 1, Date.tomorrow + assert_equal Date.current + 1, Date.tomorrow end - + def test_since assert_equal Time.local(2005,2,21,0,0,45), Date.new(2005,2,21).since(45) end -- cgit v1.2.3 From 256a15c23581865559cc758c2e377cd395cc05b3 Mon Sep 17 00:00:00 2001 From: Cezary Baginski Date: Sat, 1 May 2010 23:33:36 +0200 Subject: AR: fixed postgres fixture tests [#4519 state:resolved] Signed-off-by: Jeremy Kemper --- activerecord/lib/active_record/fixtures.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 0bc49c1daa..4bf33c3856 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -516,7 +516,7 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash) # Cap primary key sequences to max(pk). if connection.respond_to?(:reset_pk_sequence!) table_names.each do |table_name| - connection.reset_pk_sequence!(table_name) + connection.reset_pk_sequence!(table_name.tr('/', '_')) end end end -- cgit v1.2.3 From 08b07b60b6d91a2f7bba5eec1e9b1d26599c578a Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sun, 2 May 2010 11:30:10 +1000 Subject: Adding ability to pass proc's to the ActionMailer class default method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- actionmailer/lib/action_mailer/base.rb | 7 ++++++- actionmailer/test/base_test.rb | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index e566132f4e..3a49da5984 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -528,8 +528,13 @@ module ActionMailer #:nodoc: content_type = headers[:content_type] parts_order = headers[:parts_order] + # Call all the procs (if any) + default_values = self.class.default.merge(self.class.default) do |k,v| + v.respond_to?(:call) ? v.call : v + end + # Handle defaults - headers = headers.reverse_merge(self.class.default) + headers = headers.reverse_merge(default_values) headers[:subject] ||= default_i18n_subject # Apply charset at the beginning so all fields are properly quoted diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 8e69073009..81e41dc8d4 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -113,6 +113,15 @@ class BaseTest < ActiveSupport::TestCase end end end + + class ProcMailer < ActionMailer::Base + default :to => 'system@test.lindsaar.net', + 'X-Proc-Method' => Proc.new { Time.now.to_i.to_s } + + def welcome + mail + end + end test "method call to mail does not raise error" do assert_nothing_raised { BaseMailer.welcome } @@ -560,6 +569,14 @@ class BaseTest < ActiveSupport::TestCase MyInterceptor.expects(:delivering_email).with(mail) mail.deliver end + + test "being able to put proc's into the defaults hash and they get evaluated on mail sending" do + mail1 = ProcMailer.welcome + yesterday = 1.day.ago + Time.stubs(:now).returns(yesterday) + mail2 = ProcMailer.welcome + assert(mail1['X-Proc-Method'].to_s.to_i > mail2['X-Proc-Method'].to_s.to_i) + end protected -- cgit v1.2.3 From ceaa100e59c7953ce5c0e978ddd6d5bc046c9fd9 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sun, 2 May 2010 13:16:28 +1000 Subject: Adding ability for the procs to be called within the instance, allows you to pass results from instance methods to the mail header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- actionmailer/lib/action_mailer/base.rb | 2 +- actionmailer/test/base_test.rb | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 3a49da5984..b88172dfc2 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -530,7 +530,7 @@ module ActionMailer #:nodoc: # Call all the procs (if any) default_values = self.class.default.merge(self.class.default) do |k,v| - v.respond_to?(:call) ? v.call : v + v.respond_to?(:call) ? v.bind(self).call : v end # Handle defaults diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 81e41dc8d4..5506d62d6a 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -116,11 +116,19 @@ class BaseTest < ActiveSupport::TestCase class ProcMailer < ActionMailer::Base default :to => 'system@test.lindsaar.net', - 'X-Proc-Method' => Proc.new { Time.now.to_i.to_s } + 'X-Proc-Method' => Proc.new { Time.now.to_i.to_s }, + :subject => Proc.new { give_a_greeting } def welcome mail end + + private + + def give_a_greeting + "Thanks for signing up this afternoon" + end + end test "method call to mail does not raise error" do @@ -577,6 +585,11 @@ class BaseTest < ActiveSupport::TestCase mail2 = ProcMailer.welcome assert(mail1['X-Proc-Method'].to_s.to_i > mail2['X-Proc-Method'].to_s.to_i) end + + test "we can call other defined methods on the class as needed" do + mail = ProcMailer.welcome + assert_equal("Thanks for signing up this afternoon", mail.subject) + end protected -- cgit v1.2.3 From 02028e529c97488b6c70cdbf66dc08c7fb2d36aa Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 2 May 2010 14:59:51 -0300 Subject: Missing require added make pass activesupport/test/json/encoding_test.rb in isolation Signed-off-by: Xavier Noria --- activesupport/lib/active_support/json/encoding.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index e692f6d142..3d7be8da1f 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -1,6 +1,7 @@ # encoding: utf-8 require 'bigdecimal' require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/big_decimal/conversions' require 'active_support/core_ext/hash/except' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/module/delegation' -- cgit v1.2.3 From 109d3ee38d1c39f0e27bc827065427635d6396b2 Mon Sep 17 00:00:00 2001 From: Justin George Date: Tue, 27 Apr 2010 14:13:47 -0700 Subject: Make notifications go off even when an error is raised, so that we capture the underlying performance data [#4505 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is important when trying to keep track of many layers of interrelated calls i.e.: ActiveRecord::Base.transaction do MyModel.find(1) #ActiveRecord::NotFound end # should capture the full time until the error propagation Signed-off-by: José Valim --- activesupport/lib/active_support/notifications/instrumenter.rb | 10 +++++++--- activesupport/test/notifications_test.rb | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/activesupport/lib/active_support/notifications/instrumenter.rb b/activesupport/lib/active_support/notifications/instrumenter.rb index f3d877efe7..ef3fdd1843 100644 --- a/activesupport/lib/active_support/notifications/instrumenter.rb +++ b/activesupport/lib/active_support/notifications/instrumenter.rb @@ -15,9 +15,13 @@ module ActiveSupport # and publish it. def instrument(name, payload={}) time = Time.now - result = yield(payload) if block_given? - @notifier.publish(name, time, Time.now, @id, payload) - result + begin + yield(payload) if block_given? + ensure + # Notify in an ensure block so that we can be certain end + # events get sent even if an error occurs in the passed-in block + @notifier.publish(name, time, Time.now, @id, payload) + end end private diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb index c2e1c588f0..251380a0d5 100644 --- a/activesupport/test/notifications_test.rb +++ b/activesupport/test/notifications_test.rb @@ -168,7 +168,7 @@ module Notifications assert_equal Hash[:payload => "notifications"], @events.last.payload end - def test_instrument_does_not_publish_when_exception_is_raised + def test_instrument_publishes_when_exception_is_raised begin instrument(:awesome, :payload => "notifications") do raise "FAIL" @@ -178,7 +178,7 @@ module Notifications end drain - assert_equal 0, @events.size + assert_equal 1, @events.size end def test_event_is_pushed_even_without_block -- cgit v1.2.3 From 731d4392e478ff5526b595074d9caa999da8bd0c Mon Sep 17 00:00:00 2001 From: Justin George Date: Tue, 27 Apr 2010 21:16:06 -0700 Subject: Change event namespace ordering to most-significant first [#4504 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More work still needs to be done on some of these names (render_template.action_view and render_template!.action_view particularly) but this allows (for example) /^sql/ to subscribe to all the various ORMs without further modification Signed-off-by: José Valim --- actionmailer/lib/action_mailer/base.rb | 4 ++-- actionpack/lib/action_controller/caching/fragments.rb | 2 +- actionpack/lib/action_controller/caching/pages.rb | 2 +- .../lib/action_controller/metal/instrumentation.rb | 10 +++++----- actionpack/lib/action_controller/test_case.rb | 8 ++++---- actionpack/lib/action_view/render/partials.rb | 4 ++-- actionpack/lib/action_view/render/rendering.rb | 2 +- actionpack/lib/action_view/template.rb | 2 +- .../connection_adapters/abstract/query_cache.rb | 2 +- .../connection_adapters/abstract_adapter.rb | 2 +- activeresource/lib/active_resource/connection.rb | 2 +- activesupport/lib/active_support/cache.rb | 2 +- railties/lib/rails/log_subscriber.rb | 6 +++--- .../application/initializers/notifications_test.rb | 2 +- railties/test/log_subscriber_test.rb | 18 +++++++++--------- 15 files changed, 34 insertions(+), 34 deletions(-) diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index b88172dfc2..fd7b969496 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -316,7 +316,7 @@ module ActionMailer #:nodoc: # end # end def receive(raw_mail) - ActiveSupport::Notifications.instrument("action_mailer.receive") do |payload| + ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload| mail = Mail.new(raw_mail) set_payload_for_mail(payload, mail) new.receive(mail) @@ -328,7 +328,7 @@ module ActionMailer #:nodoc: # when you call :deliver on the Mail::Message, calling +deliver_mail+ directly # and passing a Mail::Message will do nothing except tell the logger you sent the email. def deliver_mail(mail) #:nodoc: - ActiveSupport::Notifications.instrument("action_mailer.deliver") do |payload| + ActiveSupport::Notifications.instrument("deliver.action_mailer") do |payload| self.set_payload_for_mail(payload, mail) yield # Let Mail do the delivery actions end diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb index 473a2fe214..460273dac1 100644 --- a/actionpack/lib/action_controller/caching/fragments.rb +++ b/actionpack/lib/action_controller/caching/fragments.rb @@ -99,7 +99,7 @@ module ActionController #:nodoc: end def instrument_fragment_cache(name, key) - ActiveSupport::Notifications.instrument("action_controller.#{name}", :key => key){ yield } + ActiveSupport::Notifications.instrument("#{name}.action_controller", :key => key){ yield } end end end diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb index cefd1f48c0..4f7a5d3f55 100644 --- a/actionpack/lib/action_controller/caching/pages.rb +++ b/actionpack/lib/action_controller/caching/pages.rb @@ -109,7 +109,7 @@ module ActionController #:nodoc: end def instrument_page_cache(name, path) - ActiveSupport::Notifications.instrument("action_controller.#{name}", :path => path){ yield } + ActiveSupport::Notifications.instrument("#{name}.action_controller", :path => path){ yield } end end diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb index d69de65f28..ba38b186d6 100644 --- a/actionpack/lib/action_controller/metal/instrumentation.rb +++ b/actionpack/lib/action_controller/metal/instrumentation.rb @@ -23,9 +23,9 @@ module ActionController :path => (request.fullpath rescue "unknown") } - ActiveSupport::Notifications.instrument("action_controller.start_processing", raw_payload.dup) + ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup) - ActiveSupport::Notifications.instrument("action_controller.process_action", raw_payload) do |payload| + ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload| result = super payload[:status] = response.status append_info_to_payload(payload) @@ -42,20 +42,20 @@ module ActionController end def send_file(path, options={}) - ActiveSupport::Notifications.instrument("action_controller.send_file", + ActiveSupport::Notifications.instrument("send_file.action_controller", options.merge(:path => path)) do super end end def send_data(data, options = {}) - ActiveSupport::Notifications.instrument("action_controller.send_data", options) do + ActiveSupport::Notifications.instrument("send_data.action_controller", options) do super end end def redirect_to(*args) - ActiveSupport::Notifications.instrument("action_controller.redirect_to") do |payload| + ActiveSupport::Notifications.instrument("redirect_to.action_controller") do |payload| result = super payload[:status] = self.status payload[:location] = self.location diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 2b9b34961e..2010d8573c 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -16,12 +16,12 @@ module ActionController @templates = Hash.new(0) @layouts = Hash.new(0) - ActiveSupport::Notifications.subscribe("action_view.render_template") do |name, start, finish, id, payload| + ActiveSupport::Notifications.subscribe("render_template.action_view") do |name, start, finish, id, payload| path = payload[:layout] @layouts[path] += 1 end - ActiveSupport::Notifications.subscribe("action_view.render_template!") do |name, start, finish, id, payload| + ActiveSupport::Notifications.subscribe("!render_template.action_view") do |name, start, finish, id, payload| path = payload[:virtual_path] next unless path partial = path =~ /^.*\/_[^\/]*$/ @@ -36,8 +36,8 @@ module ActionController end def teardown_subscriptions - ActiveSupport::Notifications.unsubscribe("action_view.render_template") - ActiveSupport::Notifications.unsubscribe("action_view.render_template!") + ActiveSupport::Notifications.unsubscribe("render_template.action_view") + ActiveSupport::Notifications.unsubscribe("!render_template.action_view") end # Asserts that the request was rendered with the appropriate template file or partials diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 4d23d55687..974345633c 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -211,12 +211,12 @@ module ActionView identifier = ((@template = find_template) ? @template.identifier : @path) if @collection - ActiveSupport::Notifications.instrument("action_view.render_collection", + ActiveSupport::Notifications.instrument("render_collection.action_view", :identifier => identifier || "collection", :count => @collection.size) do render_collection end else - content = ActiveSupport::Notifications.instrument("action_view.render_partial", + content = ActiveSupport::Notifications.instrument("render_partial.action_view", :identifier => identifier) do render_partial end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 492326964a..4198013f57 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -52,7 +52,7 @@ module ActionView locals = options[:locals] || {} layout = find_layout(layout) if layout - ActiveSupport::Notifications.instrument("action_view.render_template", + ActiveSupport::Notifications.instrument("render_template.action_view", :identifier => template.identifier, :layout => layout.try(:virtual_path)) do content = template.render(self, locals) { |*name| _layout_for(*name) } diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 3c0cd35359..a1a970e2d2 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -41,7 +41,7 @@ module ActionView def render(view, locals, &block) # Notice that we use a bang in this instrumentation because you don't want to # consume this in production. This is only slow if it's being listened to. - ActiveSupport::Notifications.instrument("action_view.render_template!", :virtual_path => @virtual_path) do + ActiveSupport::Notifications.instrument("!render_template.action_view", :virtual_path => @virtual_path) do method_name = compile(locals, view) view.send(method_name, locals, &block) end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb index 3c560903f7..533a7bb8e6 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -76,7 +76,7 @@ module ActiveRecord def cache_sql(sql) result = if @query_cache.has_key?(sql) - ActiveSupport::Notifications.instrument("active_record.sql", + ActiveSupport::Notifications.instrument("sql.active_record", :sql => sql, :name => "CACHE", :connection_id => self.object_id) @query_cache[sql] else diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 578297029b..28a59c1e62 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -197,7 +197,7 @@ module ActiveRecord def log(sql, name) name ||= "SQL" result = nil - ActiveSupport::Notifications.instrument("active_record.sql", + ActiveSupport::Notifications.instrument("sql.active_record", :sql => sql, :name => name, :connection_id => self.object_id) do @runtime += Benchmark.ms { result = yield } end diff --git a/activeresource/lib/active_resource/connection.rb b/activeresource/lib/active_resource/connection.rb index 2f0ccd7dae..b7befe110d 100644 --- a/activeresource/lib/active_resource/connection.rb +++ b/activeresource/lib/active_resource/connection.rb @@ -106,7 +106,7 @@ module ActiveResource private # Makes a request to the remote service. def request(method, path, *arguments) - result = ActiveSupport::Notifications.instrument("active_resource.request") do |payload| + result = ActiveSupport::Notifications.instrument("request.active_resource") do |payload| payload[:method] = method payload[:request_uri] = "#{site.scheme}://#{site.host}:#{site.port}#{path}" payload[:result] = http.send(method, path, *arguments) diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index ec5007c284..2605a3f2b8 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -502,7 +502,7 @@ module ActiveSupport if self.class.instrument payload = { :key => key } payload.merge!(options) if options.is_a?(Hash) - ActiveSupport::Notifications.instrument("active_support.cache_#{operation}", payload){ yield } + ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield } else yield end diff --git a/railties/lib/rails/log_subscriber.rb b/railties/lib/rails/log_subscriber.rb index 42697d2e32..145c7e0ace 100644 --- a/railties/lib/rails/log_subscriber.rb +++ b/railties/lib/rails/log_subscriber.rb @@ -22,7 +22,7 @@ module Rails # # Rails::LogSubscriber.add :active_record, ActiveRecord::Railtie::LogSubscriber.new # - # So whenever a "active_record.sql" notification arrive to Rails::LogSubscriber, + # So whenever a "sql.active_record" notification arrive to Rails::LogSubscriber, # it will properly dispatch the event (ActiveSupport::Notifications::Event) to # the sql method. # @@ -54,7 +54,7 @@ module Rails log_subscribers << log_subscriber log_subscriber.public_methods(false).each do |event| - notifier.subscribe("#{namespace}.#{event}") do |*args| + notifier.subscribe("#{event}.#{namespace}") do |*args| next if log_subscriber.logger.nil? begin @@ -105,4 +105,4 @@ module Rails "#{bold}#{color}#{text}#{CLEAR}" end end -end \ No newline at end of file +end diff --git a/railties/test/application/initializers/notifications_test.rb b/railties/test/application/initializers/notifications_test.rb index b99cf5bb4f..276950c78c 100644 --- a/railties/test/application/initializers/notifications_test.rb +++ b/railties/test/application/initializers/notifications_test.rb @@ -38,7 +38,7 @@ module ApplicationTests ActiveRecord::Base.logger = logger = MockLogger.new # Mimic ActiveRecord notifications - instrument "active_record.sql", :name => "SQL", :sql => "SHOW tables" + instrument "sql.active_record", :name => "SQL", :sql => "SHOW tables" wait assert_equal 1, logger.logged.size diff --git a/railties/test/log_subscriber_test.rb b/railties/test/log_subscriber_test.rb index 49288cfaa8..a3a755ae62 100644 --- a/railties/test/log_subscriber_test.rb +++ b/railties/test/log_subscriber_test.rb @@ -61,21 +61,21 @@ class SyncLogSubscriberTest < ActiveSupport::TestCase def test_event_is_sent_to_the_registered_class Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber - instrument "my_log_subscriber.some_event" + instrument "some_event.my_log_subscriber" wait - assert_equal %w(my_log_subscriber.some_event), @logger.logged(:info) + assert_equal %w(some_event.my_log_subscriber), @logger.logged(:info) end def test_event_is_an_active_support_notifications_event Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber - instrument "my_log_subscriber.some_event" + instrument "some_event.my_log_subscriber" wait assert_kind_of ActiveSupport::Notifications::Event, @log_subscriber.event end def test_does_not_send_the_event_if_it_doesnt_match_the_class Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber - instrument "my_log_subscriber.unknown_event" + instrument "unknown_event.my_log_subscriber" wait # If we get here, it means that NoMethodError was not raised. end @@ -84,7 +84,7 @@ class SyncLogSubscriberTest < ActiveSupport::TestCase Rails.logger = nil @log_subscriber.expects(:some_event).never Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber - instrument "my_log_subscriber.some_event" + instrument "some_event.my_log_subscriber" wait end @@ -110,14 +110,14 @@ class SyncLogSubscriberTest < ActiveSupport::TestCase def test_logging_does_not_die_on_failures Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber - instrument "my_log_subscriber.puke" - instrument "my_log_subscriber.some_event" + instrument "puke.my_log_subscriber" + instrument "some_event.my_log_subscriber" wait assert_equal 1, @logger.logged(:info).size - assert_equal 'my_log_subscriber.some_event', @logger.logged(:info).last + assert_equal 'some_event.my_log_subscriber', @logger.logged(:info).last assert_equal 1, @logger.logged(:error).size - assert_equal 'Could not log "my_log_subscriber.puke" event. RuntimeError: puke', @logger.logged(:error).last + assert_equal 'Could not log "puke.my_log_subscriber" event. RuntimeError: puke', @logger.logged(:error).last end end \ No newline at end of file -- cgit v1.2.3 From a76c7e68d5e39f5962d9cb85c98e6a8e96f8b3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 2 May 2010 22:40:20 +0200 Subject: Event should be aware if yielded block failed or not. --- activesupport/lib/active_support/notifications/instrumenter.rb | 8 +++++--- activesupport/test/notifications_test.rb | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/notifications/instrumenter.rb b/activesupport/lib/active_support/notifications/instrumenter.rb index ef3fdd1843..7e89402822 100644 --- a/activesupport/lib/active_support/notifications/instrumenter.rb +++ b/activesupport/lib/active_support/notifications/instrumenter.rb @@ -12,14 +12,16 @@ module ActiveSupport end # Instrument the given block by measuring the time taken to execute it - # and publish it. + # and publish it. Notice that events get sent even if an error occurs + # in the passed-in block def instrument(name, payload={}) time = Time.now begin yield(payload) if block_given? + rescue Exception => e + payload[:exception] = [e.class.name, e.message] + raise e ensure - # Notify in an ensure block so that we can be certain end - # events get sent even if an error occurs in the passed-in block @notifier.publish(name, time, Time.now, @id, payload) end end diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb index 251380a0d5..e11de5f67a 100644 --- a/activesupport/test/notifications_test.rb +++ b/activesupport/test/notifications_test.rb @@ -179,6 +179,8 @@ module Notifications drain assert_equal 1, @events.size + assert_equal Hash[:payload => "notifications", + :exception => ["RuntimeError", "FAIL"]], @events.last.payload end def test_event_is_pushed_even_without_block -- cgit v1.2.3 From 91125f9927ffbe1a16494910ae0e8228a4400439 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 2 May 2010 09:20:17 -0500 Subject: move FixtureResolver to a file that is accessible outside Rails' own tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#4522 state:resolved] Signed-off-by: José Valim --- actionpack/lib/action_view/testing/resolvers.rb | 35 +++++++++++++++++++++++++ actionpack/test/abstract_unit.rb | 2 +- actionpack/test/controller/layout_test.rb | 2 -- actionpack/test/lib/fixture_template.rb | 29 -------------------- 4 files changed, 36 insertions(+), 32 deletions(-) create mode 100644 actionpack/lib/action_view/testing/resolvers.rb delete mode 100644 actionpack/test/lib/fixture_template.rb diff --git a/actionpack/lib/action_view/testing/resolvers.rb b/actionpack/lib/action_view/testing/resolvers.rb new file mode 100644 index 0000000000..f468e57c26 --- /dev/null +++ b/actionpack/lib/action_view/testing/resolvers.rb @@ -0,0 +1,35 @@ +require 'action_view/template/resolver' + +module ActionView #:nodoc: + # Use FixtureResolver in your tests to simulate the presence of files on the + # file system. This is used internally by Rails' own test suite, and is + # useful for testing extensions that have no way of knowing what the file + # system will look like at runtime. + class FixtureResolver < PathResolver + attr_reader :hash + + def initialize(hash = {}) + super() + @hash = hash + end + + private + + def query(path, exts, formats) + query = Regexp.escape(path) + exts.each do |ext| + query << '(' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << '|)' + end + + templates = [] + @hash.select { |k,v| k =~ /^#{query}$/ }.each do |path, source| + handler, format = extract_handler_and_format(path, formats) + templates << Template.new(source, path, handler, + :virtual_path => path, :format => format) + end + + templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size } + end + end +end + diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index f3ff258016..89ba0990f1 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -16,8 +16,8 @@ require 'test/unit' require 'abstract_controller' require 'action_controller' require 'action_view' +require 'action_view/testing/resolvers' require 'action_dispatch' -require 'fixture_template' require 'active_support/dependencies' require 'active_model' diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index 48be7571ea..165c61ffad 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -10,8 +10,6 @@ ActionView::Template::register_template_handler :mab, ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../fixtures/layout_tests/' ] -require "fixture_template" - class LayoutTest < ActionController::Base def self.controller_path; 'views' end def self._implied_layout_name; to_s.underscore.gsub(/_controller$/, '') ; end diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb deleted file mode 100644 index b49ccd39ca..0000000000 --- a/actionpack/test/lib/fixture_template.rb +++ /dev/null @@ -1,29 +0,0 @@ -module ActionView #:nodoc: - class FixtureResolver < PathResolver - attr_reader :hash - - def initialize(hash = {}) - super() - @hash = hash - end - - private - - def query(path, exts, formats) - query = Regexp.escape(path) - exts.each do |ext| - query << '(' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << '|)' - end - - templates = [] - @hash.select { |k,v| k =~ /^#{query}$/ }.each do |path, source| - handler, format = extract_handler_and_format(path, formats) - templates << Template.new(source, path, handler, - :virtual_path => path, :format => format) - end - - templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size } - end - - end -end \ No newline at end of file -- cgit v1.2.3 From a3044967ed48e27104e8c97719c798ee2f416846 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 2 May 2010 09:54:43 -0500 Subject: add tests for FixtureResolver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- .../test/template/testing/fixture_resolver_test.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 actionpack/test/template/testing/fixture_resolver_test.rb diff --git a/actionpack/test/template/testing/fixture_resolver_test.rb b/actionpack/test/template/testing/fixture_resolver_test.rb new file mode 100644 index 0000000000..de83540468 --- /dev/null +++ b/actionpack/test/template/testing/fixture_resolver_test.rb @@ -0,0 +1,18 @@ +require 'abstract_unit' + +class FixtureResolverTest < ActiveSupport::TestCase + def test_should_return_empty_list_for_unknown_path + resolver = ActionView::FixtureResolver.new() + templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :handlers => []}) + assert_equal [], templates, "expected an empty list of templates" + end + + def test_should_return_template_for_declared_path + resolver = ActionView::FixtureResolver.new("arbitrary/path" => "this text") + templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :handlers => []}) + assert_equal 1, templates.size, "expected one template" + assert_equal "this text", templates.first.source + assert_equal "arbitrary/path", templates.first.virtual_path + assert_equal [:html], templates.first.formats + end +end -- cgit v1.2.3 From 8672a97e11b1a3697b0147b83fd1f812395997a1 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 2 May 2010 10:04:32 -0500 Subject: add NullResolver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#4523 state:resolved] Signed-off-by: José Valim --- actionpack/lib/action_view/testing/resolvers.rb | 8 ++++++++ actionpack/test/template/testing/null_resolver_test.rb | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 actionpack/test/template/testing/null_resolver_test.rb diff --git a/actionpack/lib/action_view/testing/resolvers.rb b/actionpack/lib/action_view/testing/resolvers.rb index f468e57c26..578c56c6c4 100644 --- a/actionpack/lib/action_view/testing/resolvers.rb +++ b/actionpack/lib/action_view/testing/resolvers.rb @@ -31,5 +31,13 @@ module ActionView #:nodoc: templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size } end end + + class NullResolver < ActionView::PathResolver + def query(path, exts, formats) + handler, format = extract_handler_and_format(path, formats) + [ActionView::Template.new("Template generated by Null Resolver", path, handler, :virtual_path => path, :format => format)] + end + end + end diff --git a/actionpack/test/template/testing/null_resolver_test.rb b/actionpack/test/template/testing/null_resolver_test.rb new file mode 100644 index 0000000000..e142506e6a --- /dev/null +++ b/actionpack/test/template/testing/null_resolver_test.rb @@ -0,0 +1,12 @@ +require 'abstract_unit' + +class NullResolverTest < ActiveSupport::TestCase + def test_should_return_template_for_any_path + resolver = ActionView::NullResolver.new() + templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :handlers => []}) + assert_equal 1, templates.size, "expected one template" + assert_equal "Template generated by Null Resolver", templates.first.source + assert_equal "arbitrary/path", templates.first.virtual_path + assert_equal [:html], templates.first.formats + end +end -- cgit v1.2.3 From 0e00f428a816cd24ca645794385fd7b71dbfed73 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 3 May 2010 00:02:14 +0200 Subject: adds test coverage for Date.current vs Date.today in Date.(yesterday|tomorrow) implementation --- activesupport/test/core_ext/date_ext_test.rb | 46 +++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index 4ff714cabc..c403d7fb11 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -178,11 +178,47 @@ class DateExtCalculationsTest < Test::Unit::TestCase def test_yesterday_constructor assert_equal Date.current - 1, Date.yesterday end + + def test_yesterday_constructor_when_zone_default_is_not_set + with_env_tz 'UTC' do + with_tz_default do + Time.stubs(:now).returns Time.local(2000, 1, 1) + assert_equal Date.new(1999, 12, 31), Date.yesterday + end + end + end + + def test_yesterday_constructor_when_zone_default_is_set + with_env_tz 'UTC' do + with_tz_default ActiveSupport::TimeZone['Eastern Time (US & Canada)'] do # UTC -5 + Time.stubs(:now).returns Time.local(2000, 1, 1) + assert_equal Date.new(1999, 12, 30), Date.yesterday + end + end + end def test_tomorrow_constructor assert_equal Date.current + 1, Date.tomorrow end - + + def test_tomorrow_constructor_when_zone_default_is_not_set + with_env_tz 'UTC' do + with_tz_default do + Time.stubs(:now).returns Time.local(1999, 12, 31) + assert_equal Date.new(2000, 1, 1), Date.tomorrow + end + end + end + + def test_tomorrow_constructor_when_zone_default_is_set + with_env_tz 'UTC' do + with_tz_default ActiveSupport::TimeZone['Europe/Paris'] do # UTC +1 + Time.stubs(:now).returns Time.local(1999, 12, 31, 23) + assert_equal Date.new(2000, 1, 2), Date.tomorrow + end + end + end + def test_since assert_equal Time.local(2005,2,21,0,0,45), Date.new(2005,2,21).since(45) end @@ -264,6 +300,14 @@ class DateExtCalculationsTest < Test::Unit::TestCase ensure old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ') end + + def with_tz_default(tz = nil) + old_tz = Time.zone_default + Time.zone_default = tz + yield + ensure + Time.zone_default = old_tz + end end class DateExtBehaviorTest < Test::Unit::TestCase -- cgit v1.2.3 From 8ae9b05fa0ca579ecabcd563e6ba75ea0f44f074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 3 May 2010 12:54:52 +0200 Subject: Make backtrace_cleaner work as expected. Prior to this patch, the Full Trace rarely showed the full trace. Also, increase performance considerably. --- actionpack/lib/action_view/template/error.rb | 32 ++++++---------------------- railties/lib/rails/backtrace_cleaner.rb | 23 ++++++++++---------- 2 files changed, 17 insertions(+), 38 deletions(-) diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb index 5222ffa89c..a947d746e3 100644 --- a/actionpack/lib/action_view/template/error.rb +++ b/actionpack/lib/action_view/template/error.rb @@ -21,17 +21,18 @@ module ActionView super("Missing #{template_type} #{path} with #{details.inspect} in view paths #{display_paths}") end end + class Template # The Template::Error exception is raised when the compilation of the template fails. This exception then gathers a # bunch of intimate details and uses it to report a very precise exception message. class Error < ActionViewError #:nodoc: SOURCE_CODE_RADIUS = 3 - attr_reader :original_exception + attr_reader :original_exception, :backtrace def initialize(template, assigns, original_exception) @template, @assigns, @original_exception = template, assigns.dup, original_exception - @backtrace = compute_backtrace + @backtrace = original_exception.backtrace end def file_name @@ -42,14 +43,6 @@ module ActionView ActiveSupport::Deprecation.silence { original_exception.message } end - def clean_backtrace - if defined?(Rails) && Rails.respond_to?(:backtrace_cleaner) - Rails.backtrace_cleaner.clean(original_exception.backtrace) - else - original_exception.backtrace - end - end - def sub_template_message if @sub_templates "Trace of template inclusion: " + @@ -87,29 +80,16 @@ module ActionView @line_number ||= if file_name regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/ - - $1 if message =~ regexp or clean_backtrace.find { |line| line =~ regexp } + $1 if message =~ regexp || backtrace.find { |line| line =~ regexp } end end def to_s - "\n#{self.class} (#{message}) #{source_location}:\n" + - "#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n" - end - - # don't do anything nontrivial here. Any raised exception from here becomes fatal - # (and can't be rescued). - def backtrace - @backtrace + "\n#{self.class} (#{message}) #{source_location}:\n\n" + + "#{source_extract(4)}\n #{backtrace.join("\n ")}\n\n" end private - def compute_backtrace - [ - "#{source_location.capitalize}\n\n#{source_extract(4)}\n " + - clean_backtrace.join("\n ") - ] - end def source_location if line_number diff --git a/railties/lib/rails/backtrace_cleaner.rb b/railties/lib/rails/backtrace_cleaner.rb index ee2635d4cd..bedefaa51c 100644 --- a/railties/lib/rails/backtrace_cleaner.rb +++ b/railties/lib/rails/backtrace_cleaner.rb @@ -2,29 +2,28 @@ require 'active_support/backtrace_cleaner' module Rails class BacktraceCleaner < ActiveSupport::BacktraceCleaner - ERB_METHOD_SIG = /:in `_run_erb_.*/ - APP_DIRS = %w( app config lib test ) + APP_DIRS_PATTERN = /^\/?(app|config|lib|test)/ + RENDER_TEMPLATE_PATTERN = /:in `_render_template_\w*'/ def initialize super add_filter { |line| line.sub("#{Rails.root}/", '') } - add_filter { |line| line.sub(ERB_METHOD_SIG, '') } + add_filter { |line| line.sub(RENDER_TEMPLATE_PATTERN, '') } add_filter { |line| line.sub('./', '/') } # for tests add_gem_filters - - add_silencer { |line| !APP_DIRS.any? { |dir| line =~ /^\/?#{dir}/ } } + add_silencer { |line| line !~ APP_DIRS_PATTERN } end private def add_gem_filters - return unless defined? Gem - (Gem.path + [Gem.default_dir]).uniq.each do |path| - # http://gist.github.com/30430 - add_filter { |line| - line.sub(%r{(#{path})/gems/([^/]+)-([0-9.]+)/(.*)}, '\2 (\3) \4') - } - end + return unless defined?(Gem) + + gems_paths = (Gem.path + [Gem.default_dir]).uniq.map!{ |p| Regexp.escape(p) } + return if gems_paths.empty? + + gems_regexp = %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w\.]+)/(.*)} + add_filter { |line| line.sub(gems_regexp, '\2 (\3) \4') } end end -- cgit v1.2.3 From 9bd91b00b85c77bc294ae2a99beae203cc163227 Mon Sep 17 00:00:00 2001 From: Lawrence Pit Date: Mon, 3 May 2010 16:44:32 +1000 Subject: Favor %{} in all code instead of (deprecated) {{}} as interpolation syntax for I18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- actionpack/lib/action_view/helpers/form_helper.rb | 2 +- actionpack/test/template/form_helper_test.rb | 6 +++--- .../lib/active_model/validations/exclusion.rb | 2 +- .../lib/active_model/validations/inclusion.rb | 2 +- activemodel/lib/active_model/validations/length.rb | 6 +++--- .../validations/conditional_validation_test.rb | 24 +++++++++++----------- .../cases/validations/exclusion_validation_test.rb | 2 +- .../cases/validations/format_validation_test.rb | 2 +- .../i18n_generate_message_validation_test.rb | 14 ++++++------- .../test/cases/validations/i18n_validation_test.rb | 2 +- .../cases/validations/inclusion_validation_test.rb | 2 +- .../cases/validations/length_validation_test.rb | 24 +++++++++++----------- .../validations/numericality_validation_test.rb | 4 ++-- .../i18n_generate_message_validation_test.rb | 4 ++-- .../activerecord_validations_callbacks.textile | 24 +++++++++++----------- railties/guides/source/i18n.textile | 10 ++++----- 16 files changed, 65 insertions(+), 65 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index b2470edf00..6e26ae6c29 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1179,7 +1179,7 @@ module ActionView # helpers: # submit: # post: - # create: "Add {{model}}" + # create: "Add %{model}" # def submit(value=nil, options={}) value, options = nil, value if value.is_a?(Hash) diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 47ac911540..2234fbece9 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -33,11 +33,11 @@ class FormHelperTest < ActionView::TestCase I18n.backend.store_translations 'submit', { :helpers => { :submit => { - :create => 'Create {{model}}', - :update => 'Confirm {{model}} changes', + :create => 'Create %{model}', + :update => 'Confirm %{model} changes', :submit => 'Save changes', :another_post => { - :update => 'Update your {{model}}' + :update => 'Update your %{model}' } } } diff --git a/activemodel/lib/active_model/validations/exclusion.rb b/activemodel/lib/active_model/validations/exclusion.rb index 7ee718cf3c..2f51edfa9a 100644 --- a/activemodel/lib/active_model/validations/exclusion.rb +++ b/activemodel/lib/active_model/validations/exclusion.rb @@ -18,7 +18,7 @@ module ActiveModel # class Person < ActiveRecord::Base # validates_exclusion_of :username, :in => %w( admin superuser ), :message => "You don't belong here" # validates_exclusion_of :age, :in => 30..60, :message => "This site is only for under 30 and over 60" - # validates_exclusion_of :format, :in => %w( mov avi ), :message => "extension {{value}} is not allowed" + # validates_exclusion_of :format, :in => %w( mov avi ), :message => "extension %{value} is not allowed" # end # # Configuration options: diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb index c1838bb93e..96dc8b6e15 100644 --- a/activemodel/lib/active_model/validations/inclusion.rb +++ b/activemodel/lib/active_model/validations/inclusion.rb @@ -18,7 +18,7 @@ module ActiveModel # class Person < ActiveRecord::Base # validates_inclusion_of :gender, :in => %w( m f ) # validates_inclusion_of :age, :in => 0..99 - # validates_inclusion_of :format, :in => %w( jpg gif png ), :message => "extension {{value}} is not included in the list" + # validates_inclusion_of :format, :in => %w( jpg gif png ), :message => "extension %{value} is not included in the list" # end # # Configuration options: diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb index 9ceb75487f..95da3e93ea 100644 --- a/activemodel/lib/active_model/validations/length.rb +++ b/activemodel/lib/active_model/validations/length.rb @@ -74,9 +74,9 @@ module ActiveModel # * :in - A synonym(or alias) for :within. # * :allow_nil - Attribute may be +nil+; skip validation. # * :allow_blank - Attribute may be blank; skip validation. - # * :too_long - The error message if the attribute goes over the maximum (default is: "is too long (maximum is {{count}} characters)"). - # * :too_short - The error message if the attribute goes under the minimum (default is: "is too short (min is {{count}} characters)"). - # * :wrong_length - The error message if using the :is method and the attribute is the wrong size (default is: "is the wrong length (should be {{count}} characters)"). + # * :too_long - The error message if the attribute goes over the maximum (default is: "is too long (maximum is %{count} characters)"). + # * :too_short - The error message if the attribute goes under the minimum (default is: "is too short (min is %{count} characters)"). + # * :wrong_length - The error message if using the :is method and the attribute is the wrong size (default is: "is the wrong length (should be %{count} characters)"). # * :message - The error message to use for a :minimum, :maximum, or :is violation. An alias of the appropriate too_long/too_short/wrong_length message. # * :on - Specifies when this validation is active (default is :save, other options :create, :update). # * :if - Specifies a method, proc or string to call to determine if the validation should diff --git a/activemodel/test/cases/validations/conditional_validation_test.rb b/activemodel/test/cases/validations/conditional_validation_test.rb index 5260162a58..6866bfcf24 100644 --- a/activemodel/test/cases/validations/conditional_validation_test.rb +++ b/activemodel/test/cases/validations/conditional_validation_test.rb @@ -13,7 +13,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_if_validation_using_method_true # When the method returns true - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true ) + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => :condition_is_true ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -22,7 +22,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_unless_validation_using_method_true # When the method returns true - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true ) + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => :condition_is_true ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert t.valid? assert !t.errors[:title].any? @@ -30,7 +30,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_if_validation_using_method_false # When the method returns false - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true_but_its_not ) + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => :condition_is_true_but_its_not ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert t.valid? assert t.errors[:title].empty? @@ -38,7 +38,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_unless_validation_using_method_false # When the method returns false - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true_but_its_not ) + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => :condition_is_true_but_its_not ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -47,7 +47,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_if_validation_using_string_true # When the evaluated string returns true - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "a = 1; a == 1" ) + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => "a = 1; a == 1" ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -56,7 +56,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_unless_validation_using_string_true # When the evaluated string returns true - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "a = 1; a == 1" ) + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => "a = 1; a == 1" ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert t.valid? assert t.errors[:title].empty? @@ -64,7 +64,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_if_validation_using_string_false # When the evaluated string returns false - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "false") + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => "false") t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert t.valid? assert t.errors[:title].empty? @@ -72,7 +72,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_unless_validation_using_string_false # When the evaluated string returns false - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "false") + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => "false") t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -81,7 +81,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_if_validation_using_block_true # When the block returns true - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => Proc.new { |r| r.content.size > 4 } ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? @@ -91,7 +91,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_unless_validation_using_block_true # When the block returns true - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => Proc.new { |r| r.content.size > 4 } ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert t.valid? @@ -100,7 +100,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_if_validation_using_block_false # When the block returns false - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => Proc.new { |r| r.title != "uhohuhoh"} ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert t.valid? @@ -109,7 +109,7 @@ class ConditionalValidationTest < ActiveModel::TestCase def test_unless_validation_using_block_false # When the block returns false - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => Proc.new { |r| r.title != "uhohuhoh"} ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? diff --git a/activemodel/test/cases/validations/exclusion_validation_test.rb b/activemodel/test/cases/validations/exclusion_validation_test.rb index 7d851f546c..fffd290fa3 100644 --- a/activemodel/test/cases/validations/exclusion_validation_test.rb +++ b/activemodel/test/cases/validations/exclusion_validation_test.rb @@ -20,7 +20,7 @@ class ExclusionValidationTest < ActiveModel::TestCase end def test_validates_exclusion_of_with_formatted_message - Topic.validates_exclusion_of( :title, :in => %w( abe monkey ), :message => "option {{value}} is restricted" ) + Topic.validates_exclusion_of( :title, :in => %w( abe monkey ), :message => "option %{value} is restricted" ) assert Topic.create("title" => "something", "content" => "abc") diff --git a/activemodel/test/cases/validations/format_validation_test.rb b/activemodel/test/cases/validations/format_validation_test.rb index e10089208a..1aa6e30f6b 100644 --- a/activemodel/test/cases/validations/format_validation_test.rb +++ b/activemodel/test/cases/validations/format_validation_test.rb @@ -67,7 +67,7 @@ class PresenceValidationTest < ActiveModel::TestCase end def test_validate_format_with_formatted_message - Topic.validates_format_of(:title, :with => /^Valid Title$/, :message => "can't be {{value}}") + Topic.validates_format_of(:title, :with => /^Valid Title$/, :message => "can't be %{value}") t = Topic.create(:title => 'Invalid title') assert_equal ["can't be Invalid title"], t.errors[:title] end diff --git a/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb b/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb index 6116ef71d4..3a644c92c9 100644 --- a/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb +++ b/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb @@ -15,7 +15,7 @@ class I18nGenerateMessageValidationTest < ActiveModel::TestCase end def test_generate_message_inclusion_with_custom_message - assert_equal 'custom message title', @person.errors.generate_message(:title, :inclusion, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @person.errors.generate_message(:title, :inclusion, :default => 'custom message %{value}', :value => 'title') end # validates_exclusion_of: generate_message(attr_name, :exclusion, :default => configuration[:message], :value => value) @@ -24,7 +24,7 @@ class I18nGenerateMessageValidationTest < ActiveModel::TestCase end def test_generate_message_exclusion_with_custom_message - assert_equal 'custom message title', @person.errors.generate_message(:title, :exclusion, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @person.errors.generate_message(:title, :exclusion, :default => 'custom message %{value}', :value => 'title') end # validates_format_of: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value) @@ -33,7 +33,7 @@ class I18nGenerateMessageValidationTest < ActiveModel::TestCase end def test_generate_message_invalid_with_custom_message - assert_equal 'custom message title', @person.errors.generate_message(:title, :invalid, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @person.errors.generate_message(:title, :invalid, :default => 'custom message %{value}', :value => 'title') end # validates_confirmation_of: generate_message(attr_name, :confirmation, :default => configuration[:message]) @@ -78,7 +78,7 @@ class I18nGenerateMessageValidationTest < ActiveModel::TestCase end def test_generate_message_too_long_with_custom_message - assert_equal 'custom message 10', @person.errors.generate_message(:title, :too_long, :default => 'custom message {{count}}', :count => 10) + assert_equal 'custom message 10', @person.errors.generate_message(:title, :too_long, :default => 'custom message %{count}', :count => 10) end # validates_length_of: generate_message(attr, :too_short, :default => options[:too_short], :count => option_value.begin) @@ -87,7 +87,7 @@ class I18nGenerateMessageValidationTest < ActiveModel::TestCase end def test_generate_message_too_short_with_custom_message - assert_equal 'custom message 10', @person.errors.generate_message(:title, :too_short, :default => 'custom message {{count}}', :count => 10) + assert_equal 'custom message 10', @person.errors.generate_message(:title, :too_short, :default => 'custom message %{count}', :count => 10) end # validates_length_of: generate_message(attr, key, :default => custom_message, :count => option_value) @@ -96,7 +96,7 @@ class I18nGenerateMessageValidationTest < ActiveModel::TestCase end def test_generate_message_wrong_length_with_custom_message - assert_equal 'custom message 10', @person.errors.generate_message(:title, :wrong_length, :default => 'custom message {{count}}', :count => 10) + assert_equal 'custom message 10', @person.errors.generate_message(:title, :wrong_length, :default => 'custom message %{count}', :count => 10) end # validates_numericality_of: generate_message(attr_name, :not_a_number, :value => raw_value, :default => configuration[:message]) @@ -105,7 +105,7 @@ class I18nGenerateMessageValidationTest < ActiveModel::TestCase end def test_generate_message_not_a_number_with_custom_message - assert_equal 'custom message title', @person.errors.generate_message(:title, :not_a_number, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @person.errors.generate_message(:title, :not_a_number, :default => 'custom message %{value}', :value => 'title') end # validates_numericality_of: generate_message(attr_name, option, :value => raw_value, :default => configuration[:message]) diff --git a/activemodel/test/cases/validations/i18n_validation_test.rb b/activemodel/test/cases/validations/i18n_validation_test.rb index 1b4c1699ae..d65d94d599 100644 --- a/activemodel/test/cases/validations/i18n_validation_test.rb +++ b/activemodel/test/cases/validations/i18n_validation_test.rb @@ -58,7 +58,7 @@ class I18nValidationTest < ActiveModel::TestCase end def test_errors_full_messages_uses_format - I18n.backend.store_translations('en', :errors => {:format => "Field {{attribute}} {{message}}"}) + I18n.backend.store_translations('en', :errors => {:format => "Field %{attribute} %{message}"}) @person.errors.add('name', 'empty') assert_equal ["Field Name empty"], @person.errors.full_messages end diff --git a/activemodel/test/cases/validations/inclusion_validation_test.rb b/activemodel/test/cases/validations/inclusion_validation_test.rb index 6b2bcd9c60..45ff0175d1 100644 --- a/activemodel/test/cases/validations/inclusion_validation_test.rb +++ b/activemodel/test/cases/validations/inclusion_validation_test.rb @@ -44,7 +44,7 @@ class InclusionValidationTest < ActiveModel::TestCase end def test_validates_inclusion_of_with_formatted_message - Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :message => "option {{value}} is not in the list" ) + Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :message => "option %{value} is not in the list" ) assert Topic.create("title" => "a", "content" => "abc").valid? diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb index 99d0268b67..254e823b7c 100644 --- a/activemodel/test/cases/validations/length_validation_test.rb +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -138,7 +138,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_optionally_validates_length_of_using_within_on_create - Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: {{count}}" + Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: %{count}" t = Topic.create("title" => "thisisnotvalid", "content" => "whatever") assert !t.save @@ -159,7 +159,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_optionally_validates_length_of_using_within_on_update - Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: {{count}}" + Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: %{count}" t = Topic.create("title" => "vali", "content" => "whatever") assert !t.save @@ -230,7 +230,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_validates_length_of_custom_errors_for_minimum_with_message - Topic.validates_length_of( :title, :minimum=>5, :message=>"boo {{count}}" ) + Topic.validates_length_of( :title, :minimum=>5, :message=>"boo %{count}" ) t = Topic.create("title" => "uhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -238,7 +238,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_validates_length_of_custom_errors_for_minimum_with_too_short - Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo {{count}}" ) + Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo %{count}" ) t = Topic.create("title" => "uhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -246,7 +246,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_validates_length_of_custom_errors_for_maximum_with_message - Topic.validates_length_of( :title, :maximum=>5, :message=>"boo {{count}}" ) + Topic.validates_length_of( :title, :maximum=>5, :message=>"boo %{count}" ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -254,7 +254,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_validates_length_of_custom_errors_for_in - Topic.validates_length_of(:title, :in => 10..20, :message => "hoo {{count}}") + Topic.validates_length_of(:title, :in => 10..20, :message => "hoo %{count}") t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -267,7 +267,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_validates_length_of_custom_errors_for_maximum_with_too_long - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}" ) + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}" ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -275,7 +275,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_validates_length_of_custom_errors_for_is_with_message - Topic.validates_length_of( :title, :is=>5, :message=>"boo {{count}}" ) + Topic.validates_length_of( :title, :is=>5, :message=>"boo %{count}" ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -283,7 +283,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_validates_length_of_custom_errors_for_is_with_wrong_length - Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo {{count}}" ) + Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo %{count}" ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? assert t.errors[:title].any? @@ -349,7 +349,7 @@ class LengthValidationTest < ActiveModel::TestCase def test_optionally_validates_length_of_using_within_on_create_utf8 with_kcode('UTF8') do - Topic.validates_length_of :title, :within => 5..10, :on => :create, :too_long => "長すぎます: {{count}}" + Topic.validates_length_of :title, :within => 5..10, :on => :create, :too_long => "長すぎます: %{count}" t = Topic.create("title" => "一二三四五六七八九十A", "content" => "whatever") assert !t.save @@ -372,7 +372,7 @@ class LengthValidationTest < ActiveModel::TestCase def test_optionally_validates_length_of_using_within_on_update_utf8 with_kcode('UTF8') do - Topic.validates_length_of :title, :within => 5..10, :on => :update, :too_short => "短すぎます: {{count}}" + Topic.validates_length_of :title, :within => 5..10, :on => :update, :too_short => "短すぎます: %{count}" t = Topic.create("title" => "一二三4", "content" => "whatever") assert !t.save @@ -407,7 +407,7 @@ class LengthValidationTest < ActiveModel::TestCase end def test_validates_length_of_with_block - Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least {{count}} words.", + Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least %{count} words.", :tokenizer => lambda {|str| str.scan(/\w+/) } t = Topic.create!(:content => "this content should be long enough") assert t.valid? diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb index 38b3f87e93..1e73744649 100644 --- a/activemodel/test/cases/validations/numericality_validation_test.rb +++ b/activemodel/test/cases/validations/numericality_validation_test.rb @@ -126,13 +126,13 @@ class NumericalityValidationTest < ActiveModel::TestCase end def test_validates_numericality_with_numeric_message - Topic.validates_numericality_of :approved, :less_than => 4, :message => "smaller than {{count}}" + Topic.validates_numericality_of :approved, :less_than => 4, :message => "smaller than %{count}" topic = Topic.new("title" => "numeric test", "approved" => 10) assert !topic.valid? assert_equal ["smaller than 4"], topic.errors[:approved] - Topic.validates_numericality_of :approved, :greater_than => 4, :message => "greater than {{count}}" + Topic.validates_numericality_of :approved, :greater_than => 4, :message => "greater than %{count}" topic = Topic.new("title" => "numeric test", "approved" => 1) assert !topic.valid? diff --git a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb index 15730c2a87..8ee2a5868c 100644 --- a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb @@ -15,7 +15,7 @@ class I18nGenerateMessageValidationTest < ActiveRecord::TestCase end def test_generate_message_invalid_with_custom_message - assert_equal 'custom message title', @topic.errors.generate_message(:title, :invalid, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @topic.errors.generate_message(:title, :invalid, :default => 'custom message %{value}', :value => 'title') end # validates_uniqueness_of: generate_message(attr_name, :taken, :default => configuration[:message]) @@ -24,7 +24,7 @@ class I18nGenerateMessageValidationTest < ActiveRecord::TestCase end def test_generate_message_taken_with_custom_message - assert_equal 'custom message title', @topic.errors.generate_message(:title, :taken, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @topic.errors.generate_message(:title, :taken, :default => 'custom message %{value}', :value => 'title') end # ActiveRecord#RecordInvalid exception diff --git a/railties/guides/source/activerecord_validations_callbacks.textile b/railties/guides/source/activerecord_validations_callbacks.textile index 126a6efff5..97915d5d55 100644 --- a/railties/guides/source/activerecord_validations_callbacks.textile +++ b/railties/guides/source/activerecord_validations_callbacks.textile @@ -234,7 +234,7 @@ This helper validates that the attributes' values are not included in a given se class Account < ActiveRecord::Base validates_exclusion_of :subdomain, :in => %w(www), - :message => "Subdomain {{value}} is reserved." + :message => "Subdomain %{value} is reserved." end @@ -262,7 +262,7 @@ This helper validates that the attributes' values are included in a given set. I class Coffee < ActiveRecord::Base validates_inclusion_of :size, :in => %w(small medium large), - :message => "{{value}} is not a valid size" + :message => "%{value} is not a valid size" end @@ -290,12 +290,12 @@ The possible length constraint options are: * +:in+ (or +:within+) - The attribute length must be included in a given interval. The value for this option must be a range. * +:is+ - The attribute length must be equal to the given value. -The default error messages depend on the type of length validation being performed. You can personalize these messages using the +:wrong_length+, +:too_long+, and +:too_short+ options and {{count}} as a placeholder for the number corresponding to the length constraint being used. You can still use the +:message+ option to specify an error message. +The default error messages depend on the type of length validation being performed. You can personalize these messages using the +:wrong_length+, +:too_long+, and +:too_short+ options and %{count} as a placeholder for the number corresponding to the length constraint being used. You can still use the +:message+ option to specify an error message. class Person < ActiveRecord::Base validates_length_of :bio, :maximum => 1000, - :too_long => "{{count}} characters is the maximum allowed" + :too_long => "%{count} characters is the maximum allowed" end @@ -307,8 +307,8 @@ class Essay < ActiveRecord::Base :minimum => 300, :maximum => 400, :tokenizer => lambda { |str| str.scan(/\w+/) }, - :too_short => "must have at least {{count}} words", - :too_long => "must have at most {{count}} words" + :too_short => "must have at least %{count} words", + :too_long => "must have at most %{count} words" end @@ -337,11 +337,11 @@ end Besides +:only_integer+, the +validates_numericality_of+ helper also accepts the following options to add constraints to acceptable values: -* +:greater_than+ - Specifies the value must be greater than the supplied value. The default error message for this option is "_must be greater than {{count}}_". -* +:greater_than_or_equal_to+ - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "_must be greater than or equal to {{count}}_". -* +:equal_to+ - Specifies the value must be equal to the supplied value. The default error message for this option is "_must be equal to {{count}}_". -* +:less_than+ - Specifies the value must be less than the supplied value. The default error message for this option is "_must be less than {{count}}_". -* +:less_than_or_equal_to+ - Specifies the value must be less than or equal the supplied value. The default error message for this option is "_must be less or equal to {{count}}_". +* +:greater_than+ - Specifies the value must be greater than the supplied value. The default error message for this option is "_must be greater than %{count}_". +* +:greater_than_or_equal_to+ - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "_must be greater than or equal to %{count}_". +* +:equal_to+ - Specifies the value must be equal to the supplied value. The default error message for this option is "_must be equal to %{count}_". +* +:less_than+ - Specifies the value must be less than the supplied value. The default error message for this option is "_must be less than %{count}_". +* +:less_than_or_equal_to+ - Specifies the value must be less than or equal the supplied value. The default error message for this option is "_must be less or equal to %{count}_". * +:odd+ - Specifies the value must be an odd number if set to true. The default error message for this option is "_must be odd_". * +:even+ - Specifies the value must be an even number if set to true. The default error message for this option is "_must be even_". @@ -469,7 +469,7 @@ The +:allow_nil+ option skips the validation when the value being validated is + class Coffee < ActiveRecord::Base validates_inclusion_of :size, :in => %w(small medium large), - :message => "{{value}} is not a valid size", :allow_nil => true + :message => "%{value} is not a valid size", :allow_nil => true end diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index dcad451e23..bb383d3cf9 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -531,7 +531,7 @@ In many cases you want to abstract your translations so that *variables can be i All options besides +:default+ and +:scope+ that are passed to +#translate+ will be interpolated to the translation: -I18n.backend.store_translations :en, :thanks => 'Thanks {{name}}!' +I18n.backend.store_translations :en, :thanks => 'Thanks %{name}!' I18n.translate :thanks, :name => 'Jeremy' # => 'Thanks Jeremy!' @@ -547,7 +547,7 @@ The +:count+ interpolation variable has a special role in that it both is interp I18n.backend.store_translations :en, :inbox => { :one => '1 message', - :other => '{{count}} messages' + :other => '%{count} messages' } I18n.translate :inbox, :count => 2 # => '2 messages' @@ -711,7 +711,7 @@ h5. Error Message Interpolation The translated model name, translated attribute name, and value are always available for interpolation. -So, for example, instead of the default error message +"can not be blank"+ you could use the attribute name like this : +"Please fill in your {{attribute}}"+. +So, for example, instead of the default error message +"can not be blank"+ you could use the attribute name like this : +"Please fill in your %{attribute}"+. * +count+, where available, can be used for pluralization if present: @@ -750,8 +750,8 @@ en: errors: template: header: - one: "1 error prohibited this {{model}} from being saved" - other: "{{count}} errors prohibited this {{model}} from being saved" + one: "1 error prohibited this %{model} from being saved" + other: "%{count} errors prohibited this %{model} from being saved" body: "There were problems with the following fields:" -- cgit v1.2.3 From 36fc489aa3086e384db9f13390f01246d006e47e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 3 May 2010 13:44:11 +0200 Subject: Update I18n gem to 0.4.0.beta1 [#4525 state:resolved]. --- activesupport/activesupport.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec index 0fea84a6ef..cfd85f61c9 100644 --- a/activesupport/activesupport.gemspec +++ b/activesupport/activesupport.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |s| s.has_rdoc = true - s.add_dependency('i18n', '~> 0.4.0.beta') + s.add_dependency('i18n', '~> 0.4.0.beta1') s.add_dependency('tzinfo', '~> 0.3.16') s.add_dependency('builder', '~> 2.1.2') s.add_dependency('memcache-client', '>= 1.7.5') -- cgit v1.2.3 From 849ab9294244ac94f9ce4621c8cd325a2992a382 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 29 Apr 2010 08:18:47 -0500 Subject: Eliminate false positives when passing symbols to assert_template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- actionpack/lib/action_controller/test_case.rb | 3 ++- .../test/controller/action_pack_assertions_test.rb | 29 +++++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 2010d8573c..34499fa784 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -57,7 +57,8 @@ module ActionController validate_request! case options - when NilClass, String + when NilClass, String, Symbol + options = options.to_s if Symbol === options rendered = @templates msg = build_message(message, "expecting but rendering with ", diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index 1741b58f72..eae2641dc0 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -349,21 +349,43 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase assert_template :partial => '_partial' end - def test_assert_template_with_nil + def test_assert_template_with_nil_passes_when_no_template_rendered get :nothing assert_template nil end - def test_assert_template_with_string + def test_assert_template_with_nil_fails_when_template_rendered + get :hello_world + assert_raise(ActiveSupport::TestCase::Assertion) do + assert_template nil + end + end + + def test_assert_template_passes_with_correct_string get :hello_world assert_template 'hello_world' + assert_template 'test/hello_world' end - def test_assert_template_with_symbol + def test_assert_template_passes_with_correct_symbol get :hello_world assert_template :hello_world end + def test_assert_template_fails_with_incorrect_string + get :hello_world + assert_raise(ActiveSupport::TestCase::Assertion) do + assert_template 'hello_planet' + end + end + + def test_assert_template_fails_with_incorrect_symbol + get :hello_world + assert_raise(ActiveSupport::TestCase::Assertion) do + assert_template :hello_planet + end + end + # check if we were rendered by a file-based template? def test_rendered_action process :nothing @@ -387,7 +409,6 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase assert_nil @response.redirect_url end - # check server errors def test_server_error_response_code process :response500 -- cgit v1.2.3 From b3dcbedc67f49ef64f33570f3e24ac00a47c0181 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 29 Apr 2010 09:29:35 -0500 Subject: move assert_template tests to their own test case [#4501 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- .../test/controller/action_pack_assertions_test.rb | 87 ++++++++++++---------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index eae2641dc0..765e111226 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -344,47 +344,6 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase end end - def test_assert_template_with_partial - get :partial - assert_template :partial => '_partial' - end - - def test_assert_template_with_nil_passes_when_no_template_rendered - get :nothing - assert_template nil - end - - def test_assert_template_with_nil_fails_when_template_rendered - get :hello_world - assert_raise(ActiveSupport::TestCase::Assertion) do - assert_template nil - end - end - - def test_assert_template_passes_with_correct_string - get :hello_world - assert_template 'hello_world' - assert_template 'test/hello_world' - end - - def test_assert_template_passes_with_correct_symbol - get :hello_world - assert_template :hello_world - end - - def test_assert_template_fails_with_incorrect_string - get :hello_world - assert_raise(ActiveSupport::TestCase::Assertion) do - assert_template 'hello_planet' - end - end - - def test_assert_template_fails_with_incorrect_symbol - get :hello_world - assert_raise(ActiveSupport::TestCase::Assertion) do - assert_template :hello_planet - end - end # check if we were rendered by a file-based template? def test_rendered_action @@ -559,6 +518,52 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase end end +class AssertTemplateTest < ActionController::TestCase + tests ActionPackAssertionsController + + def test_with_partial + get :partial + assert_template :partial => '_partial' + end + + def test_with_nil_passes_when_no_template_rendered + get :nothing + assert_template nil + end + + def test_with_nil_fails_when_template_rendered + get :hello_world + assert_raise(ActiveSupport::TestCase::Assertion) do + assert_template nil + end + end + + def test_passes_with_correct_string + get :hello_world + assert_template 'hello_world' + assert_template 'test/hello_world' + end + + def test_passes_with_correct_symbol + get :hello_world + assert_template :hello_world + end + + def test_fails_with_incorrect_string + get :hello_world + assert_raise(ActiveSupport::TestCase::Assertion) do + assert_template 'hello_planet' + end + end + + def test_fails_with_incorrect_symbol + get :hello_world + assert_raise(ActiveSupport::TestCase::Assertion) do + assert_template :hello_planet + end + end +end + class ActionPackHeaderTest < ActionController::TestCase tests ActionPackAssertionsController -- cgit v1.2.3 From 756f762cdb1ee5ad0046e40e3620399d1707fee7 Mon Sep 17 00:00:00 2001 From: Norman Clarke Date: Mon, 3 May 2010 10:16:38 -0300 Subject: Fix transliteration rule example in docs. [#4526 state:resolved] Signed-off-by: Xavier Noria --- activesupport/lib/active_support/inflector/transliterate.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/activesupport/lib/active_support/inflector/transliterate.rb b/activesupport/lib/active_support/inflector/transliterate.rb index 5ec87372d0..2c9115c427 100644 --- a/activesupport/lib/active_support/inflector/transliterate.rb +++ b/activesupport/lib/active_support/inflector/transliterate.rb @@ -24,8 +24,9 @@ module ActiveSupport # # Store the transliterations in locales/de.yml # i18n: # transliterate: - # ü: "ue" - # ö: "oe" + # :rule + # ü: "ue" + # ö: "oe" # # # Or set them using Ruby # I18n.backend.store_translations(:de, :i18n => { -- cgit v1.2.3 From 34d57251672d31e70d3ce53e1df3ea9dd4aae9c8 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 3 May 2010 15:25:28 +0200 Subject: fixes colon in previous YAML example --- activesupport/lib/active_support/inflector/transliterate.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/inflector/transliterate.rb b/activesupport/lib/active_support/inflector/transliterate.rb index 2c9115c427..2344bb1bb3 100644 --- a/activesupport/lib/active_support/inflector/transliterate.rb +++ b/activesupport/lib/active_support/inflector/transliterate.rb @@ -24,7 +24,7 @@ module ActiveSupport # # Store the transliterations in locales/de.yml # i18n: # transliterate: - # :rule + # rule: # ü: "ue" # ö: "oe" # -- cgit v1.2.3 From 9e085a9f3365e316e2026addedef30f08ead46f2 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 3 May 2010 22:04:47 +0200 Subject: adds a comment explaining why BigDecimal#as_json returns a JSON string --- activesupport/lib/active_support/json/encoding.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index 3d7be8da1f..02c233595d 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -1,7 +1,7 @@ # encoding: utf-8 require 'bigdecimal' require 'active_support/core_ext/array/wrap' -require 'active_support/core_ext/big_decimal/conversions' +require 'active_support/core_ext/big_decimal/conversions' # for #to_s require 'active_support/core_ext/hash/except' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/module/delegation' @@ -179,6 +179,14 @@ class Numeric end class BigDecimal + # A BigDecimal would be naturally represented as a JSON number. Most libraries, + # however, parse non-integer JSON numbers directly as floats. Clients using + # those libraries would get in general a wrong number and no way to recover + # other than manually inspecting the string with the JSON code itself. + # + # That's why a JSON string is returned. The JSON literal is not numeric, but if + # the other end knows by contract that the data is supposed to be a BigDecimal, + # it still has the chance to post-process the string and get the real value. def as_json(options = nil) to_s end #:nodoc: end -- cgit v1.2.3 From 5d7d0c2fa31d72bc70fdd1b1e34144da9055995d Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 3 May 2010 22:10:36 +0200 Subject: BigDecimal#as_json does not really specify the F format, it delegates that to whatever BigDecimal#to_s default format is, do the same in its test --- activesupport/test/json/encoding_test.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index ac7ca96c4d..a8ecf4e4cf 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -1,5 +1,7 @@ # encoding: utf-8 require 'abstract_unit' +require 'bigdecimal' +require 'active_support/core_ext/big_decimal/conversions' require 'active_support/json' class TestJSONEncoding < Test::Unit::TestCase @@ -26,7 +28,7 @@ class TestJSONEncoding < Test::Unit::TestCase NilTests = [[ nil, %(null) ]] NumericTests = [[ 1, %(1) ], [ 2.5, %(2.5) ], - [ BigDecimal('2.5'), %("#{BigDecimal('2.5').to_s('F')}") ]] + [ BigDecimal('2.5'), %("#{BigDecimal('2.5').to_s}") ]] StringTests = [[ 'this is the ', %("this is the \\u003Cstring\\u003E")], [ 'a "string" with quotes & an ampersand', %("a \\"string\\" with quotes \\u0026 an ampersand") ], -- cgit v1.2.3 From 6704d8c994d9d20d0cc9d71b72521e141c7dc05d Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 3 May 2010 23:11:09 +0200 Subject: date/conversions needs time/calculations for (utc|local)_time --- activesupport/lib/active_support/core_ext/date/conversions.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb index 90ab1eb281..13ef703f49 100644 --- a/activesupport/lib/active_support/core_ext/date/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date/conversions.rb @@ -1,5 +1,6 @@ require 'date' require 'active_support/inflector' +require 'active_support/core_ext/time/calculations' class Date DATE_FORMATS = { -- cgit v1.2.3 From 841c01fa0fa92aa6e3c2e5029444a9cbb4f161f3 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Tue, 4 May 2010 17:51:22 +0100 Subject: Use class_inheritable_accessor for connection_handler --- .../connection_adapters/abstract/connection_specification.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb index 2f36bec764..2493095a04 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb @@ -10,8 +10,8 @@ module ActiveRecord ## # :singleton-method: # The connection handler - cattr_accessor :connection_handler, :instance_writer => false - @@connection_handler = ConnectionAdapters::ConnectionHandler.new + class_inheritable_accessor :connection_handler, :instance_writer => false + self.connection_handler = ConnectionAdapters::ConnectionHandler.new # Returns the connection currently associated with the class. This can # also be used to "borrow" the connection to do database work that isn't @@ -54,7 +54,7 @@ module ActiveRecord raise AdapterNotSpecified unless defined?(Rails.env) establish_connection(Rails.env) when ConnectionSpecification - @@connection_handler.establish_connection(name, spec) + self.connection_handler.establish_connection(name, spec) when Symbol, String if configuration = configurations[spec.to_s] establish_connection(configuration) -- cgit v1.2.3 From fb30feb48bc755018494ac98bb1b96bb7a7c5ecb Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sun, 2 May 2010 20:38:09 +1000 Subject: Adding more docs to ActionMailer --- actionmailer/lib/action_mailer/base.rb | 62 +++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index fd7b969496..f822e14cad 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -196,21 +196,59 @@ module ActionMailer #:nodoc: # the delivery agents. Your object should make and needed modifications directly to the passed # in Mail::Message instance. # + # = Default Hash + # + # ActionMailer provides some intelligent defaults for your emails, these are usually specified in a + # default method inside the class definition: + # + # class Notifier < ActionMailer::Base + # default :sender => 'system@example.com' + # end + # + # You can pass in any header value that a Mail::Message, out of the box, ActionMailer::Base + # sets the following: + # + # * :mime_version => "1.0" + # * :charset => "UTF-8", + # * :content_type => "text/plain", + # * :parts_order => [ "text/plain", "text/enriched", "text/html" ] + # + # parts_order and charset are not actually valid Mail::Message header fields, + # but ActionMailer translates them appropriately and sets the correct values. + # + # As you can pass in any header, you need to either quote the header as a string, or pass it in as + # an underscorised symbol, so the following will work: + # + # class Notifier < ActionMailer::Base + # default 'Content-Transfer-Encoding' => '7bit', + # :content_description => 'This is a description' + # end + # + # Finally, ActionMailer also supports passing Proc objects into the default hash, so you + # can define methods that evaluate as the message is being generated: + # + # class Notifier < ActionMailer::Base + # default 'X-Special-Header' => Proc.new { my_method } + # + # private + # + # def my_method + # 'some complex call' + # end + # end + # + # Note that the proc is evaluated right at the start of the mail message generation, so if you + # set something in the defaults using a proc, and then set the same thing inside of your + # mailer method, it will get over written by the mailer method. + # # = Configuration options # - # These options are specified on the class level, like ActionMailer::Base.template_root = "/my/templates" - # - # * default - This is a class wide hash of :key => value pairs containing - # default values for the specified header fields of the Mail::Message. You can - # specify a default for any valid header for Mail::Message and it will be used if - # you do not override it. You pass in the header value as a symbol, all lower case with under - # scores instead of hyphens, so Content-Transfer-Encoding: - # becomes :content_transfer_encoding. The defaults set by Action Mailer are: - # * :mime_version => "1.0" - # * :charset => "UTF-8", - # * :content_type => "text/plain", - # * :parts_order => [ "text/plain", "text/enriched", "text/html" ] + # These options are specified on the class level, like + # ActionMailer::Base.template_root = "/my/templates" # + # * default - You can pass this in at a class level as well as within the class itself as + # per the above section. + # # * logger - the logger is used for generating information on the mailing run if available. # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers. # -- cgit v1.2.3 From 058f7feafe13024f594ba1e157305c36c20e1d2e Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sun, 2 May 2010 21:48:46 +1000 Subject: Cleaning up Action Mailer spelling with and without the space --- actionmailer/lib/action_mailer.rb | 2 +- actionmailer/lib/action_mailer/base.rb | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 46168d9a4a..70cc312634 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -27,7 +27,7 @@ $:.unshift(actionpack_path) if File.directory?(actionpack_path) && !$:.include?( require 'abstract_controller' require 'action_view' -# Common ActiveSupport usage in ActionMailer +# Common Active Support usage in Action Mailer require 'active_support/core_ext/class' require 'active_support/core_ext/object/blank' require 'active_support/core_ext/array/uniq_by' diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index f822e14cad..88298966eb 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -13,7 +13,7 @@ module ActionMailer #:nodoc: # # $ rails generate mailer Notifier # - # The generated model inherits from ActionMailer::Base. Emails are defined by creating methods + # The generated model inherits from ActionMailer::Base. Emails are defined by creating methods # within the model which are then used to set variables to be used in the mail template, to # change options on the mail, or to add attachments. # @@ -185,7 +185,7 @@ module ActionMailer #:nodoc: # # = Observing and Intercepting Mails # - # ActionMailer provides hooks into the Mail observer and interceptor methods. These allow you to + # Action Mailer provides hooks into the Mail observer and interceptor methods. These allow you to # register objects that are called during the mail delivery life cycle. # # An observer object must implement the :delivered_email(message) method which will be @@ -198,7 +198,7 @@ module ActionMailer #:nodoc: # # = Default Hash # - # ActionMailer provides some intelligent defaults for your emails, these are usually specified in a + # Action Mailer provides some intelligent defaults for your emails, these are usually specified in a # default method inside the class definition: # # class Notifier < ActionMailer::Base @@ -214,7 +214,7 @@ module ActionMailer #:nodoc: # * :parts_order => [ "text/plain", "text/enriched", "text/html" ] # # parts_order and charset are not actually valid Mail::Message header fields, - # but ActionMailer translates them appropriately and sets the correct values. + # but Action Mailer translates them appropriately and sets the correct values. # # As you can pass in any header, you need to either quote the header as a string, or pass it in as # an underscorised symbol, so the following will work: @@ -224,7 +224,7 @@ module ActionMailer #:nodoc: # :content_description => 'This is a description' # end # - # Finally, ActionMailer also supports passing Proc objects into the default hash, so you + # Finally, Action Mailer also supports passing Proc objects into the default hash, so you # can define methods that evaluate as the message is being generated: # # class Notifier < ActionMailer::Base @@ -478,7 +478,7 @@ module ActionMailer #:nodoc: # Both methods accept a headers hash. This hash allows you to specify the most used headers # in an email message, these are: # - # * :subject - The subject of the message, if this is omitted, ActionMailer will + # * :subject - The subject of the message, if this is omitted, Action Mailer will # ask the Rails I18n class for a translated :subject in the scope of # [:actionmailer, mailer_scope, action_name] or if this is missing, will translate the # humanized version of the action_name -- cgit v1.2.3 From c8d03fbe9ba461a0b635dcb85759cc4a2261ba95 Mon Sep 17 00:00:00 2001 From: Joe Hannon Date: Sun, 2 May 2010 15:55:58 -0700 Subject: grammatical error 'uses' -> 'use' --- railties/guides/source/active_record_querying.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index e47615f070..1cfec1cf77 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -17,7 +17,7 @@ If you're used to using raw SQL to find database records then, generally, you wi Code examples throughout this guide will refer to one or more of the following models: -TIP: All of the following models uses +id+ as the primary key, unless specified otherwise. +TIP: All of the following models use +id+ as the primary key, unless specified otherwise.
-- cgit v1.2.3 From d38b4771f1bf6b7c16f47ec395865e074b64606b Mon Sep 17 00:00:00 2001 From: logylaps Date: Tue, 4 May 2010 02:17:36 -0700 Subject: typo 'main.cs' -> 'main.css', and textile typo 'h6(:has_many-group)' -> 'h6(#has_many-group)', and typo. missing 'if' --- railties/guides/source/active_record_querying.textile | 2 +- railties/guides/source/association_basics.textile | 2 +- railties/guides/source/layouts_and_rendering.textile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index 1cfec1cf77..e18dbc9c42 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -802,7 +802,7 @@ will either assign an existing client object with the name "Ryan" to the client h3. Finding by SQL -If you'd like to use your own SQL to find records in a table you can use +find_by_sql+. The +find_by_sql+ method will return an array of objects even the underlying query returns just a single record. For example you could run this query: +If you'd like to use your own SQL to find records in a table you can use +find_by_sql+. The +find_by_sql+ method will return an array of objects even if the underlying query returns just a single record. For example you could run this query: Client.find_by_sql("SELECT * FROM clients diff --git a/railties/guides/source/association_basics.textile b/railties/guides/source/association_basics.textile index f13f6db6ee..335d17579d 100644 --- a/railties/guides/source/association_basics.textile +++ b/railties/guides/source/association_basics.textile @@ -1262,7 +1262,7 @@ end TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations. -h6(:has_many-group). +:group+ +h6(#has_many-group). +:group+ The +:group+ option supplies an attribute name to group the result set by, using a +GROUP BY+ clause in the finder SQL. diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 92b36ab3e4..f6b6a1a7cc 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -747,7 +747,7 @@ You can even use dynamic paths such as +cache/#{current_site}/main/display+. h5. Linking to CSS Files with +stylesheet_link_tag+ -The +stylesheet_link_tag+ helper returns an HTML +<link>+ tag for each source provided. Rails looks in +public/stylesheets+ for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include +public/stylesheets/main.cs+: +The +stylesheet_link_tag+ helper returns an HTML +<link>+ tag for each source provided. Rails looks in +public/stylesheets+ for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include +public/stylesheets/main.css+: <%= stylesheet_link_tag "main" %> -- cgit v1.2.3 From d5e3c494781abe0b16b4e40f597ff64f8ad6512f Mon Sep 17 00:00:00 2001 From: mica eked Date: Tue, 4 May 2010 02:46:21 -0700 Subject: typo "" -> "", and typo 'follow' -> 'following' --- railties/guides/source/layouts_and_rendering.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index f6b6a1a7cc..7be369453e 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -806,7 +806,7 @@ You can even use dynamic paths such as +cache/#{current_site}/main/display+. h5. Linking to Images with +image_tag+ -The +image_tag+ helper builds an HTML +<image />+ tag to the specified file. By default, files are loaded from +public/images+, note, you must specify the extension, previous versions of Rails would allow you to just call the image name and would append +.png+ if no extension was given, Rails 3.0 does not. +The +image_tag+ helper builds an HTML +<img />+ tag to the specified file. By default, files are loaded from +public/images+, note, you must specify the extension, previous versions of Rails would allow you to just call the image name and would append +.png+ if no extension was given, Rails 3.0 does not. <%= image_tag "header.png" %> @@ -1154,7 +1154,7 @@ h4. Using Nested Layouts You may find that your application requires a layout that differs slightly from your regular application layout to support one particular controller. Rather than repeating the main layout and editing it, you can accomplish this by using nested layouts (sometimes called sub-templates). Here's an example: -Suppose you have the follow +ApplicationController+ layout: +Suppose you have the following +ApplicationController+ layout: * +app/views/layouts/application.html.erb+ -- cgit v1.2.3 From 0dd3b4630fea4bd4d4010b7096c9ee79d34c4501 Mon Sep 17 00:00:00 2001 From: Josiah Ivey Date: Tue, 4 May 2010 09:52:31 -0500 Subject: image_tag should be audio_tag, and change typo 'image' to 'audio file' --- railties/guides/source/layouts_and_rendering.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 7be369453e..a874fa0ca7 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -895,10 +895,10 @@ The +audio_tag+ helper builds an HTML 5 +<audio>+ tag to the specified fil <%= audio_tag "music.mp3" %> -You can supply a path to the image if you like: +You can supply a path to the audio file if you like: -<%= image_tag "music/first_song.mp3" %> +<%= audio_tag "music/first_song.mp3" %> You can also supply a hash of additional options, such as +:id+, +:class+ etc. -- cgit v1.2.3