From 106c988c10c29332343d8de5719a8b045d093753 Mon Sep 17 00:00:00 2001 From: Vasiliy Ermolovich Date: Sun, 27 Oct 2013 18:14:16 +0300 Subject: add include_hidden option to collection_check_boxes helper --- actionview/CHANGELOG.md | 6 +++++- .../lib/action_view/helpers/tags/collection_check_boxes.rb | 10 +++++++--- actionview/test/template/form_collections_helper_test.rb | 7 +++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 59b803d088..959509510e 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,6 +1,10 @@ +* Add `include_hidden` option to `collection_check_boxes` helper. + + *Vasiliy Ermolovich* + * Ensure ActionView::Digestor.cache is correctly cleaned up when combining recursive templates with ActionView::Resolver.caching = false - + *wyaeld* * Fix `collection_check_boxes` generated hidden input to use the name attribute provided diff --git a/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb b/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb index 9b77ebeb1b..8b28e4fc33 100644 --- a/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb +++ b/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb @@ -27,10 +27,14 @@ module ActionView # Append a hidden field to make sure something will be sent back to the # server if all check boxes are unchecked. - hidden_name = @html_options[:name] || "#{tag_name}[]" - hidden = @template_object.hidden_field_tag(hidden_name, "", :id => nil) + if @options.fetch(:include_hidden, true) + hidden_name = @html_options[:name] || "#{tag_name}[]" + hidden = @template_object.hidden_field_tag(hidden_name, "", :id => nil) - rendered_collection + hidden + rendered_collection + hidden + else + rendered_collection + end end private diff --git a/actionview/test/template/form_collections_helper_test.rb b/actionview/test/template/form_collections_helper_test.rb index d28e4aeb48..4e9cd74df5 100644 --- a/actionview/test/template/form_collections_helper_test.rb +++ b/actionview/test/template/form_collections_helper_test.rb @@ -186,6 +186,13 @@ class FormCollectionsHelperTest < ActionView::TestCase assert_select "input[type=hidden][name='user[other_category_ids][]'][value=]", :count => 1 end + test 'collection check boxes does not generate a hidden field if include_hidden option is false' do + collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')] + with_collection_check_boxes :user, :category_ids, collection, :id, :name, include_hidden: false + + assert_select "input[type=hidden][name='user[category_ids][]'][value=]", :count => 0 + end + test 'collection check boxes accepts a collection and generate a serie of checkboxes with labels for label method' do collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')] with_collection_check_boxes :user, :category_ids, collection, :id, :name -- cgit v1.2.3 From 025c691536b22cc3f0ba802f6c303dd6f955c1c3 Mon Sep 17 00:00:00 2001 From: Piotr Chmolowski Date: Sat, 8 Mar 2014 23:09:54 +0100 Subject: Ensure LookupContext in Digestor selects correct variant Related to: #14242 #14243 14293 Variants passed to LookupContext#find() seem to be ignored, so I've used the setter instead: `finder.variants = [ variant ]`. I've also added some more test cases for variants. Hopefully this time passing tests will mean it actually works. --- actionpack/test/controller/caching_test.rb | 21 +++++++++++++++++++++ ...tted_fragment_cached_with_variant.html+phone.erb | 3 +++ actionview/lib/action_view/digestor.rb | 5 ++++- actionview/lib/action_view/helpers/cache_helper.rb | 18 ++++++++++++++---- .../test/fixtures/test/hello_world.html+phone.erb | 1 + .../test/fixtures/test/hello_world.text+phone.erb | 1 + actionview/test/template/digestor_test.rb | 8 +++++--- actionview/test/template/lookup_context_test.rb | 14 ++++++++++++++ 8 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 actionpack/test/fixtures/functional_caching/formatted_fragment_cached_with_variant.html+phone.erb create mode 100644 actionview/test/fixtures/test/hello_world.html+phone.erb create mode 100644 actionview/test/fixtures/test/hello_world.text+phone.erb diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 591d0eccc3..0ba8045cb5 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -164,6 +164,13 @@ class FunctionalCachingController < CachingController end end + def formatted_fragment_cached_with_variant + respond_to do |format| + format.html.phone + format.html + end + end + def fragment_cached_without_digest end end @@ -242,6 +249,20 @@ CACHED @store.read("views/test.host/functional_caching/formatted_fragment_cached/#{template_digest("functional_caching/formatted_fragment_cached", "xml")}") end + + def test_fragment_caching_with_variant + @request.variant = :phone + + get :formatted_fragment_cached_with_variant, :format => "html", :variant => :phone + assert_response :success + expected_body = "\n

PHONE

\n\n" + + assert_equal expected_body, @response.body + + assert_equal "

PHONE

", + @store.read("views/test.host/functional_caching/formatted_fragment_cached_with_variant/#{template_digest("functional_caching/formatted_fragment_cached_with_variant", :html, :phone)}") + end + private def template_digest(name, format, variant = nil) ActionView::Digestor.digest(name: name, format: format, variant: variant, finder: @controller.lookup_context) diff --git a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached_with_variant.html+phone.erb b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached_with_variant.html+phone.erb new file mode 100644 index 0000000000..e523b74ae3 --- /dev/null +++ b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached_with_variant.html+phone.erb @@ -0,0 +1,3 @@ + +<%= cache do %>

PHONE

<% end %> + diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index da43fef2e3..4e3773abe7 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -126,7 +126,10 @@ module ActionView end def template - @template ||= finder.find(logical_name, [], partial?, formats: [ format ], variants: [ variant ]) + @template ||= begin + finder.variants = [ variant ] + finder.find(logical_name, [], partial?, formats: [ format ]) + end end def source diff --git a/actionview/lib/action_view/helpers/cache_helper.rb b/actionview/lib/action_view/helpers/cache_helper.rb index 30e4e5e329..3177d18c4d 100644 --- a/actionview/lib/action_view/helpers/cache_helper.rb +++ b/actionview/lib/action_view/helpers/cache_helper.rb @@ -165,10 +165,20 @@ module ActionView def fragment_name_with_digest(name) #:nodoc: if @virtual_path - [ - *Array(name.is_a?(Hash) ? controller.url_for(name).split("://").last : name), - Digestor.digest(name: @virtual_path, format: formats.last.to_sym, variant: request.variant, finder: lookup_context, dependencies: view_cache_dependencies) - ] + variant = request.variant.is_a?(Array) ? request.variant.first : request.variant + + options = { + name: @virtual_path, + format: formats.last.to_sym, + variant: variant, + finder: lookup_context, + dependencies: view_cache_dependencies + } + + names = Array(name.is_a?(Hash) ? controller.url_for(name).split("://").last : name) + digest = Digestor.digest(options) + + [*names, digest] else name end diff --git a/actionview/test/fixtures/test/hello_world.html+phone.erb b/actionview/test/fixtures/test/hello_world.html+phone.erb new file mode 100644 index 0000000000..b4f236f878 --- /dev/null +++ b/actionview/test/fixtures/test/hello_world.html+phone.erb @@ -0,0 +1 @@ +Hello phone! \ No newline at end of file diff --git a/actionview/test/fixtures/test/hello_world.text+phone.erb b/actionview/test/fixtures/test/hello_world.text+phone.erb new file mode 100644 index 0000000000..611e2ee442 --- /dev/null +++ b/actionview/test/fixtures/test/hello_world.text+phone.erb @@ -0,0 +1 @@ +Hello texty phone! \ No newline at end of file diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index 2406a64310..0580758dab 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -15,10 +15,12 @@ end class FixtureFinder FIXTURES_DIR = "#{File.dirname(__FILE__)}/../fixtures/digestor" - attr_reader :details + attr_reader :details + attr_accessor :variants def initialize - @details = {} + @details = {} + @variants = [] end def details_key @@ -28,7 +30,7 @@ class FixtureFinder def find(logical_name, keys, partial, options) partial_name = partial ? logical_name.gsub(%r|/([^/]+)$|, '/_\1') : logical_name format = options[:formats].first.to_s - format += "+#{options[:variants].first}" if options[:variants].any? + format += "+#{@variants.first}" if @variants.any? FixtureTemplate.new("digestor/#{partial_name}.#{format}.erb") end diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb index ce9485e146..4f7823045e 100644 --- a/actionview/test/template/lookup_context_test.rb +++ b/actionview/test/template/lookup_context_test.rb @@ -93,6 +93,20 @@ class LookupContextTest < ActiveSupport::TestCase assert_equal "Hey verden", template.source end + test "find templates with given variants" do + @lookup_context.formats = [:html] + @lookup_context.variants = [:phone] + + template = @lookup_context.find("hello_world", %w(test)) + assert_equal "Hello phone!", template.source + + @lookup_context.variants = [:phone] + @lookup_context.formats = [:text] + + template = @lookup_context.find("hello_world", %w(test)) + assert_equal "Hello texty phone!", template.source + end + test "found templates respects given formats if one cannot be found from template or handler" do ActionView::Template::Handlers::Builder.expects(:default_format).returns(nil) @lookup_context.formats = [:text] -- cgit v1.2.3 From f72feae9bafbadfd4da4e383bb302afc33c7d3e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Tue, 11 Mar 2014 16:30:00 +0100 Subject: Don't pass variant in params, it's ignored We're setting variant above, in request object directly --- actionpack/test/controller/caching_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 0ba8045cb5..9923b90bae 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -253,7 +253,7 @@ CACHED def test_fragment_caching_with_variant @request.variant = :phone - get :formatted_fragment_cached_with_variant, :format => "html", :variant => :phone + get :formatted_fragment_cached_with_variant, :format => "html" assert_response :success expected_body = "\n

PHONE

\n\n" -- cgit v1.2.3 From 0ca6836a5a5dc249f82c98d34e17205a559157cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Tue, 11 Mar 2014 16:30:58 +0100 Subject: Don't create addition vars, use options[] directly --- actionview/lib/action_view/digestor.rb | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 4e3773abe7..df6e7bba60 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -20,14 +20,9 @@ module ActionView def digest(*args) options = _setup_options(*args) - name = options[:name] - format = options[:format] - variant = options[:variant] - finder = options[:finder] - - details_key = finder.details_key.hash + details_key = options[:finder].details_key.hash dependencies = Array.wrap(options[:dependencies]) - cache_key = ([name, details_key, format, variant].compact + dependencies).join('.') + cache_key = ([options[:name], details_key, options[:format], options[:variant]].compact + dependencies).join('.') # this is a correctly done double-checked locking idiom # (ThreadSafe::Cache's lookups have volatile semantics) -- cgit v1.2.3 From d3d3d07d99ea8fbfa242a6c2cfa7279aea51bc7c Mon Sep 17 00:00:00 2001 From: Lauro Caetano Date: Thu, 13 Mar 2014 15:57:35 -0300 Subject: Test deprecation warning for passing an ActiveRecord object to `exists?` --- activerecord/test/cases/finder_test.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index af33caefa5..9adfc72634 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -61,6 +61,12 @@ class FinderTest < ActiveRecord::TestCase assert_raise(NoMethodError) { Topic.exists?([1,2]) } end + def test_exists_passing_active_record_object_is_deprecated + assert_deprecated do + Topic.exists?(Topic.new) + end + end + def test_exists_fails_when_parameter_has_invalid_type if current_adapter?(:PostgreSQLAdapter, :MysqlAdapter) assert_raises ActiveRecord::StatementInvalid do -- cgit v1.2.3 From 433b19d7e82263fb78c481576ed0f475a62fde06 Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Thu, 13 Mar 2014 13:05:10 -0400 Subject: Make select_all on query cache accept a Relation without binds. [fixes #14361] [related #13886] --- activerecord/CHANGELOG.md | 6 ++++++ .../abstract/database_statements.rb | 21 +++++++++------------ .../connection_adapters/abstract/query_cache.rb | 1 + activerecord/test/cases/query_cache_test.rb | 8 ++++++++ 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index d52c2f711e..d6044988f0 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,9 @@ +* Add support for `Relation` be passed as parameter on `QueryCache#select_all`. + + Fixes #14361. + + *arthurnn* + * Passing an Active Record object to `find` is now deprecated. Call `.id` on the object first. diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index 6eb59cc398..dd1962e4d6 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -20,14 +20,7 @@ module ActiveRecord # Returns an ActiveRecord::Result instance. def select_all(arel, name = nil, binds = []) - if arel.is_a?(Relation) - relation = arel - arel = relation.arel - if !binds || binds.empty? - binds = relation.bind_values - end - end - + arel, binds = binds_from_relation arel, binds select(to_sql(arel, binds), name, binds) end @@ -47,10 +40,7 @@ module ActiveRecord # Returns an array of the values of the first column in a select: # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3] def select_values(arel, name = nil) - binds = [] - if arel.is_a?(Relation) - arel, binds = arel.arel, arel.bind_values - end + arel, binds = binds_from_relation arel select_rows(to_sql(arel, binds), name, binds).map(&:first) end @@ -389,6 +379,13 @@ module ActiveRecord row = result.rows.first row && row.first end + + def binds_from_relation(relation, binds = []) + if relation.is_a?(Relation) && binds.blank? + relation, binds = relation.arel, relation.bind_values + end + [relation, binds] + end end end 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 adc23a6674..4a4506c7f5 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -63,6 +63,7 @@ module ActiveRecord def select_all(arel, name = nil, binds = []) if @query_cache_enabled && !locked?(arel) + arel, binds = binds_from_relation arel, binds sql = to_sql(arel, binds) cache_sql(sql, binds) { super(sql, name, binds) } else diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index da8ae672fe..9d89d6a1e8 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -118,6 +118,14 @@ class QueryCacheTest < ActiveRecord::TestCase assert ActiveRecord::Base.connection.query_cache.empty?, 'cache should be empty' end + def test_cache_passing_a_relation + post = Post.first + Post.cache do + query = post.categories.select(:post_id) + assert Post.connection.select_all(query).is_a?(ActiveRecord::Result) + end + end + def test_find_queries assert_queries(2) { Task.find(1); Task.find(1) } end -- cgit v1.2.3 From 499c6aa684263feb1bd24faea70e6dde79ab238b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 13 Mar 2014 12:02:32 -0700 Subject: require actions rather than create_file thor's create_file seems to have a circular dependency on itself when used with our constant loading stuff. fixes #14319 --- railties/lib/rails/generators/actions/create_migration.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/generators/actions/create_migration.rb b/railties/lib/rails/generators/actions/create_migration.rb index 9c3332927f..cf3b7acfff 100644 --- a/railties/lib/rails/generators/actions/create_migration.rb +++ b/railties/lib/rails/generators/actions/create_migration.rb @@ -1,4 +1,4 @@ -require 'thor/actions/create_file' +require 'thor/actions' module Rails module Generators -- cgit v1.2.3 From a9023eccd682efff0cc7e14057112648195cac58 Mon Sep 17 00:00:00 2001 From: Lauro Caetano Date: Thu, 13 Mar 2014 16:10:04 -0300 Subject: Add test for deprecation warning for passing an AR object to `find`. --- activerecord/test/cases/finder_test.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 9adfc72634..c0440744e9 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -33,6 +33,12 @@ class FinderTest < ActiveRecord::TestCase assert_equal(topics(:first).title, Topic.find(1).title) end + def test_find_passing_active_record_object_is_deprecated + assert_deprecated do + Topic.find(Topic.last) + end + end + def test_symbols_table_ref Post.first # warm up x = Symbol.all_symbols.count -- cgit v1.2.3 From a0936a1635a86c5cc6b3afa331503aac1e87ced7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Thu, 13 Mar 2014 16:53:05 -0300 Subject: No need to binds be optional --- .../active_record/connection_adapters/abstract/database_statements.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index dd1962e4d6..e0516c0773 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -40,7 +40,7 @@ module ActiveRecord # Returns an array of the values of the first column in a select: # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3] def select_values(arel, name = nil) - arel, binds = binds_from_relation arel + arel, binds = binds_from_relation arel, [] select_rows(to_sql(arel, binds), name, binds).map(&:first) end @@ -380,7 +380,7 @@ module ActiveRecord row && row.first end - def binds_from_relation(relation, binds = []) + def binds_from_relation(relation, binds) if relation.is_a?(Relation) && binds.blank? relation, binds = relation.arel, relation.bind_values end -- cgit v1.2.3 From 4d1bc027e138df64841f8af3003cae39fb3b133a Mon Sep 17 00:00:00 2001 From: Afshin Mokhtari Date: Thu, 13 Mar 2014 20:28:02 +0000 Subject: Fix probs in sections 5.6 and 5.9; [ci skip] --- guides/source/getting_started.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 3ef9e04a02..bb8753cb2e 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -751,8 +751,8 @@ Rails has several security features that help you write secure applications, and you're running into one of them now. This one is called `strong_parameters`, which requires us to tell Rails exactly which parameters we want to accept in our controllers. In this case, we want to allow the -`title` and `text` parameters, so change your `create` controller action to -look like this: +`title` and `text` parameters, so add the new `article_params` method, and +change your `create` controller action to use it, like this: ```ruby def create @@ -900,7 +900,7 @@ Also add a link in `app/views/articles/new.html.erb`, underneath the form, to go back to the `index` action: ```erb -<%= form_for :article do |f| %> +<%= form_for :article, url: articles_path do |f| %> ... <% end %> -- cgit v1.2.3 From c63b18de1865182e027a97ea4186717a71792b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Wed, 12 Mar 2014 15:42:21 +0100 Subject: Add variants to Template class --- actionview/lib/action_view/template.rb | 3 ++- actionview/lib/action_view/template/resolver.rb | 17 ++++++++++------- actionview/lib/action_view/testing/resolvers.rb | 12 ++++++++---- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 961a969b6e..9d39d02a37 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -97,7 +97,7 @@ module ActionView extend Template::Handlers - attr_accessor :locals, :formats, :virtual_path + attr_accessor :locals, :formats, :variants, :virtual_path attr_reader :source, :identifier, :handler, :original_encoding, :updated_at @@ -123,6 +123,7 @@ module ActionView @virtual_path = details[:virtual_path] @updated_at = details[:updated_at] || Time.now @formats = Array(format).map { |f| f.respond_to?(:ref) ? f.ref : f } + @variants = [details[:variant]] @compile_mutex = Mutex.new end diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb index 3a3b74cdd5..403824bd8e 100644 --- a/actionview/lib/action_view/template/resolver.rb +++ b/actionview/lib/action_view/template/resolver.rb @@ -154,7 +154,8 @@ module ActionView cached = nil templates.each do |t| t.locals = locals - t.formats = details[:formats] || [:html] if t.formats.empty? + t.formats = details[:formats] || [:html] if t.formats.empty? + t.variants = details[:variants] || [] if t.variants.empty? t.virtual_path ||= (cached ||= build_path(*path_info)) end end @@ -189,13 +190,15 @@ module ActionView } template_paths.map { |template| - handler, format = extract_handler_and_format(template, formats) - contents = File.binread template + handler, format, variant = extract_handler_and_format_and_variant(template, formats) + contents = File.binread(template) Template.new(contents, File.expand_path(template), handler, :virtual_path => path.virtual, :format => format, - :updated_at => mtime(template)) + :variant => variant, + :updated_at => mtime(template) + ) } end @@ -228,7 +231,7 @@ module ActionView # Extract handler and formats from path. If a format cannot be a found neither # from the path, or the handler, we should return the array of formats given # to the resolver. - def extract_handler_and_format(path, default_formats) + def extract_handler_and_format_and_variant(path, default_formats) pieces = File.basename(path).split(".") pieces.shift @@ -240,10 +243,10 @@ module ActionView end handler = Template.handler_for_extension(extension) - format = pieces.last && pieces.last.split(EXTENSIONS[:variants], 2).first # remove variant from format + format, variant = pieces.last.split(EXTENSIONS[:variants], 2) if pieces.last format &&= Template::Types[format] - [handler, format] + [handler, format, variant] end end diff --git a/actionview/lib/action_view/testing/resolvers.rb b/actionview/lib/action_view/testing/resolvers.rb index af53ad3b25..dfb7d463b4 100644 --- a/actionview/lib/action_view/testing/resolvers.rb +++ b/actionview/lib/action_view/testing/resolvers.rb @@ -30,9 +30,13 @@ module ActionView #:nodoc: @hash.each do |_path, array| source, updated_at = array next unless _path =~ query - handler, format = extract_handler_and_format(_path, formats) + handler, format, variant = extract_handler_and_format_and_variant(_path, formats) templates << Template.new(source, _path, handler, - :virtual_path => path.virtual, :format => format, :updated_at => updated_at) + :virtual_path => path.virtual, + :format => format, + :variant => variant, + :updated_at => updated_at + ) end templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size } @@ -41,8 +45,8 @@ module ActionView #:nodoc: class NullResolver < 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)] + handler, format, variant = extract_handler_and_format_and_variant(path, formats) + [ActionView::Template.new("Template generated by Null Resolver", path, handler, :virtual_path => path, :format => format, :variant => variant)] end end -- cgit v1.2.3 From 48a6baea5ebb5539ab8ae9696cca6e95aac08a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Wed, 12 Mar 2014 15:43:09 +0100 Subject: Don't pass hash as keys to #find method --- actionview/lib/action_view/digestor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index df6e7bba60..6ef962383d 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -123,7 +123,7 @@ module ActionView def template @template ||= begin finder.variants = [ variant ] - finder.find(logical_name, [], partial?, formats: [ format ]) + finder.find(logical_name, [], partial?) end end -- cgit v1.2.3 From 4725d588960213fd617d3d17c936aa206a161cfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Thu, 13 Mar 2014 14:46:43 +0100 Subject: Disable LookupContext's cache when looking for template --- actionview/lib/action_view/digestor.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 6ef962383d..666291e1c1 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -122,8 +122,12 @@ module ActionView def template @template ||= begin - finder.variants = [ variant ] - finder.find(logical_name, [], partial?) + finder.formats = [format] + finder.variants = [variant] + + finder.disable_cache do + finder.find(logical_name, [], partial?) + end end end -- cgit v1.2.3 From 3b9daf0ff9f7981d375e7617b1ec46e9fc988aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Thu, 13 Mar 2014 16:27:24 +0100 Subject: Rename _setup_options to _options_for_digest --- actionview/lib/action_view/digestor.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 666291e1c1..dad3cea73a 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -18,7 +18,7 @@ module ActionView # * dependencies - An array of dependent views # * partial - Specifies whether the template is a partial def digest(*args) - options = _setup_options(*args) + options = _options_for_digest(*args) details_key = options[:finder].details_key.hash dependencies = Array.wrap(options[:dependencies]) @@ -33,7 +33,7 @@ module ActionView end end - def _setup_options(*args) + def _options_for_digest(*args) unless args.first.is_a?(Hash) ActiveSupport::Deprecation.warn("Arguments to ActionView::Digestor should be provided as a hash. The support for regular arguments will be removed in Rails 5.0 or later") @@ -76,7 +76,7 @@ module ActionView attr_reader :name, :format, :variant, :finder, :options def initialize(*args) - @options = self.class._setup_options(*args) + @options = self.class._options_for_digest(*args) @name = @options.delete(:name) @format = @options.delete(:format) -- cgit v1.2.3 From 03b8922ee4ba6051ae18917b5904f8664e715695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Thu, 13 Mar 2014 16:55:54 +0100 Subject: Set format in finder --- actionview/test/template/digestor_test.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index 0580758dab..2d4c434f9c 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -16,10 +16,12 @@ class FixtureFinder FIXTURES_DIR = "#{File.dirname(__FILE__)}/../fixtures/digestor" attr_reader :details + attr_accessor :formats attr_accessor :variants def initialize @details = {} + @formats = [] @variants = [] end @@ -27,9 +29,9 @@ class FixtureFinder details.hash end - def find(logical_name, keys, partial, options) - partial_name = partial ? logical_name.gsub(%r|/([^/]+)$|, '/_\1') : logical_name - format = options[:formats].first.to_s + def find(name, prefixes = [], partial = false, keys = [], options = {}) + partial_name = partial ? name.gsub(%r|/([^/]+)$|, '/_\1') : name + format = @formats.first.to_s format += "+#{@variants.first}" if @variants.any? FixtureTemplate.new("digestor/#{partial_name}.#{format}.erb") @@ -288,6 +290,9 @@ class TemplateDigestorTest < ActionView::TestCase def digest(template_name, options = {}) options = options.dup + finder.formats = [:html] + finder.variants = [options[:variant]] if options[:variant].present? + ActionView::Digestor.digest({ name: template_name, format: :html, finder: finder }.merge(options)) end -- cgit v1.2.3 From 9f677bf043eb359a91d346bb5a1e6ee81cef6665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Thu, 13 Mar 2014 16:56:29 +0100 Subject: Add mocked disable_cache for FixtureFinder --- actionview/test/template/digestor_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index 2d4c434f9c..1c47952f54 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -36,6 +36,10 @@ class FixtureFinder FixtureTemplate.new("digestor/#{partial_name}.#{format}.erb") end + + def disable_cache(&block) + yield + end end class TemplateDigestorTest < ActionView::TestCase -- cgit v1.2.3 From 2c2326e6eab4d192e361871787335ffa711af597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Fri, 14 Mar 2014 13:40:46 +0100 Subject: Introduce #with_formats_and_variants to prevent problems with mutating finder object --- actionview/lib/action_view/digestor.rb | 7 ++----- actionview/lib/action_view/lookup_context.rb | 8 ++++++++ actionview/test/template/digestor_test.rb | 8 ++++++++ actionview/test/template/lookup_context_test.rb | 13 +++++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index dad3cea73a..abbfdc786e 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -122,11 +122,8 @@ module ActionView def template @template ||= begin - finder.formats = [format] - finder.variants = [variant] - - finder.disable_cache do - finder.find(logical_name, [], partial?) + finder.with_formats_and_variants([format], [variant]) do + finder.disable_cache { finder.find(logical_name, [], partial?) } end end end diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb index 76c9890776..d7f116c10c 100644 --- a/actionview/lib/action_view/lookup_context.rb +++ b/actionview/lib/action_view/lookup_context.rb @@ -246,5 +246,13 @@ module ActionView end end end + + def with_formats_and_variants(new_formats, new_variants) + old_formats, old_variants = formats, variants + self.formats, self.variants = new_formats, new_variants + yield + ensure + self.formats, self.variants = old_formats, old_variants + end end end diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index 1c47952f54..72d1f43f12 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -40,6 +40,14 @@ class FixtureFinder def disable_cache(&block) yield end + + def with_formats_and_variants(new_formats, new_variants) + old_formats, old_variants = formats, variants + self.formats, self.variants = new_formats, new_variants + yield + ensure + self.formats, self.variants = old_formats, old_variants + end end class TemplateDigestorTest < ActionView::TestCase diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb index 4f7823045e..b11f252110 100644 --- a/actionview/test/template/lookup_context_test.rb +++ b/actionview/test/template/lookup_context_test.rb @@ -205,6 +205,19 @@ class LookupContextTest < ActiveSupport::TestCase @lookup_context.prefixes = ["foo"] assert_equal ["foo"], @lookup_context.prefixes end + + test "with_formats_and_variants preserves original values after execution" do + @lookup_context.formats = [:html] + @lookup_context.variants = [:phone] + + @lookup_context.with_formats_and_variants([:xml], [:tablet]) do + assert_equal [:xml], @lookup_context.formats + assert_equal [:tablet], @lookup_context.variants + end + + assert_equal [:html], @lookup_context.formats + assert_equal [:phone], @lookup_context.variants + end end class LookupContextWithFalseCaching < ActiveSupport::TestCase -- cgit v1.2.3 From 13cdb5fb49e08945855bd7196d5520cf2a885c5c Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Fri, 14 Mar 2014 10:41:02 -0300 Subject: Avoid duplicated conditionals --- activerecord/lib/active_record/associations/collection_association.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index ff0fbe932b..1f314e0677 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -145,9 +145,8 @@ module ActiveRecord # be chained. Since << flattens its argument list and inserts each record, # +push+ and +concat+ behave identically. def concat(*records) - load_target if owner.new_record? - if owner.new_record? + load_target concat_records(records) else transaction { concat_records(records) } -- cgit v1.2.3 From eaa19cc5761f8f86fb37683984d385a8707ad8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 14 Mar 2014 13:20:16 -0300 Subject: Force sass-rails ~> 4.0.2 to avoid sprockets compatibility error See https://github.com/rails/sass-rails/issues/191 for more information --- railties/lib/rails/generators/app_base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index b2ecc22294..fbdc47ea44 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -246,7 +246,7 @@ module Rails 'Use SCSS for stylesheets') else gems << GemfileEntry.version('sass-rails', - '~> 4.0.1', + '~> 4.0.2', 'Use SCSS for stylesheets') end -- cgit v1.2.3 From 7f17019e079bb9e6352f11d537633ddf10ea5903 Mon Sep 17 00:00:00 2001 From: schneems Date: Tue, 11 Mar 2014 22:23:21 -0500 Subject: Allow custom JDBC urls mitigates #14323 --- .../active_record/connection_adapters/connection_specification.rb | 4 ++-- .../test/cases/connection_adapters/connection_handler_test.rb | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb index 3f8b14bf67..9a133168f8 100644 --- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb @@ -237,8 +237,8 @@ module ActiveRecord # hash and merges with the rest of the hash. # Connection details inside of the "url" key win any merge conflicts def resolve_hash_connection(spec) - if url = spec.delete("url") - connection_hash = resolve_string_connection(url) + if spec["url"] && spec["url"] !~ /^jdbc:/ + connection_hash = resolve_string_connection(spec.delete("url")) spec.merge!(connection_hash) end spec diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb index 599e8c762c..68ddc08f89 100644 --- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb +++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb @@ -17,6 +17,12 @@ module ActiveRecord ENV["DATABASE_URL"] = @previous_database_url end + def test_jdbc_url + config = { "production" => { "url" => "jdbc:postgres://localhost/foo" } } + actual = klass.new(config).resolve + assert_equal config, actual + end + def test_environment_does_not_exist_in_config_url_does_exist ENV['DATABASE_URL'] = "postgres://localhost/foo" config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } } -- cgit v1.2.3 From aa27766e2fa8ba92b0943e829b7e91b7518a777d Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 14 Mar 2014 11:33:42 -0500 Subject: better test error messages --- railties/test/generators/plugin_generator_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index b2fc3a2a4f..7ebc015fe2 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -185,22 +185,22 @@ class PluginGeneratorTest < Rails::Generators::TestCase run_generator FileUtils.cd destination_root quietly { system 'bundle install' } - assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`) + assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`) end def test_ensure_that_tests_works_in_full_mode run_generator [destination_root, "--full", "--skip_active_record"] FileUtils.cd destination_root quietly { system 'bundle install' } - assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`) + assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`) end def test_ensure_that_migration_tasks_work_with_mountable_option run_generator [destination_root, "--mountable"] FileUtils.cd destination_root quietly { system 'bundle install' } - `bundle exec rake db:migrate` - assert_equal 0, $?.exitstatus + output = `bundle exec rake db:migrate 2>&1` + assert $?.success?, "Command failed: #{output}" end def test_creating_engine_in_full_mode -- cgit v1.2.3 From d153355d35954e0e553d4b1b34db10a0ea7fa6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 14 Mar 2014 14:34:49 -0300 Subject: Match the whole string --- tasks/release.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/release.rb b/tasks/release.rb index 439a9e0c05..f6ec2dbe58 100644 --- a/tasks/release.rb +++ b/tasks/release.rb @@ -102,7 +102,7 @@ namespace :all do abort "[ABORTING] `git status` reports a dirty tree. Make sure all changes are committed" end - unless ENV['SKIP_TAG'] || `git tag | grep #{tag}`.strip.empty? + unless ENV['SKIP_TAG'] || `git tag | grep '^#{tag}$`.strip.empty? abort "[ABORTING] `git tag` shows that #{tag} already exists. Has this version already\n"\ " been released? Git tagging can be skipped by setting SKIP_TAG=1" end -- cgit v1.2.3 From b4c96490eeb1fbb944e116c7703dd528b37fc08a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 14 Mar 2014 14:52:17 -0300 Subject: Take in consideration guides CHANGELOG --- tasks/release.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/release.rb b/tasks/release.rb index f6ec2dbe58..a55cb68a47 100644 --- a/tasks/release.rb +++ b/tasks/release.rb @@ -68,7 +68,7 @@ end namespace :changelog do task :release_date do - FRAMEWORKS.each do |fw| + FRAMEWORKS + ['guides'].each do |fw| require 'date' replace = '\1(' + Date.today.strftime('%B %d, %Y') + ')' fname = File.join fw, 'CHANGELOG.md' @@ -79,7 +79,7 @@ namespace :changelog do end task :release_summary do - FRAMEWORKS.each do |fw| + FRAMEWORKS + ['guides'].each do |fw| puts "## #{fw}" fname = File.join fw, 'CHANGELOG.md' contents = File.readlines fname -- cgit v1.2.3 From a2fb164a4fadf0f34055089b75ef9077bded8524 Mon Sep 17 00:00:00 2001 From: robertomiranda Date: Thu, 13 Mar 2014 19:16:49 -0500 Subject: Add Public Api for register new extensions for Rake Notes --- railties/lib/rails/source_annotation_extractor.rb | 39 ++++++++++++++--------- railties/test/application/rake/notes_test.rb | 5 +++ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index 83e28090f8..5863ad1ed7 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -18,6 +18,22 @@ class SourceAnnotationExtractor @@directories ||= %w(app config db lib test) + (ENV['SOURCE_ANNOTATION_DIRECTORIES'] || '').split(',') end + def self.extensions + @@extensions ||= {} + end + + # Registers new Annotations File Extensions + # SourceAnnotationExtractor::Annotation.register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ } + def self.register_extensions(*extensions, &block) + self.extensions[/\.(#{extensions.join("|")})$/] = block + end + + register_extensions("builder", "rb", "coffe", "rake") { |tag| /#\s*(#{tag}):?\s*(.*)$/ } + register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ } + register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ } + register_extensions("haml") { |tag| /-\s*#\s*(#{tag}):?\s*(.*)$/ } + register_extensions("slim") { |tag| /\/\s*\s*(#{tag}):?\s*(.*)$/ } + # Returns a representation of the annotation that looks like this: # # [126] [TODO] This algorithm is simple and clearly correct, make it faster. @@ -78,21 +94,14 @@ class SourceAnnotationExtractor if File.directory?(item) results.update(find_in(item)) else - pattern = - case item - when /\.(builder|rb|coffee|rake)$/ - /#\s*(#{tag}):?\s*(.*)$/ - when /\.(css|scss|sass|less|js)$/ - /\/\/\s*(#{tag}):?\s*(.*)$/ - when /\.erb$/ - /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ - when /\.haml$/ - /-\s*#\s*(#{tag}):?\s*(.*)$/ - when /\.slim$/ - /\/\s*\s*(#{tag}):?\s*(.*)$/ - else nil - end - results.update(extract_annotations_from(item, pattern)) if pattern + extension = Annotation.extensions.detect do |regexp, _block| + regexp.match(item) + end + + if extension + pattern = extension.last.call(tag) + results.update(extract_annotations_from(item, pattern)) if pattern + end end end diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 05f6338b68..62ab28082d 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -175,6 +175,11 @@ module ApplicationTests end end + test 'register a new extension' do + SourceAnnotationExtractor::Annotation.register_extensions(".test1", ".test2") { |tag| /#{tag}/ } + assert SourceAnnotationExtractor::Annotation.extensions[/(\.test1|\.test2)/] + end + private def boot_rails super -- cgit v1.2.3 From d17b87919fae5850051bf7a173d3c6a84778f941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 14 Mar 2014 17:28:31 -0300 Subject: Fix the resolver cache and stop mutating the lookup_context Before we had a bug in the resolver cache so the disable_cache were not working when passing options to find --- actionview/lib/action_view/digestor.rb | 4 ++-- actionview/lib/action_view/lookup_context.rb | 17 ++++++++--------- actionview/test/template/digestor_test.rb | 8 -------- actionview/test/template/lookup_context_test.rb | 13 ------------- 4 files changed, 10 insertions(+), 32 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index abbfdc786e..c302bc15fa 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -122,8 +122,8 @@ module ActionView def template @template ||= begin - finder.with_formats_and_variants([format], [variant]) do - finder.disable_cache { finder.find(logical_name, [], partial?) } + finder.disable_cache do + finder.find(logical_name, [], partial?, [], formats: [format], variants: [variant]) end end end diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb index d7f116c10c..855fed0190 100644 --- a/actionview/lib/action_view/lookup_context.rb +++ b/actionview/lib/action_view/lookup_context.rb @@ -159,7 +159,14 @@ module ActionView def detail_args_for(options) return @details, details_key if options.empty? # most common path. user_details = @details.merge(options) - [user_details, DetailsKey.get(user_details)] + + if @cache + details_key = DetailsKey.get(user_details) + else + details_key = nil + end + + [user_details, details_key] end # Support legacy foo.erb names even though we now ignore .erb @@ -246,13 +253,5 @@ module ActionView end end end - - def with_formats_and_variants(new_formats, new_variants) - old_formats, old_variants = formats, variants - self.formats, self.variants = new_formats, new_variants - yield - ensure - self.formats, self.variants = old_formats, old_variants - end end end diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index 72d1f43f12..1c47952f54 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -40,14 +40,6 @@ class FixtureFinder def disable_cache(&block) yield end - - def with_formats_and_variants(new_formats, new_variants) - old_formats, old_variants = formats, variants - self.formats, self.variants = new_formats, new_variants - yield - ensure - self.formats, self.variants = old_formats, old_variants - end end class TemplateDigestorTest < ActionView::TestCase diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb index b11f252110..4f7823045e 100644 --- a/actionview/test/template/lookup_context_test.rb +++ b/actionview/test/template/lookup_context_test.rb @@ -205,19 +205,6 @@ class LookupContextTest < ActiveSupport::TestCase @lookup_context.prefixes = ["foo"] assert_equal ["foo"], @lookup_context.prefixes end - - test "with_formats_and_variants preserves original values after execution" do - @lookup_context.formats = [:html] - @lookup_context.variants = [:phone] - - @lookup_context.with_formats_and_variants([:xml], [:tablet]) do - assert_equal [:xml], @lookup_context.formats - assert_equal [:tablet], @lookup_context.variants - end - - assert_equal [:html], @lookup_context.formats - assert_equal [:phone], @lookup_context.variants - end end class LookupContextWithFalseCaching < ActiveSupport::TestCase -- cgit v1.2.3 From d75eeadf740f5ec01c72cb8b0da77de80db4d2a9 Mon Sep 17 00:00:00 2001 From: Sammy Larbi Date: Sat, 20 Apr 2013 13:06:22 -0500 Subject: Fix #to_json for BasicObject Enumerables --- activesupport/CHANGELOG.md | 5 +++ .../lib/active_support/core_ext/object/json.rb | 2 +- .../lib/active_support/core_ext/object/to_json.rb | 2 +- activesupport/test/json/encoding_test.rb | 43 +++++++++++++++++----- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 38a761384e..4eccea2848 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,8 @@ +* Ensure classes which `include Enumerable` get `#to_json` in addition to + `#as_json`. + + *Sammy Larbi* + * Change the signature of `fetch_multi` to return a hash rather than an array. This makes it consistent with the output of `read_multi`. diff --git a/activesupport/lib/active_support/core_ext/object/json.rb b/activesupport/lib/active_support/core_ext/object/json.rb index 8e08cfbf26..5496692373 100644 --- a/activesupport/lib/active_support/core_ext/object/json.rb +++ b/activesupport/lib/active_support/core_ext/object/json.rb @@ -26,7 +26,7 @@ require 'active_support/core_ext/module/aliasing' # bypassed completely. This means that as_json won't be invoked and the JSON gem will simply # ignore any options it does not natively understand. This also means that ::JSON.{generate,dump} # should give exactly the same results with or without active support. -[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass| +[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].each do |klass| klass.class_eval do def to_json_with_active_support_encoder(options = nil) if options.is_a?(::JSON::State) diff --git a/activesupport/lib/active_support/core_ext/object/to_json.rb b/activesupport/lib/active_support/core_ext/object/to_json.rb index 3dcae6fc7f..f58364f9c6 100644 --- a/activesupport/lib/active_support/core_ext/object/to_json.rb +++ b/activesupport/lib/active_support/core_ext/object/to_json.rb @@ -2,4 +2,4 @@ ActiveSupport::Deprecation.warn 'You have required `active_support/core_ext/obje 'This file will be removed in Rails 4.2. You should require `active_support/core_ext/object/json` ' \ 'instead.' -require 'active_support/core_ext/object/json' +require 'active_support/core_ext/object/json' \ No newline at end of file diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index c4283ee79a..f22d7b8b02 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -327,12 +327,39 @@ class TestJSONEncoding < ActiveSupport::TestCase assert_equal(%([{"address":{"city":"London"}},{"address":{"city":"Paris"}}]), json) end - def test_enumerable_should_pass_encoding_options_to_children_in_as_json - people = [ - { :name => 'John', :address => { :city => 'London', :country => 'UK' }}, - { :name => 'Jean', :address => { :city => 'Paris' , :country => 'France' }} + People = Class.new(BasicObject) do + include Enumerable + def initialize() + @people = [ + { :name => 'John', :address => { :city => 'London', :country => 'UK' }}, + { :name => 'Jean', :address => { :city => 'Paris' , :country => 'France' }} + ] + end + def each(*, &blk) + @people.each do |p| + yield p if blk + p + end.each + end + end + + def test_enumerable_should_generate_json_with_as_json + json = People.new.as_json :only => [:address, :city] + expected = [ + { 'address' => { 'city' => 'London' }}, + { 'address' => { 'city' => 'Paris' }} ] - json = people.each.as_json :only => [:address, :city] + + assert_equal(expected, json) + end + + def test_enumerable_should_generate_json_with_to_json + json = People.new.to_json :only => [:address, :city] + assert_equal(%([{"address":{"city":"London"}},{"address":{"city":"Paris"}}]), json) + end + + def test_enumerable_should_pass_encoding_options_to_children_in_as_json + json = People.new.each.as_json :only => [:address, :city] expected = [ { 'address' => { 'city' => 'London' }}, { 'address' => { 'city' => 'Paris' }} @@ -342,11 +369,7 @@ class TestJSONEncoding < ActiveSupport::TestCase end def test_enumerable_should_pass_encoding_options_to_children_in_to_json - people = [ - { :name => 'John', :address => { :city => 'London', :country => 'UK' }}, - { :name => 'Jean', :address => { :city => 'Paris' , :country => 'France' }} - ] - json = people.each.to_json :only => [:address, :city] + json = People.new.each.to_json :only => [:address, :city] assert_equal(%([{"address":{"city":"London"}},{"address":{"city":"Paris"}}]), json) end -- cgit v1.2.3 From 810af6f6ee62d76e9ed529d93ea9686a45e5a81e Mon Sep 17 00:00:00 2001 From: robertomiranda Date: Fri, 14 Mar 2014 15:34:24 -0500 Subject: Remove .scss, .sass, .less, .haml, .slim, coffee from Rake Notes. Now we have an API for register it in the corresponding gems --- railties/lib/rails/source_annotation_extractor.rb | 6 ++---- railties/test/application/rake/notes_test.rb | 16 +++------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index 5863ad1ed7..b5f1ca1602 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -28,11 +28,9 @@ class SourceAnnotationExtractor self.extensions[/\.(#{extensions.join("|")})$/] = block end - register_extensions("builder", "rb", "coffe", "rake") { |tag| /#\s*(#{tag}):?\s*(.*)$/ } - register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ } + register_extensions("builder", "rb", "rake") { |tag| /#\s*(#{tag}):?\s*(.*)$/ } + register_extensions("css", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ } register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ } - register_extensions("haml") { |tag| /-\s*#\s*(#{tag}):?\s*(.*)$/ } - register_extensions("slim") { |tag| /\/\s*\s*(#{tag}):?\s*(.*)$/ } # Returns a representation of the annotation that looks like this: # diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 62ab28082d..2191de32af 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -1,4 +1,5 @@ require "isolation/abstract_unit" +require 'rails/source_annotation_extractor' module ApplicationTests module RakeTests @@ -18,14 +19,8 @@ module ApplicationTests test 'notes finds notes for certain file_types' do app_file "app/views/home/index.html.erb", "<% # TODO: note in erb %>" - app_file "app/views/home/index.html.haml", "-# TODO: note in haml" - app_file "app/views/home/index.html.slim", "/ TODO: note in slim" - app_file "app/assets/javascripts/application.js.coffee", "# TODO: note in coffee" app_file "app/assets/javascripts/application.js", "// TODO: note in js" app_file "app/assets/stylesheets/application.css", "// TODO: note in css" - app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss" - app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass" - app_file "app/assets/stylesheets/application.css.less", "// TODO: note in less" app_file "app/controllers/application_controller.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in ruby" app_file "lib/tasks/task.rake", "# TODO: note in rake" app_file 'app/views/home/index.html.builder', '# TODO: note in builder' @@ -42,19 +37,13 @@ module ApplicationTests lines = output.scan(/\[([0-9\s]+)\](\s)/) assert_match(/note in erb/, output) - assert_match(/note in haml/, output) - assert_match(/note in slim/, output) assert_match(/note in ruby/, output) - assert_match(/note in coffee/, output) assert_match(/note in js/, output) assert_match(/note in css/, output) - assert_match(/note in scss/, output) - assert_match(/note in sass/, output) - assert_match(/note in less/, output) assert_match(/note in rake/, output) assert_match(/note in builder/, output) - assert_equal 12, lines.size + assert_equal 6, lines.size lines.each do |line| assert_equal 4, line[0].size @@ -178,6 +167,7 @@ module ApplicationTests test 'register a new extension' do SourceAnnotationExtractor::Annotation.register_extensions(".test1", ".test2") { |tag| /#{tag}/ } assert SourceAnnotationExtractor::Annotation.extensions[/(\.test1|\.test2)/] + assert_blank SourceAnnotationExtractor::Annotation.extensions[/(\.haml)/] end private -- cgit v1.2.3 From f43421cb65da635988f2bb5341d519c3c2748b74 Mon Sep 17 00:00:00 2001 From: robertomiranda Date: Fri, 14 Mar 2014 17:51:14 -0500 Subject: Supporting .ruby, .yml and .yaml Extension in Rake Notes --- railties/lib/rails/source_annotation_extractor.rb | 2 +- railties/test/application/rake/notes_test.rb | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index b5f1ca1602..af6d90b5bd 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -28,7 +28,7 @@ class SourceAnnotationExtractor self.extensions[/\.(#{extensions.join("|")})$/] = block end - register_extensions("builder", "rb", "rake") { |tag| /#\s*(#{tag}):?\s*(.*)$/ } + register_extensions("builder", "rb", "rake", "yml", "yaml", "ruby") { |tag| /#\s*(#{tag}):?\s*(.*)$/ } register_extensions("css", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ } register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ } diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 2191de32af..b6b1bd63f4 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -24,6 +24,9 @@ module ApplicationTests app_file "app/controllers/application_controller.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in ruby" app_file "lib/tasks/task.rake", "# TODO: note in rake" app_file 'app/views/home/index.html.builder', '# TODO: note in builder' + app_file 'config/locales/en.yml', '# TODO: note in yml' + app_file 'config/locales/en.yaml', '# TODO: note in yml' + app_file "app/views/home/index.ruby", "# TODO: note in ruby" boot_rails require 'rake' @@ -42,8 +45,10 @@ module ApplicationTests assert_match(/note in css/, output) assert_match(/note in rake/, output) assert_match(/note in builder/, output) + assert_match(/note in yml/, output) + assert_match(/note in yaml/, output) - assert_equal 6, lines.size + assert_equal 9, lines.size lines.each do |line| assert_equal 4, line[0].size -- cgit v1.2.3 From a215ca63355d7c404db6d2daae868a80c0aa23b6 Mon Sep 17 00:00:00 2001 From: Washington Luiz Date: Fri, 14 Mar 2014 19:44:07 -0300 Subject: Update callbacks executed on AR::Base#touch [skip ci] As of https://github.com/rails/rails/pull/12031 after_commit and after_rollback are also executed --- activerecord/lib/active_record/persistence.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 4e63206cf4..d85fad1e13 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -405,8 +405,8 @@ module ActiveRecord end # Saves the record with the updated_at/on attributes set to the current time. - # Please note that no validation is performed and only the +after_touch+ - # callback is executed. + # Please note that no validation is performed and only the +after_touch+, + # +after_commit+ and +after_rollback+ callbacks are executed. # If an attribute name is passed, that attribute is updated along with # updated_at/on attributes. # -- cgit v1.2.3 From bae7f1dae90c37b0e02482a1d99f4aeec5d49e24 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Fri, 14 Mar 2014 20:17:03 -0300 Subject: Obey `validate: false` option for habtm Fixes #14383. --- activerecord/lib/active_record/associations.rb | 2 +- .../has_and_belongs_to_many_associations_test.rb | 24 ++++++++++++++++++++++ activerecord/test/models/person.rb | 13 ++++++++++++ activerecord/test/models/treasure.rb | 1 + 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index f725356cd9..860e76fa18 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1584,7 +1584,7 @@ module ActiveRecord hm_options[:through] = middle_reflection.name hm_options[:source] = join_model.right_reflection.name - [:before_add, :after_add, :before_remove, :after_remove, :autosave].each do |k| + [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate].each do |k| hm_options[k] = options[k] if options.key? k end diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index bac1cb8e2d..366472c6fd 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -11,6 +11,7 @@ require 'models/author' require 'models/tag' require 'models/tagging' require 'models/parrot' +require 'models/person' require 'models/pirate' require 'models/treasure' require 'models/price_estimate' @@ -795,4 +796,27 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end end + def test_association_with_validate_false_does_not_run_associated_validation_callbacks_on_create + rich_person = RichPerson.new + + treasure = Treasure.new + treasure.rich_people << rich_person + treasure.valid? + + assert_equal 1, treasure.rich_people.size + assert_nil rich_person.first_name, 'should not run associated person validation on create when validate: false' + end + + def test_association_with_validate_false_does_not_run_associated_validation_callbacks_on_update + rich_person = RichPerson.create! + person_first_name = rich_person.first_name + assert_not_nil person_first_name + + treasure = Treasure.new + treasure.rich_people << rich_person + treasure.valid? + + assert_equal 1, treasure.rich_people.size + assert_equal person_first_name, rich_person.first_name, 'should not run associated person validation on update when validate: false' + end end diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb index 1a282dbce4..c7e54e7b63 100644 --- a/activerecord/test/models/person.rb +++ b/activerecord/test/models/person.rb @@ -89,6 +89,19 @@ class RichPerson < ActiveRecord::Base self.table_name = 'people' has_and_belongs_to_many :treasures, :join_table => 'peoples_treasures' + + before_validation :run_before_create, on: :create + before_validation :run_before_validation + + private + + def run_before_create + self.first_name = first_name.to_s + 'run_before_create' + end + + def run_before_validation + self.first_name = first_name.to_s + 'run_before_validation' + end end class NestedPerson < ActiveRecord::Base diff --git a/activerecord/test/models/treasure.rb b/activerecord/test/models/treasure.rb index e864295acf..a69d3fd3df 100644 --- a/activerecord/test/models/treasure.rb +++ b/activerecord/test/models/treasure.rb @@ -3,6 +3,7 @@ class Treasure < ActiveRecord::Base belongs_to :looter, :polymorphic => true has_many :price_estimates, :as => :estimate_of + has_and_belongs_to_many :rich_people, join_table: 'peoples_treasures', validate: false accepts_nested_attributes_for :looter end -- cgit v1.2.3 From 3baace687cfbf4c98367fda31e0a4b0f85ce813f Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Thu, 13 Mar 2014 21:35:58 -0700 Subject: Use teardown helper method. Follow-Up to https://github.com/rails/rails/pull/14348 Ensure that SQLCounter.clear_log is called after each test. This is a step to prevent side effects when running tests. This will allow us to run them in random order. --- activerecord/test/cases/adapter_test.rb | 2 +- activerecord/test/cases/adapters/mysql/active_schema_test.rb | 2 +- activerecord/test/cases/adapters/mysql/reserved_word_test.rb | 2 +- activerecord/test/cases/adapters/mysql2/active_schema_test.rb | 2 +- activerecord/test/cases/adapters/mysql2/reserved_word_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/active_schema_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/array_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/bytea_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/citext_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/composite_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/datatype_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/enum_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/hstore_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/json_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/ltree_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/range_test.rb | 2 +- .../test/cases/adapters/postgresql/schema_authorization_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/schema_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/view_test.rb | 2 +- activerecord/test/cases/adapters/postgresql/xml_test.rb | 2 +- activerecord/test/cases/ar_schema_test.rb | 2 +- .../test/cases/associations/eager_load_nested_include_test.rb | 4 ++-- activerecord/test/cases/associations/eager_singularization_test.rb | 2 +- activerecord/test/cases/attribute_methods_test.rb | 2 +- activerecord/test/cases/bind_parameter_test.rb | 2 +- .../test/cases/connection_adapters/connection_handler_test.rb | 2 +- activerecord/test/cases/connection_pool_test.rb | 3 +-- activerecord/test/cases/defaults_test.rb | 2 +- activerecord/test/cases/disconnected_test.rb | 2 +- activerecord/test/cases/explain_subscriber_test.rb | 2 +- activerecord/test/cases/inheritance_test.rb | 2 +- activerecord/test/cases/invalid_connection_test.rb | 2 +- activerecord/test/cases/invertible_migration_test.rb | 2 +- activerecord/test/cases/migration/change_schema_test.rb | 3 +-- activerecord/test/cases/migration/change_table_test.rb | 2 +- activerecord/test/cases/migration/column_positioning_test.rb | 3 +-- activerecord/test/cases/migration/create_join_table_test.rb | 3 +-- activerecord/test/cases/migration/index_test.rb | 3 +-- activerecord/test/cases/migration/logger_test.rb | 3 +-- activerecord/test/cases/migration/references_index_test.rb | 3 +-- activerecord/test/cases/migration_test.rb | 4 ++-- activerecord/test/cases/migrator_test.rb | 3 +-- activerecord/test/cases/modules_test.rb | 2 +- activerecord/test/cases/nested_attributes_test.rb | 2 +- activerecord/test/cases/pooled_connections_test.rb | 2 +- activerecord/test/cases/reaper_test.rb | 3 +-- activerecord/test/cases/serialized_attribute_test.rb | 3 +-- activerecord/test/cases/unconnected_test.rb | 2 +- activerecord/test/cases/validations/i18n_validation_test.rb | 2 +- 49 files changed, 51 insertions(+), 61 deletions(-) diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index 0eb1231c79..696b859b36 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -218,7 +218,7 @@ module ActiveRecord @connection = Klass.connection end - def teardown + teardown do Klass.remove_connection end diff --git a/activerecord/test/cases/adapters/mysql/active_schema_test.rb b/activerecord/test/cases/adapters/mysql/active_schema_test.rb index 0878925a6c..e77138eb1d 100644 --- a/activerecord/test/cases/adapters/mysql/active_schema_test.rb +++ b/activerecord/test/cases/adapters/mysql/active_schema_test.rb @@ -11,7 +11,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase end end - def teardown + teardown do ActiveRecord::Base.remove_connection ActiveRecord::Base.establish_connection(@connection) end diff --git a/activerecord/test/cases/adapters/mysql/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql/reserved_word_test.rb index 8eb9565963..61ae0abfd1 100644 --- a/activerecord/test/cases/adapters/mysql/reserved_word_test.rb +++ b/activerecord/test/cases/adapters/mysql/reserved_word_test.rb @@ -37,7 +37,7 @@ class MysqlReservedWordTest < ActiveRecord::TestCase 'distinct_select'=>'distinct_id int, select_id int' end - def teardown + teardown do drop_tables_directly ['group', 'select', 'values', 'distinct', 'distinct_select', 'order'] end diff --git a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb index 4ccf568406..7905edaf83 100644 --- a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb +++ b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb @@ -11,7 +11,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase end end - def teardown + teardown do ActiveRecord::Base.remove_connection ActiveRecord::Base.establish_connection(@connection) end diff --git a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb index 1a82308176..799d927ee4 100644 --- a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb +++ b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb @@ -37,7 +37,7 @@ class MysqlReservedWordTest < ActiveRecord::TestCase 'distinct_select'=>'distinct_id int, select_id int' end - def teardown + teardown do drop_tables_directly ['group', 'select', 'values', 'distinct', 'distinct_select', 'order'] end diff --git a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb index 22dd48e113..3808db5141 100644 --- a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb @@ -7,7 +7,7 @@ class PostgresqlActiveSchemaTest < ActiveRecord::TestCase end end - def teardown + teardown do ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do remove_method :execute end diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb index 3090f4478f..f5f1c791e1 100644 --- a/activerecord/test/cases/adapters/postgresql/array_test.rb +++ b/activerecord/test/cases/adapters/postgresql/array_test.rb @@ -19,7 +19,7 @@ class PostgresqlArrayTest < ActiveRecord::TestCase @column = PgArray.columns.find { |c| c.name == 'tags' } end - def teardown + teardown do @connection.execute 'drop table if exists pg_arrays' end diff --git a/activerecord/test/cases/adapters/postgresql/bytea_test.rb b/activerecord/test/cases/adapters/postgresql/bytea_test.rb index b8dd35c4c5..c3394d7712 100644 --- a/activerecord/test/cases/adapters/postgresql/bytea_test.rb +++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb @@ -23,7 +23,7 @@ class PostgresqlByteaTest < ActiveRecord::TestCase assert(@column.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQLColumn)) end - def teardown + teardown do @connection.execute 'drop table if exists bytea_data_type' end diff --git a/activerecord/test/cases/adapters/postgresql/citext_test.rb b/activerecord/test/cases/adapters/postgresql/citext_test.rb index ebb9ff98b1..148dc9d07c 100644 --- a/activerecord/test/cases/adapters/postgresql/citext_test.rb +++ b/activerecord/test/cases/adapters/postgresql/citext_test.rb @@ -25,7 +25,7 @@ class PostgresqlCitextTest < ActiveRecord::TestCase @column = Citext.columns_hash['cival'] end - def teardown + teardown do @connection.execute 'DROP TABLE IF EXISTS citexts;' @connection.execute 'DROP EXTENSION IF EXISTS citext CASCADE;' end diff --git a/activerecord/test/cases/adapters/postgresql/composite_test.rb b/activerecord/test/cases/adapters/postgresql/composite_test.rb index 7202cce390..ed39204145 100644 --- a/activerecord/test/cases/adapters/postgresql/composite_test.rb +++ b/activerecord/test/cases/adapters/postgresql/composite_test.rb @@ -8,7 +8,7 @@ class PostgresqlCompositeTest < ActiveRecord::TestCase self.table_name = "postgresql_composites" end - def teardown + teardown do @connection.execute 'DROP TABLE IF EXISTS postgresql_composites' @connection.execute 'DROP TYPE IF EXISTS full_address' end diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb index 158bc6ee89..e7dda1a1af 100644 --- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb +++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb @@ -67,7 +67,7 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase @connection.execute("INSERT INTO postgresql_timestamp_with_zones (id, time) VALUES (1, '2010-01-01 10:00:00-1')") end - def teardown + teardown do [PostgresqlArray, PostgresqlTsvector, PostgresqlMoney, PostgresqlNumber, PostgresqlTime, PostgresqlNetworkAddress, PostgresqlBitString, PostgresqlOid, PostgresqlTimestampWithZone].each(&:delete_all) end diff --git a/activerecord/test/cases/adapters/postgresql/enum_test.rb b/activerecord/test/cases/adapters/postgresql/enum_test.rb index 62f84caf91..7208edef5f 100644 --- a/activerecord/test/cases/adapters/postgresql/enum_test.rb +++ b/activerecord/test/cases/adapters/postgresql/enum_test.rb @@ -8,7 +8,7 @@ class PostgresqlEnumTest < ActiveRecord::TestCase self.table_name = "postgresql_enums" end - def teardown + teardown do @connection.execute 'DROP TABLE IF EXISTS postgresql_enums' @connection.execute 'DROP TYPE IF EXISTS mood' end diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb index f2502430de..90ec1524b5 100644 --- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb +++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb @@ -31,7 +31,7 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase @column = Hstore.columns.find { |c| c.name == 'tags' } end - def teardown + teardown do @connection.execute 'drop table if exists hstores' end diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb index 3daef399d8..10c0a6c395 100644 --- a/activerecord/test/cases/adapters/postgresql/json_test.rb +++ b/activerecord/test/cases/adapters/postgresql/json_test.rb @@ -26,7 +26,7 @@ class PostgresqlJSONTest < ActiveRecord::TestCase @column = JsonDataType.columns.find { |c| c.name == 'payload' } end - def teardown + teardown do @connection.execute 'drop table if exists json_data_type' end diff --git a/activerecord/test/cases/adapters/postgresql/ltree_test.rb b/activerecord/test/cases/adapters/postgresql/ltree_test.rb index 5d12ca75ca..e72fd4360d 100644 --- a/activerecord/test/cases/adapters/postgresql/ltree_test.rb +++ b/activerecord/test/cases/adapters/postgresql/ltree_test.rb @@ -19,7 +19,7 @@ class PostgresqlLtreeTest < ActiveRecord::TestCase skip "do not test on PG without ltree" end - def teardown + teardown do @connection.execute 'drop table if exists ltrees' end diff --git a/activerecord/test/cases/adapters/postgresql/range_test.rb b/activerecord/test/cases/adapters/postgresql/range_test.rb index 4e84335e9b..a9d4312fb3 100644 --- a/activerecord/test/cases/adapters/postgresql/range_test.rb +++ b/activerecord/test/cases/adapters/postgresql/range_test.rb @@ -8,7 +8,7 @@ if ActiveRecord::Base.connection.supports_ranges? end class PostgresqlRangeTest < ActiveRecord::TestCase - def teardown + teardown do @connection.execute 'DROP TABLE IF EXISTS postgresql_ranges' @connection.execute 'DROP TYPE IF EXISTS floatrange' end diff --git a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb index d5e1838543..99c26c4bf7 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb @@ -27,7 +27,7 @@ class SchemaAuthorizationTest < ActiveRecord::TestCase end end - def teardown + teardown do set_session_auth @connection.execute "RESET search_path" USERS.each do |u| diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index 3f7009c1d1..5e5f653d17 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -71,7 +71,7 @@ class SchemaTest < ActiveRecord::TestCase @connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{UNMATCHED_PK_TABLE_NAME} (id integer NOT NULL DEFAULT nextval('#{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}'::regclass), CONSTRAINT unmatched_pkey PRIMARY KEY (id))" end - def teardown + teardown do @connection.execute "DROP SCHEMA #{SCHEMA2_NAME} CASCADE" @connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE" end diff --git a/activerecord/test/cases/adapters/postgresql/view_test.rb b/activerecord/test/cases/adapters/postgresql/view_test.rb index 66e07b71a0..08071894c4 100644 --- a/activerecord/test/cases/adapters/postgresql/view_test.rb +++ b/activerecord/test/cases/adapters/postgresql/view_test.rb @@ -24,7 +24,7 @@ class ViewTest < ActiveRecord::TestCase @connection.execute "CREATE VIEW #{SCHEMA_NAME}.#{VIEW_NAME} AS SELECT id,name,email,moment FROM #{SCHEMA_NAME}.#{TABLE_NAME}" end - def teardown + teardown do @connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE" end diff --git a/activerecord/test/cases/adapters/postgresql/xml_test.rb b/activerecord/test/cases/adapters/postgresql/xml_test.rb index dd2a727afe..ae299697b1 100644 --- a/activerecord/test/cases/adapters/postgresql/xml_test.rb +++ b/activerecord/test/cases/adapters/postgresql/xml_test.rb @@ -23,7 +23,7 @@ class PostgresqlXMLTest < ActiveRecord::TestCase @column = XmlDataType.columns.find { |c| c.name == 'payload' } end - def teardown + teardown do @connection.execute 'drop table if exists xml_data_type' end diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb index 500df52cd8..811695938e 100644 --- a/activerecord/test/cases/ar_schema_test.rb +++ b/activerecord/test/cases/ar_schema_test.rb @@ -10,7 +10,7 @@ if ActiveRecord::Base.connection.supports_migrations? ActiveRecord::SchemaMigration.drop_table end - def teardown + teardown do @connection.drop_table :fruits rescue nil @connection.drop_table :nep_fruits rescue nil @connection.drop_table :nep_schema_migrations rescue nil diff --git a/activerecord/test/cases/associations/eager_load_nested_include_test.rb b/activerecord/test/cases/associations/eager_load_nested_include_test.rb index 5ff117eaa0..0ff87d53ea 100644 --- a/activerecord/test/cases/associations/eager_load_nested_include_test.rb +++ b/activerecord/test/cases/associations/eager_load_nested_include_test.rb @@ -68,7 +68,7 @@ class EagerLoadPolyAssocsTest < ActiveRecord::TestCase generate_test_object_graphs end - def teardown + teardown do [Circle, Square, Triangle, PaintColor, PaintTexture, ShapeExpression, NonPolyOne, NonPolyTwo].each do |c| c.delete_all @@ -111,7 +111,7 @@ class EagerLoadNestedIncludeWithMissingDataTest < ActiveRecord::TestCase @first_categorization = @davey_mcdave.categorizations.create(:category => Category.first, :post => @first_post) end - def teardown + teardown do @davey_mcdave.destroy @first_post.destroy @first_comment.destroy diff --git a/activerecord/test/cases/associations/eager_singularization_test.rb b/activerecord/test/cases/associations/eager_singularization_test.rb index b12bc355e8..a61a070331 100644 --- a/activerecord/test/cases/associations/eager_singularization_test.rb +++ b/activerecord/test/cases/associations/eager_singularization_test.rb @@ -90,7 +90,7 @@ class EagerSingularizationTest < ActiveRecord::TestCase end end - def teardown + teardown do connection.drop_table :viri connection.drop_table :octopi connection.drop_table :passes diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index 173081cb28..952baaca36 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -22,7 +22,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase @target.table_name = 'topics' end - def teardown + teardown do ActiveRecord::Base.send(:attribute_method_matchers).clear ActiveRecord::Base.send(:attribute_method_matchers).concat(@old_matchers) end diff --git a/activerecord/test/cases/bind_parameter_test.rb b/activerecord/test/cases/bind_parameter_test.rb index 291751c435..24eb91bef9 100644 --- a/activerecord/test/cases/bind_parameter_test.rb +++ b/activerecord/test/cases/bind_parameter_test.rb @@ -25,7 +25,7 @@ module ActiveRecord ActiveSupport::Notifications.subscribe('sql.active_record', @listener) end - def teardown + teardown do ActiveSupport::Notifications.unsubscribe(@listener) end diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb index 599e8c762c..bca63f6b97 100644 --- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb +++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb @@ -13,7 +13,7 @@ module ActiveRecord @previous_database_url = ENV.delete("DATABASE_URL") end - def teardown + teardown do ENV["DATABASE_URL"] = @previous_database_url end diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index 1cf215017b..c4108ad7f6 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -22,8 +22,7 @@ module ActiveRecord end end - def teardown - super + teardown do @pool.disconnect! end diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb index 7e3d91e08c..7d438803a1 100644 --- a/activerecord/test/cases/defaults_test.rb +++ b/activerecord/test/cases/defaults_test.rb @@ -206,7 +206,7 @@ if current_adapter?(:PostgreSQLAdapter) assert_equal "some text", Default.new.text_col, "Default of text column was not correctly parse after updating default using '::text' since postgreSQL will add parens to the default in db" end - def teardown + teardown do @connection.schema_search_path = @old_search_path Default.reset_column_information end diff --git a/activerecord/test/cases/disconnected_test.rb b/activerecord/test/cases/disconnected_test.rb index 9e268dad74..94447addc1 100644 --- a/activerecord/test/cases/disconnected_test.rb +++ b/activerecord/test/cases/disconnected_test.rb @@ -10,7 +10,7 @@ class TestDisconnectedAdapter < ActiveRecord::TestCase @connection = ActiveRecord::Base.connection end - def teardown + teardown do return if in_memory_db? spec = ActiveRecord::Base.connection_config ActiveRecord::Base.establish_connection(spec) diff --git a/activerecord/test/cases/explain_subscriber_test.rb b/activerecord/test/cases/explain_subscriber_test.rb index b00e2744b9..8de2ddb10d 100644 --- a/activerecord/test/cases/explain_subscriber_test.rb +++ b/activerecord/test/cases/explain_subscriber_test.rb @@ -48,7 +48,7 @@ if ActiveRecord::Base.connection.supports_explain? assert queries.empty? end - def teardown + teardown do ActiveRecord::ExplainRegistry.reset end diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index e2ff2aa451..f5f85f2412 100644 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -339,7 +339,7 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase ActiveSupport::Dependencies.log_activity = true end - def teardown + teardown do ActiveSupport::Dependencies.log_activity = false self.class.const_remove :FirmOnTheFly rescue nil Firm.const_remove :FirmOnTheFly rescue nil diff --git a/activerecord/test/cases/invalid_connection_test.rb b/activerecord/test/cases/invalid_connection_test.rb index f6774d7ef4..8416c81f45 100644 --- a/activerecord/test/cases/invalid_connection_test.rb +++ b/activerecord/test/cases/invalid_connection_test.rb @@ -12,7 +12,7 @@ class TestAdapterWithInvalidConnection < ActiveRecord::TestCase Bird.establish_connection adapter: 'mysql', database: 'i_do_not_exist' end - def teardown + teardown do Bird.remove_connection end diff --git a/activerecord/test/cases/invertible_migration_test.rb b/activerecord/test/cases/invertible_migration_test.rb index 2b1749cf70..285172d33e 100644 --- a/activerecord/test/cases/invertible_migration_test.rb +++ b/activerecord/test/cases/invertible_migration_test.rb @@ -122,7 +122,7 @@ module ActiveRecord end end - def teardown + teardown do %w[horses new_horses].each do |table| if ActiveRecord::Base.connection.table_exists?(table) ActiveRecord::Base.connection.drop_table(table) diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb index 294f2eb9fe..5418d913b0 100644 --- a/activerecord/test/cases/migration/change_schema_test.rb +++ b/activerecord/test/cases/migration/change_schema_test.rb @@ -11,8 +11,7 @@ module ActiveRecord @table_name = :testings end - def teardown - super + teardown do connection.drop_table :testings rescue nil ActiveRecord::Base.primary_key_prefix_type = nil end diff --git a/activerecord/test/cases/migration/change_table_test.rb b/activerecord/test/cases/migration/change_table_test.rb index c1d7cd5874..a6d506b04a 100644 --- a/activerecord/test/cases/migration/change_table_test.rb +++ b/activerecord/test/cases/migration/change_table_test.rb @@ -8,7 +8,7 @@ module ActiveRecord @connection = Minitest::Mock.new end - def teardown + teardown do assert @connection.verify end diff --git a/activerecord/test/cases/migration/column_positioning_test.rb b/activerecord/test/cases/migration/column_positioning_test.rb index 87e29e41ba..77a752f050 100644 --- a/activerecord/test/cases/migration/column_positioning_test.rb +++ b/activerecord/test/cases/migration/column_positioning_test.rb @@ -18,8 +18,7 @@ module ActiveRecord end end - def teardown - super + teardown do connection.drop_table :testings rescue nil ActiveRecord::Base.primary_key_prefix_type = nil end diff --git a/activerecord/test/cases/migration/create_join_table_test.rb b/activerecord/test/cases/migration/create_join_table_test.rb index efaec0f823..62b60f7f7b 100644 --- a/activerecord/test/cases/migration/create_join_table_test.rb +++ b/activerecord/test/cases/migration/create_join_table_test.rb @@ -10,8 +10,7 @@ module ActiveRecord @connection = ActiveRecord::Base.connection end - def teardown - super + teardown do %w(artists_musics musics_videos catalog).each do |table_name| connection.drop_table table_name if connection.tables.include?(table_name) end diff --git a/activerecord/test/cases/migration/index_test.rb b/activerecord/test/cases/migration/index_test.rb index 8d1daa0a04..35af11f672 100644 --- a/activerecord/test/cases/migration/index_test.rb +++ b/activerecord/test/cases/migration/index_test.rb @@ -21,8 +21,7 @@ module ActiveRecord end end - def teardown - super + teardown do connection.drop_table :testings rescue nil ActiveRecord::Base.primary_key_prefix_type = nil end diff --git a/activerecord/test/cases/migration/logger_test.rb b/activerecord/test/cases/migration/logger_test.rb index 97efb94b66..84224e6e4c 100644 --- a/activerecord/test/cases/migration/logger_test.rb +++ b/activerecord/test/cases/migration/logger_test.rb @@ -19,8 +19,7 @@ module ActiveRecord ActiveRecord::SchemaMigration.delete_all end - def teardown - super + teardown do ActiveRecord::SchemaMigration.drop_table end diff --git a/activerecord/test/cases/migration/references_index_test.rb b/activerecord/test/cases/migration/references_index_test.rb index 19eb7d3c9e..4485701a4e 100644 --- a/activerecord/test/cases/migration/references_index_test.rb +++ b/activerecord/test/cases/migration/references_index_test.rb @@ -11,8 +11,7 @@ module ActiveRecord @table_name = :testings end - def teardown - super + teardown do connection.drop_table :testings rescue nil end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 1bda472d23..455ec78f68 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -33,7 +33,7 @@ class MigrationTest < ActiveRecord::TestCase ActiveRecord::Base.connection.schema_cache.clear! end - def teardown + teardown do ActiveRecord::Base.table_name_prefix = "" ActiveRecord::Base.table_name_suffix = "" @@ -585,7 +585,7 @@ if ActiveRecord::Base.connection.supports_bulk_alter? Person.reset_sequence_name end - def teardown + teardown do Person.connection.drop_table(:delete_me) rescue nil end diff --git a/activerecord/test/cases/migrator_test.rb b/activerecord/test/cases/migrator_test.rb index 3f9854200d..c77a818b93 100644 --- a/activerecord/test/cases/migrator_test.rb +++ b/activerecord/test/cases/migrator_test.rb @@ -26,8 +26,7 @@ module ActiveRecord ActiveRecord::SchemaMigration.delete_all rescue nil end - def teardown - super + teardown do ActiveRecord::SchemaMigration.delete_all rescue nil ActiveRecord::Migration.verbose = true end diff --git a/activerecord/test/cases/modules_test.rb b/activerecord/test/cases/modules_test.rb index 9124105e6d..f7db195521 100644 --- a/activerecord/test/cases/modules_test.rb +++ b/activerecord/test/cases/modules_test.rb @@ -18,7 +18,7 @@ class ModulesTest < ActiveRecord::TestCase ActiveRecord::Base.store_full_sti_class = false end - def teardown + teardown do # reinstate the constants that we undefined in the setup @undefined_consts.each do |constant, value| Object.send :const_set, constant, value unless value.nil? diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 2f89699df7..6bec760ea7 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -28,7 +28,7 @@ end class TestNestedAttributesInGeneral < ActiveRecord::TestCase include AssertRaiseWithMessage - def teardown + teardown do Pirate.accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } end diff --git a/activerecord/test/cases/pooled_connections_test.rb b/activerecord/test/cases/pooled_connections_test.rb index 626c6aeaf8..dd0e934ec2 100644 --- a/activerecord/test/cases/pooled_connections_test.rb +++ b/activerecord/test/cases/pooled_connections_test.rb @@ -10,7 +10,7 @@ class PooledConnectionsTest < ActiveRecord::TestCase @connection = ActiveRecord::Base.remove_connection end - def teardown + teardown do ActiveRecord::Base.clear_all_connections! ActiveRecord::Base.establish_connection(@connection) @per_test_teardown.each {|td| td.call } diff --git a/activerecord/test/cases/reaper_test.rb b/activerecord/test/cases/reaper_test.rb index b62a41c08e..015c37cce8 100644 --- a/activerecord/test/cases/reaper_test.rb +++ b/activerecord/test/cases/reaper_test.rb @@ -10,8 +10,7 @@ module ActiveRecord @pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec end - def teardown - super + teardown do @pool.connections.each(&:close) end diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb index bc67da8d27..5609cf310c 100644 --- a/activerecord/test/cases/serialized_attribute_test.rb +++ b/activerecord/test/cases/serialized_attribute_test.rb @@ -10,8 +10,7 @@ class SerializedAttributeTest < ActiveRecord::TestCase MyObject = Struct.new :attribute1, :attribute2 - def teardown - super + teardown do Topic.serialize("content") end diff --git a/activerecord/test/cases/unconnected_test.rb b/activerecord/test/cases/unconnected_test.rb index e82ca3f93d..afb893a52c 100644 --- a/activerecord/test/cases/unconnected_test.rb +++ b/activerecord/test/cases/unconnected_test.rb @@ -11,7 +11,7 @@ class TestUnconnectedAdapter < ActiveRecord::TestCase @specification = ActiveRecord::Base.remove_connection end - def teardown + teardown do @underlying = nil ActiveRecord::Base.establish_connection(@specification) load_schema if in_memory_db? diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb index efa0c9b934..3db742c15b 100644 --- a/activerecord/test/cases/validations/i18n_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_validation_test.rb @@ -14,7 +14,7 @@ class I18nValidationTest < ActiveRecord::TestCase I18n.backend.store_translations('en', :errors => {:messages => {:custom => nil}}) end - def teardown + teardown do I18n.load_path.replace @old_load_path I18n.backend = @old_backend end -- cgit v1.2.3 From 933e9b4fe2710f8a5bfe0b00c09361e1aea12a9d Mon Sep 17 00:00:00 2001 From: Kevin Casey Date: Mon, 17 Feb 2014 18:41:21 -0800 Subject: re-raise error if error occurs before committing in streaming update the tests, using an if-else --- actionpack/lib/action_controller/metal/live.rb | 21 +++++++++++---------- actionpack/test/controller/live_stream_test.rb | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/actionpack/lib/action_controller/metal/live.rb b/actionpack/lib/action_controller/metal/live.rb index 41b997a755..acf40b2e16 100644 --- a/actionpack/lib/action_controller/metal/live.rb +++ b/actionpack/lib/action_controller/metal/live.rb @@ -228,18 +228,19 @@ module ActionController begin super(name) rescue => e - unless @_response.committed? + if @_response.committed? + begin + @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html + @_response.stream.call_on_error + rescue => exception + log_error(exception) + ensure + log_error(e) + @_response.stream.close + end + else error = e end - begin - @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html - @_response.stream.call_on_error - rescue => exception - log_error(exception) - ensure - log_error(e) - @_response.stream.close - end ensure @_response.commit! end diff --git a/actionpack/test/controller/live_stream_test.rb b/actionpack/test/controller/live_stream_test.rb index 2fd5c930ba..947f64176b 100644 --- a/actionpack/test/controller/live_stream_test.rb +++ b/actionpack/test/controller/live_stream_test.rb @@ -153,6 +153,11 @@ module ActionController render 'doesntexist' end + def exception_in_view_after_commit + response.stream.write "" + render 'doesntexist' + end + def exception_with_callback response.headers['Content-Type'] = 'text/event-stream' @@ -269,6 +274,13 @@ module ActionController assert_raises(ActionView::MissingTemplate) do get :exception_in_view end + + capture_log_output do |output| + get :exception_in_view_after_commit + assert_match %r((window\.location = "/500\.html")$), response.body + assert_match 'Missing template test/doesntexist', output.rewind && output.read + assert_stream_closed + end assert response.body assert_stream_closed end @@ -277,6 +289,13 @@ module ActionController assert_raises(ActionView::MissingTemplate) do get :exception_in_view, format: :json end + + capture_log_output do |output| + get :exception_in_view_after_commit, format: :json + assert_equal '', response.body + assert_match 'Missing template test/doesntexist', output.rewind && output.read + assert_stream_closed + end end def test_exception_callback_when_committed -- cgit v1.2.3 From 7a5601c432d3906cc6ab853b3316e76a162f75d1 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 15 Mar 2014 06:26:06 -0700 Subject: Remove deprecation on active_support/core_ext/class/attribute_accessors requires. Appropriate to keep this, users don't care that the implementation got unified. --- .../lib/active_support/core_ext/class/attribute_accessors.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb index 083b165dce..84d5e95e7a 100644 --- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb +++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb @@ -1,6 +1,4 @@ -require 'active_support/deprecation' +# cattr_* became mattr_* aliases in 7dfbd91b0780fbd6a1dd9bfbc176e10894871d2d, +# but we keep this around for libraries that directly require it knowing they +# want cattr_*. No need to deprecate. require 'active_support/core_ext/module/attribute_accessors' - -ActiveSupport::Deprecation.warn( - "The cattr_* method definitions have been moved into active_support/core_ext/module/attribute_accessors. Please require that instead." -) -- cgit v1.2.3 From 0da775846aa186238ad1813ed414ae508ae0f706 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 15 Mar 2014 06:55:14 -0700 Subject: Clarify AV::Digestor.digest method signature docs and deprecation warning --- actionview/lib/action_view/digestor.rb | 43 +++++++++++++++---------------- actionview/test/template/digestor_test.rb | 4 +-- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index c302bc15fa..40d493da64 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -17,8 +17,8 @@ module ActionView # * finder - An instance of ActionView::LookupContext # * dependencies - An array of dependent views # * partial - Specifies whether the template is a partial - def digest(*args) - options = _options_for_digest(*args) + def digest(options_or_deprecated_name, *deprecated_args) + options = _options_for_digest(options_or_deprecated_name, *deprecated_args) details_key = options[:finder].details_key.hash dependencies = Array.wrap(options[:dependencies]) @@ -33,20 +33,22 @@ module ActionView end end - def _options_for_digest(*args) - unless args.first.is_a?(Hash) - ActiveSupport::Deprecation.warn("Arguments to ActionView::Digestor should be provided as a hash. The support for regular arguments will be removed in Rails 5.0 or later") - - { - name: args.first, - format: args.second, - finder: args.third, - }.merge(args.fourth || {}) + def _options_for_digest(options_or_deprecated_name, *deprecated_args) + if !options_or_deprecated_name.is_a?(Hash) + ActiveSupport::Deprecation.warn \ + 'ActionView::Digestor.digest changed its method signature from ' \ + '#digest(name, format, finder, options) to #digest(options), ' \ + 'with options now including :name, :format, :finder, and ' \ + ':variant. Please update your code to pass a Hash argument. ' \ + 'Support for the old method signature will be removed in Rails 5.0.' + + _options_for_digest (deprecated_args[2] || {}).merge \ + name: options_or_deprecated_name, + format: deprecated_args[0], + finder: deprecated_args[1] else - options = args.first - options.assert_valid_keys(:name, :format, :variant, :finder, :dependencies, :partial) - - options + options_or_deprecated_name.assert_valid_keys(:name, :format, :variant, :finder, :dependencies, :partial) + options_or_deprecated_name end end @@ -75,13 +77,10 @@ module ActionView attr_reader :name, :format, :variant, :finder, :options - def initialize(*args) - @options = self.class._options_for_digest(*args) - - @name = @options.delete(:name) - @format = @options.delete(:format) - @variant = @options.delete(:variant) - @finder = @options.delete(:finder) + def initialize(options_or_deprecated_name, *deprecated_args) + options = self.class._options_for_digest(options_or_deprecated_name, *deprecated_args) + @options = options.except(:name, :format, :variant, :finder) + @name, @format, @variant, @finder = options.values_at(:name, :format, :variant, :finder) end def digest diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index 1c47952f54..0cbfd14c94 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -262,8 +262,8 @@ class TemplateDigestorTest < ActionView::TestCase end def test_arguments_deprecation - assert_deprecated(/should be provided as a hash/) { ActionView::Digestor.digest('messages/show', :html, finder) } - assert_deprecated(/should be provided as a hash/) { ActionView::Digestor.new('messages/show', :html, finder) } + assert_deprecated(/will be removed/) { ActionView::Digestor.digest('messages/show', :html, finder) } + assert_deprecated(/will be removed/) { ActionView::Digestor.new('messages/show', :html, finder) } end private -- cgit v1.2.3 From 2156df13e08ff716463603730657bd321c03f8b4 Mon Sep 17 00:00:00 2001 From: Zoltan Kiss Date: Fri, 14 Mar 2014 18:08:18 -0500 Subject: Minor grammer, code conventions fix [ci skip] Conflicts: activesupport/lib/active_support/core_ext/hash/conversions.rb --- activesupport/lib/active_support/core_ext/hash/conversions.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb index 7bea461c77..6c3e48a3ca 100644 --- a/activesupport/lib/active_support/core_ext/hash/conversions.rb +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb @@ -105,7 +105,7 @@ class Hash # hash = Hash.from_xml(xml) # # => {"hash"=>{"foo"=>1, "bar"=>2}} # - # DisallowedType is raised if the XML contains attributes with type="yaml" or + # +DisallowedType+ is raised if the XML contains attributes with type="yaml" or # type="symbol". Use Hash.from_trusted_xml to parse this XML. def from_xml(xml, disallowed_types = nil) ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h @@ -241,4 +241,3 @@ module ActiveSupport end end - -- cgit v1.2.3 From f870c4d063f6ac3b5fe96670955a08fcd7e15e67 Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Sat, 15 Mar 2014 18:56:32 -0400 Subject: Fix MailerPreview broken tests `BaseMailerPreview.welcome` is an instance method, so we need to stub the method on a instance level and not on Class. The stub is important to make sure the Message object is the same in the other expectations. This was working randomly because Mocha uses == to compare two objects on the `with()` expectation and even if the Mail::Message objects were not the same object they are equal, but thats not the case in 100% of the runs. So we need to make sure we use `.any_instance` method and have the right message object. --- actionmailer/test/base_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index d4a89a17ee..b66e5bd6a3 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -594,7 +594,7 @@ class BaseTest < ActiveSupport::TestCase test "you can register a preview interceptor to the mail object that gets passed the mail object before previewing" do ActionMailer::Base.register_preview_interceptor(MyInterceptor) mail = BaseMailer.welcome - BaseMailerPreview.stubs(:welcome).returns(mail) + BaseMailerPreview.any_instance.stubs(:welcome).returns(mail) MyInterceptor.expects(:previewing_email).with(mail) BaseMailerPreview.call(:welcome) end @@ -602,7 +602,7 @@ class BaseTest < ActiveSupport::TestCase test "you can register a preview interceptor using its stringified name to the mail object that gets passed the mail object before previewing" do ActionMailer::Base.register_preview_interceptor("BaseTest::MyInterceptor") mail = BaseMailer.welcome - BaseMailerPreview.stubs(:welcome).returns(mail) + BaseMailerPreview.any_instance.stubs(:welcome).returns(mail) MyInterceptor.expects(:previewing_email).with(mail) BaseMailerPreview.call(:welcome) end @@ -610,7 +610,7 @@ class BaseTest < ActiveSupport::TestCase test "you can register an interceptor using its symbolized underscored name to the mail object that gets passed the mail object before previewing" do ActionMailer::Base.register_preview_interceptor(:"base_test/my_interceptor") mail = BaseMailer.welcome - BaseMailerPreview.stubs(:welcome).returns(mail) + BaseMailerPreview.any_instance.stubs(:welcome).returns(mail) MyInterceptor.expects(:previewing_email).with(mail) BaseMailerPreview.call(:welcome) end @@ -618,7 +618,7 @@ class BaseTest < ActiveSupport::TestCase test "you can register multiple preview interceptors to the mail object that both get passed the mail object before previewing" do ActionMailer::Base.register_preview_interceptors("BaseTest::MyInterceptor", MySecondInterceptor) mail = BaseMailer.welcome - BaseMailerPreview.stubs(:welcome).returns(mail) + BaseMailerPreview.any_instance.stubs(:welcome).returns(mail) MyInterceptor.expects(:previewing_email).with(mail) MySecondInterceptor.expects(:previewing_email).with(mail) BaseMailerPreview.call(:welcome) -- cgit v1.2.3 From 024e5e3104ecfaa3856b500dbe1547be8cb7e9f1 Mon Sep 17 00:00:00 2001 From: Afshin Mokhtari Date: Sat, 15 Mar 2014 23:28:34 +0000 Subject: Reword 5.6 strong parameters and private method stuff [ci skip] --- guides/source/getting_started.md | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index bb8753cb2e..17a21778ee 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -749,10 +749,33 @@ article. Try it! You should get an error that looks like this: Rails has several security features that help you write secure applications, and you're running into one of them now. This one is called -`strong_parameters`, which requires us to tell Rails exactly which parameters -we want to accept in our controllers. In this case, we want to allow the -`title` and `text` parameters, so add the new `article_params` method, and -change your `create` controller action to use it, like this: +`[strong_parameters](http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters)`, +which requires us to tell Rails exactly which parameters are allowed into +our controller actions. + +Why do you have to bother? The ability to grab and automatically assign +all controller parameters to your model in one shot makes the programmer's +job easier, but this convenience also allows malicious use. What if a +request to the server was crafted to look like a new article form submit +but also included extra fields with values that violated your applications +integrity? They would be 'mass assigned' into your model and then into the +database along with the good stuff - potentially breaking your application +or worse. + +We have to whitelist our controller parameters to prevent wrongful +mass assignment. In this case, we want to both allow and require the +`title` and `text` parameters for valid use of `create`. The syntax for +this introduces `require` and `permit`. The change will involve one line: + +```ruby + @article = Article.new(params.require(:article).permit(:title, :text)) +``` + +This is often factored out into its own method so it can be reused by +multiple actions in the same controller, for example `create` and `update`. +Above and beyond mass assignment issues, the method is often made +`private` to make sure it can't be called outside its intended context. +Here is the result: ```ruby def create @@ -768,13 +791,7 @@ private end ``` -See the `permit`? It allows us to accept both `title` and `text` in this -action. - -TIP: Note that `def article_params` is private. This new approach prevents an -attacker from setting the model's attributes by manipulating the hash passed to -the model. -For more information, refer to +TIP: For more information, refer to the reference above and [this blog article about Strong Parameters](http://weblog.rubyonrails.org/2012/3/21/strong-parameters/). ### Showing Articles -- cgit v1.2.3 From f47421f2a058a5ca845969e8d15be2028c3e6972 Mon Sep 17 00:00:00 2001 From: Eric Steele Date: Sat, 15 Mar 2014 21:49:04 -0400 Subject: Extend fixture label replacement to allow string interpolation Allows fixtures to use their $LABEL as part of a string instead of limiting use to the entire value. mark: first_name: $LABEL username: $LABEL1973 email: $LABEL@$LABELmail.com users(:mark).first_name # => mark users(:mark).username # => mark1973 users(:mark).email # => mark@markmail.com --- activerecord/CHANGELOG.md | 10 ++++++++++ activerecord/lib/active_record/fixtures.rb | 3 ++- activerecord/test/cases/fixtures_test.rb | 4 ++++ activerecord/test/fixtures/pirates.yml | 3 +++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index d6044988f0..98f883fdb8 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,13 @@ +* Extend Fixture $LABEL replacement to allow string interpolation + Example: + + martin: + email: $LABEL@email.com + + users(:martin).email # => martin@email.com + + *Eric Steele* + * Add support for `Relation` be passed as parameter on `QueryCache#select_all`. Fixes #14361. diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 59467636d7..6f134bbef8 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -361,6 +361,7 @@ module ActiveRecord # geeksomnia: # name: Geeksomnia's Account # subdomain: $LABEL + # email: $LABEL@email.com # # Also, sometimes (like when porting older join table fixtures) you'll need # to be able to get a hold of the identifier for a given label. ERB @@ -627,7 +628,7 @@ module ActiveRecord # interpolate the fixture label row.each do |key, value| - row[key] = label if "$LABEL" == value + row[key] = value.gsub("$LABEL", label) if value.is_a?(String) end # generate a primary key if necessary diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index 37c6af74da..1147418815 100644 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -782,6 +782,10 @@ class FoxyFixturesTest < ActiveRecord::TestCase assert_equal("frederick", parrots(:frederick).name) end + def test_supports_label_string_interpolation + assert_equal("X marks the spot!", pirates(:mark).catchphrase) + end + def test_supports_polymorphic_belongs_to assert_equal(pirates(:redbeard), treasures(:sapphire).looter) assert_equal(parrots(:louis), treasures(:ruby).looter) diff --git a/activerecord/test/fixtures/pirates.yml b/activerecord/test/fixtures/pirates.yml index 6004f390a4..1bb3bf0051 100644 --- a/activerecord/test/fixtures/pirates.yml +++ b/activerecord/test/fixtures/pirates.yml @@ -7,3 +7,6 @@ redbeard: parrot: louis created_on: "<%= 2.weeks.ago.to_s(:db) %>" updated_on: "<%= 2.weeks.ago.to_s(:db) %>" + +mark: + catchphrase: "X $LABELs the spot!" -- cgit v1.2.3 From e9625d63bb427dc9746d8fadb9074057cd7ed11d Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sun, 16 Mar 2014 12:23:58 +0900 Subject: Let COMMAND_WHITELIST be an Array, not a String --- railties/lib/rails/commands/commands_tasks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/commands/commands_tasks.rb b/railties/lib/rails/commands/commands_tasks.rb index f061c2bf74..6cfbc70c51 100644 --- a/railties/lib/rails/commands/commands_tasks.rb +++ b/railties/lib/rails/commands/commands_tasks.rb @@ -27,7 +27,7 @@ In addition to those, there are: All commands can be run with -h (or --help) for more information. EOT - COMMAND_WHITELIST = %(plugin generate destroy console server dbconsole runner new version help) + COMMAND_WHITELIST = %w(plugin generate destroy console server dbconsole runner new version help) def initialize(argv) @argv = argv -- cgit v1.2.3 From af981764686c28db40305adf9cfc308f2e20ab50 Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Sun, 16 Mar 2014 10:07:31 +0100 Subject: Remove extra white-spaces [ci skip] Follow up to 024e5e31 --- guides/source/getting_started.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 17a21778ee..c54c9efe94 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -749,32 +749,32 @@ article. Try it! You should get an error that looks like this: Rails has several security features that help you write secure applications, and you're running into one of them now. This one is called -`[strong_parameters](http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters)`, +`[strong_parameters](http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters)`, which requires us to tell Rails exactly which parameters are allowed into our controller actions. Why do you have to bother? The ability to grab and automatically assign -all controller parameters to your model in one shot makes the programmer's -job easier, but this convenience also allows malicious use. What if a -request to the server was crafted to look like a new article form submit -but also included extra fields with values that violated your applications -integrity? They would be 'mass assigned' into your model and then into the +all controller parameters to your model in one shot makes the programmer's +job easier, but this convenience also allows malicious use. What if a +request to the server was crafted to look like a new article form submit +but also included extra fields with values that violated your applications +integrity? They would be 'mass assigned' into your model and then into the database along with the good stuff - potentially breaking your application or worse. -We have to whitelist our controller parameters to prevent wrongful -mass assignment. In this case, we want to both allow and require the -`title` and `text` parameters for valid use of `create`. The syntax for +We have to whitelist our controller parameters to prevent wrongful +mass assignment. In this case, we want to both allow and require the +`title` and `text` parameters for valid use of `create`. The syntax for this introduces `require` and `permit`. The change will involve one line: ```ruby @article = Article.new(params.require(:article).permit(:title, :text)) ``` -This is often factored out into its own method so it can be reused by +This is often factored out into its own method so it can be reused by multiple actions in the same controller, for example `create` and `update`. -Above and beyond mass assignment issues, the method is often made -`private` to make sure it can't be called outside its intended context. +Above and beyond mass assignment issues, the method is often made +`private` to make sure it can't be called outside its intended context. Here is the result: ```ruby @@ -791,7 +791,7 @@ private end ``` -TIP: For more information, refer to the reference above and +TIP: For more information, refer to the reference above and [this blog article about Strong Parameters](http://weblog.rubyonrails.org/2012/3/21/strong-parameters/). ### Showing Articles -- cgit v1.2.3 From bb0518891c4c7cc40ff01d90983b83beb61242af Mon Sep 17 00:00:00 2001 From: Andrew White Date: Sun, 16 Mar 2014 09:15:52 +0000 Subject: Use nested_scope? not shallow? to determine whether to copy options The method `shallow?` returns false if the parent resource is a singleton so we need to check if we're not inside a nested scope before copying the :path and :as options to their shallow equivalents. Fixes #14388. --- actionpack/CHANGELOG.md | 8 ++++++ actionpack/lib/action_dispatch/routing/mapper.rb | 6 +++- actionpack/test/dispatch/routing_test.rb | 36 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index c23577de9b..59460cbe82 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,11 @@ +* The method `shallow?` returns false if the parent resource is a singleton so + we need to check if we're not inside a nested scope before copying the :path + and :as options to their shallow equivalents. + + Fixes #14388. + + *Andrew White* + * Make logging of CSRF failures optional (but on by default) with the `log_warning_on_csrf_failure` configuration setting in `ActionController::RequestForgeryProtection`. diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 357829e59f..5de0a0cbc6 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -707,7 +707,7 @@ module ActionDispatch options[:path] = args.flatten.join('/') if args.any? options[:constraints] ||= {} - unless shallow? + unless nested_scope? options[:shallow_path] ||= options[:path] if options.key?(:path) options[:shallow_prefix] ||= options[:as] if options.key?(:as) end @@ -1547,6 +1547,10 @@ module ActionDispatch RESOURCE_METHOD_SCOPES.include? @scope[:scope_level] end + def nested_scope? #:nodoc: + @scope[:scope_level] == :nested + end + def with_exclusive_scope begin old_name_prefix, old_path = @scope[:as], @scope[:path] diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index a47050adce..ab2f0ec8de 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -1958,6 +1958,42 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal '/comments/3/preview', preview_comment_path(:id => '3') end + def test_shallow_nested_resources_inside_resource + draw do + resource :membership, shallow: true do + resources :cards + end + end + + get '/membership/cards' + assert_equal 'cards#index', @response.body + assert_equal '/membership/cards', membership_cards_path + + get '/membership/cards/new' + assert_equal 'cards#new', @response.body + assert_equal '/membership/cards/new', new_membership_card_path + + post '/membership/cards' + assert_equal 'cards#create', @response.body + + get '/cards/1' + assert_equal 'cards#show', @response.body + assert_equal '/cards/1', card_path('1') + + get '/cards/1/edit' + assert_equal 'cards#edit', @response.body + assert_equal '/cards/1/edit', edit_card_path('1') + + put '/cards/1' + assert_equal 'cards#update', @response.body + + patch '/cards/1' + assert_equal 'cards#update', @response.body + + delete '/cards/1' + assert_equal 'cards#destroy', @response.body + end + def test_shallow_nested_resources_within_scope draw do scope '/hello' do -- cgit v1.2.3 From ce38a6b8b62e73596ec1062663e85726fbca8933 Mon Sep 17 00:00:00 2001 From: robertomiranda Date: Sun, 16 Mar 2014 14:32:08 -0500 Subject: Fix Shadowing extensions variable in Register Annotation Exentsions --- railties/lib/rails/source_annotation_extractor.rb | 4 ++-- railties/test/application/rake/notes_test.rb | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index af6d90b5bd..201532d299 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -24,8 +24,8 @@ class SourceAnnotationExtractor # Registers new Annotations File Extensions # SourceAnnotationExtractor::Annotation.register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ } - def self.register_extensions(*extensions, &block) - self.extensions[/\.(#{extensions.join("|")})$/] = block + def self.register_extensions(*exts, &block) + extensions[/\.(#{exts.join("|")})$/] = block end register_extensions("builder", "rb", "rake", "yml", "yaml", "ruby") { |tag| /#\s*(#{tag}):?\s*(.*)$/ } diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index b6b1bd63f4..28efc84c57 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -25,7 +25,7 @@ module ApplicationTests app_file "lib/tasks/task.rake", "# TODO: note in rake" app_file 'app/views/home/index.html.builder', '# TODO: note in builder' app_file 'config/locales/en.yml', '# TODO: note in yml' - app_file 'config/locales/en.yaml', '# TODO: note in yml' + app_file 'config/locales/en.yaml', '# TODO: note in yaml' app_file "app/views/home/index.ruby", "# TODO: note in ruby" boot_rails @@ -40,13 +40,13 @@ module ApplicationTests lines = output.scan(/\[([0-9\s]+)\](\s)/) assert_match(/note in erb/, output) - assert_match(/note in ruby/, output) assert_match(/note in js/, output) assert_match(/note in css/, output) assert_match(/note in rake/, output) assert_match(/note in builder/, output) assert_match(/note in yml/, output) assert_match(/note in yaml/, output) + assert_match(/note in ruby/, output) assert_equal 9, lines.size @@ -170,9 +170,9 @@ module ApplicationTests end test 'register a new extension' do - SourceAnnotationExtractor::Annotation.register_extensions(".test1", ".test2") { |tag| /#{tag}/ } - assert SourceAnnotationExtractor::Annotation.extensions[/(\.test1|\.test2)/] - assert_blank SourceAnnotationExtractor::Annotation.extensions[/(\.haml)/] + SourceAnnotationExtractor::Annotation.register_extensions("test1", "test2"){ |tag| /#{tag}/ } + assert_not_nil SourceAnnotationExtractor::Annotation.extensions[/\.(test1|test2)$/] + assert_nil SourceAnnotationExtractor::Annotation.extensions[/\.(haml)$/] end private -- cgit v1.2.3 From 27e95727d7f1da623cd3f22b643ae5eb0d3a93b1 Mon Sep 17 00:00:00 2001 From: robertomiranda Date: Sun, 16 Mar 2014 14:57:21 -0500 Subject: Add config.annotations, in order to register new extensions for Rake notes at config level --- railties/lib/rails/application/configuration.rb | 4 ++++ railties/test/application/configuration_test.rb | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 20e3de32aa..9aec2f9734 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -1,6 +1,7 @@ require 'active_support/core_ext/kernel/reporting' require 'active_support/file_update_checker' require 'rails/engine/configuration' +require 'rails/source_annotation_extractor' module Rails class Application @@ -149,6 +150,9 @@ module Rails end end + def annotations + SourceAnnotationExtractor::Annotation + end end end end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index b39cd3747b..b11fd55170 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -793,5 +793,15 @@ module ApplicationTests assert ActiveRecord::Base.dump_schema_after_migration end + + test "config.annotations wrapping SourceAnnotationExtractor::Annotation class" do + make_basic_app do |app| + app.config.annotations.register_extensions("coffee") do |tag| + /#\s*(#{tag}):?\s*(.*)$/ + end + end + + assert_not_nil SourceAnnotationExtractor::Annotation.extensions[/\.(coffee)$/] + end end end -- cgit v1.2.3 From 4ece124396669d3580e7f229ab407a0d4882727a Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 16 Mar 2014 16:06:27 -0700 Subject: Avoid concurrent test collision on the same memcache server by namespacing keys --- actionpack/test/dispatch/session/mem_cache_store_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/test/dispatch/session/mem_cache_store_test.rb b/actionpack/test/dispatch/session/mem_cache_store_test.rb index e53ce4195b..f3cc4f31d8 100644 --- a/actionpack/test/dispatch/session/mem_cache_store_test.rb +++ b/actionpack/test/dispatch/session/mem_cache_store_test.rb @@ -172,7 +172,7 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest end @app = self.class.build_app(set) do |middleware| - middleware.use ActionDispatch::Session::MemCacheStore, :key => '_session_id' + middleware.use ActionDispatch::Session::MemCacheStore, :key => '_session_id', :namespace => "mem_cache_store_test:#{SecureRandom.hex(10)}" middleware.delete "ActionDispatch::ShowExceptions" end -- cgit v1.2.3 From cbc3b89c100faada58c2781f17296ade52a9bf05 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 16 Mar 2014 16:08:16 -0700 Subject: Add an explicit require for 4ece124396669d3580e7f229ab407a0d4882727a rather than assume SecureRandom is available --- actionpack/test/dispatch/session/mem_cache_store_test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/actionpack/test/dispatch/session/mem_cache_store_test.rb b/actionpack/test/dispatch/session/mem_cache_store_test.rb index f3cc4f31d8..92544230b2 100644 --- a/actionpack/test/dispatch/session/mem_cache_store_test.rb +++ b/actionpack/test/dispatch/session/mem_cache_store_test.rb @@ -1,4 +1,5 @@ require 'abstract_unit' +require 'securerandom' # You need to start a memcached server inorder to run these tests class MemCacheStoreTest < ActionDispatch::IntegrationTest -- cgit v1.2.3 From 1330274657dc59296c556e840a8870dd14bb84ae Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Fri, 14 Mar 2014 20:57:36 -0300 Subject: Fix assertions --- railties/test/application/rake/dbs_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb index 35d9c31c1e..6bf49f3d67 100644 --- a/railties/test/application/rake/dbs_test.rb +++ b/railties/test/application/rake/dbs_test.rb @@ -132,7 +132,7 @@ module ApplicationTests ActiveRecord::Base.connection_config[:database]) require "#{app_path}/app/models/book" #if structure is not loaded correctly, exception would be raised - assert Book.count, 0 + assert_equal 0, Book.count end end @@ -157,7 +157,7 @@ module ApplicationTests ActiveRecord::Base.establish_connection :test require "#{app_path}/app/models/book" #if structure is not loaded correctly, exception would be raised - assert Book.count, 0 + assert_equal 0, Book.count assert_match(/#{ActiveRecord::Base.configurations['test']['database']}/, ActiveRecord::Base.connection_config[:database]) end -- cgit v1.2.3 From a0c1c18e4d85e2d95241a1924683b396bd3ae4e5 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Mon, 17 Mar 2014 08:44:56 +0100 Subject: format ActiveRecord CHANGELOG. [ci skip] --- activerecord/CHANGELOG.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 98f883fdb8..4018b3fd84 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,4 +1,5 @@ -* Extend Fixture $LABEL replacement to allow string interpolation +* Extend fixture `$LABEL` replacement to allow string interpolation. + Example: martin: @@ -7,24 +8,24 @@ users(:martin).email # => martin@email.com *Eric Steele* - + * Add support for `Relation` be passed as parameter on `QueryCache#select_all`. Fixes #14361. *arthurnn* -* Passing an Active Record object to `find` is now deprecated. Call `.id` - on the object first. +* Passing an Active Record object to `find` is now deprecated. Call `.id` + on the object first. -* Passing an Active Record object to `exists?` is now deprecated. Call `.id` - on the object first. +* Passing an Active Record object to `find` or `exists?` is now deprecated. + Call `.id` on the object first. -* Only use BINARY for mysql case sensitive uniqueness check when column has a case insensitive collation. +* Only use BINARY for MySQL case sensitive uniqueness check when column has a case insensitive collation. *Ryuta Kamizono* -* Support for Mysql 5.6 Fractional Seconds. +* Support for MySQL 5.6 fractional seconds. *arthurnn*, *Tatsuhiko Miyagawa* -- cgit v1.2.3 From 378c8d2c996558aa4108280d5f0db8daf040d0fc Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Mon, 17 Mar 2014 10:55:21 +0100 Subject: fix `number_to_percentage` with `Float::NAN`, `Float::INFINITY`. Closes #14405. This is a follow-up to 9e997e9039435617b6a844158f5437e97f6bc107 to restore the documented behavior. --- actionview/CHANGELOG.md | 7 +++++++ actionview/test/template/number_helper_test.rb | 3 +++ .../active_support/number_helper/number_to_rounded_converter.rb | 3 +-- activesupport/test/number_helper_test.rb | 3 +++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index a0e773e887..db3fa3be86 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,10 @@ +* `number_to_percentage` does not crash with `Float::NAN` or `Float::INFINITY` + as input. + + Fixes #14405. + + *Yves Senn* + * Add `include_hidden` option to `collection_check_boxes` helper. *Vasiliy Ermolovich* diff --git a/actionview/test/template/number_helper_test.rb b/actionview/test/template/number_helper_test.rb index 11bc978324..adb888319d 100644 --- a/actionview/test/template/number_helper_test.rb +++ b/actionview/test/template/number_helper_test.rb @@ -32,6 +32,9 @@ class NumberHelperTest < ActionView::TestCase assert_equal "100%", number_to_percentage(100, precision: 0) assert_equal "123.4%", number_to_percentage(123.400, precision: 3, strip_insignificant_zeros: true) assert_equal "1.000,000%", number_to_percentage(1000, delimiter: ".", separator: ",") + assert_equal "98a%", number_to_percentage("98a") + assert_equal "NaN%", number_to_percentage(Float::NAN) + assert_equal "Inf%", number_to_percentage(Float::INFINITY) end def test_number_with_delimiter diff --git a/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb b/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb index c42354fc83..c45f6cdcfa 100644 --- a/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb +++ b/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb @@ -32,8 +32,7 @@ module ActiveSupport end formatted_string = - case rounded_number - when BigDecimal + if BigDecimal === rounded_number && rounded_number.finite? s = rounded_number.to_s('F') + '0'*precision a, b = s.split('.', 2) a + '.' + b[0, precision] diff --git a/activesupport/test/number_helper_test.rb b/activesupport/test/number_helper_test.rb index 6d8d835de7..9bdb92024e 100644 --- a/activesupport/test/number_helper_test.rb +++ b/activesupport/test/number_helper_test.rb @@ -79,6 +79,9 @@ module ActiveSupport assert_equal("123.4%", number_helper.number_to_percentage(123.400, :precision => 3, :strip_insignificant_zeros => true)) assert_equal("1.000,000%", number_helper.number_to_percentage(1000, :delimiter => '.', :separator => ',')) assert_equal("1000.000 %", number_helper.number_to_percentage(1000, :format => "%n %")) + assert_equal("98a%", number_helper.number_to_percentage("98a")) + assert_equal("NaN%", number_helper.number_to_percentage(Float::NAN)) + assert_equal("Inf%", number_helper.number_to_percentage(Float::INFINITY)) end end -- cgit v1.2.3 From 8ba60912ca42a66cb59a31346623a6f9d2439192 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Mon, 17 Mar 2014 14:20:23 +0100 Subject: `where.not` adds `references` for `includes`. Closes #14406. --- activerecord/CHANGELOG.md | 6 ++++++ activerecord/lib/active_record/relation/query_methods.rb | 2 ++ activerecord/test/cases/associations/eager_test.rb | 10 ++++++++++ activerecord/test/cases/relations_test.rb | 8 ++++++++ 4 files changed, 26 insertions(+) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 4018b3fd84..b648eed06a 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,9 @@ +* `where.not` adds `references` for `includes` like normal `where` calls do. + + Fixes #14406. + + *Yves Senn* + * Extend fixture `$LABEL` replacement to allow string interpolation. Example: diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 8c005a7222..e41df0ea29 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -49,6 +49,8 @@ module ActiveRecord Arel::Nodes::Not.new(rel) end end + + @scope.references!(PredicateBuilder.references(opts)) if Hash === opts @scope.where_values += where_value @scope end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 416a39ea4c..e59161fc5b 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1203,4 +1203,14 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal 5, author.posts.size } end + + test "including associations with where.not adds implicit references" do + author = assert_queries(2) { + Author.includes(:posts).where.not(posts: { title: 'Welcome to the weblog'} ).last + } + + assert_no_queries { + assert_equal 2, author.posts.size + } + end end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 3b4b4c92f0..fddb7c204a 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -1366,6 +1366,14 @@ class RelationTest < ActiveRecord::TestCase assert_equal ['comments'], scope.references_values end + def test_automatically_added_where_not_references + scope = Post.where.not(comments: { body: "Bla" }) + assert_equal ['comments'], scope.references_values + + scope = Post.where.not('comments.body' => 'Bla') + assert_equal ['comments'], scope.references_values + end + def test_automatically_added_having_references scope = Post.having(:comments => { :body => "Bla" }) assert_equal ['comments'], scope.references_values -- cgit v1.2.3 From 8eac0a6b5817defabef6cee2f12baeda26e91d8f Mon Sep 17 00:00:00 2001 From: robertomiranda Date: Sun, 16 Mar 2014 15:08:16 -0500 Subject: Add Changelog Entry ref #14379 --- railties/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 35b3a379ae..b52b80e802 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,11 @@ +* Add public API to register new extensions for `rake notes`. + + Example: + + config.annotations.register_extensions("scss", "sass") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ } + + *Roberto Miranda* + * Removed unnecessary `rails application` command. *Arun Agrawal* -- cgit v1.2.3 From 6b4793b1d2793e37a3cd314ab84edf5ccc2a2032 Mon Sep 17 00:00:00 2001 From: robertomiranda Date: Mon, 17 Mar 2014 10:31:21 -0500 Subject: Update command line guide --- guides/source/command_line.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/guides/source/command_line.md b/guides/source/command_line.md index 8949ef4c78..57283f7c40 100644 --- a/guides/source/command_line.md +++ b/guides/source/command_line.md @@ -411,7 +411,7 @@ The `doc:` namespace has the tools to generate documentation for your app, API d ### `notes` -`rake notes` will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is done in files with extension `.builder`, `.rb`, `.erb`, `.haml`, `.slim`, `.css`, `.scss`, `.js`, `.coffee`, `.rake`, `.sass` and `.less` for both default and custom annotations. +`rake notes` will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is done in files with extension `.builder`, `.rb`, `.rake`, `.yml`, `.yaml`, `.ruby`, `.css`, `.js` and `.erb` for both default and custom annotations. ```bash $ rake notes @@ -425,6 +425,12 @@ app/models/school.rb: * [ 17] [FIXME] ``` +You can add support for new file extensions using `config.annotations.register_extensions` option, which receives a list of the extensions with its corresponding regex to match it up. + +```ruby +config.annotations.register_extensions("scss", "sass", "less") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ } +``` + If you are looking for a specific annotation, say FIXME, you can use `rake notes:fixme`. Note that you have to lower case the annotation's name. ```bash -- cgit v1.2.3 From 3b073ac19530b657d7585047027dcf78a452161c Mon Sep 17 00:00:00 2001 From: robertomiranda Date: Mon, 17 Mar 2014 15:20:46 -0500 Subject: Rake notes should picked up new Extensions registered in the config/application.rb file --- railties/test/application/rake/notes_test.rb | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 28efc84c57..df5615be1c 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -170,9 +170,25 @@ module ApplicationTests end test 'register a new extension' do - SourceAnnotationExtractor::Annotation.register_extensions("test1", "test2"){ |tag| /#{tag}/ } - assert_not_nil SourceAnnotationExtractor::Annotation.extensions[/\.(test1|test2)$/] - assert_nil SourceAnnotationExtractor::Annotation.extensions[/\.(haml)$/] + add_to_config %q{ config.annotations.register_extensions("scss", "sass") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ } } + app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss" + app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass" + + boot_rails + + require 'rake' + require 'rdoc/task' + require 'rake/testtask' + + Rails.application.load_tasks + + Dir.chdir(app_path) do + output = `bundle exec rake notes` + lines = output.scan(/\[([0-9\s]+)\]/).flatten + assert_match(/note in scss/, output) + assert_match(/note in sass/, output) + assert_equal 2, lines.size + end end private -- cgit v1.2.3 From cc0d54bcc09a8ab834041787df69f6795a468b91 Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Sat, 8 Mar 2014 01:14:26 +1030 Subject: Teach PostgreSQLAdapter#reset! to actually reset It wasn't doing anything beyond clearing the statement cache. --- .../connection_adapters/postgresql_adapter.rb | 7 ++++- .../cases/adapters/postgresql/connection_test.rb | 31 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index e5f7913c70..49d1a20659 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -616,7 +616,12 @@ module ActiveRecord def reset! clear_cache! - super + reset_transaction + unless @connection.transaction_status == ::PG::PQTRANS_IDLE + @connection.query 'ROLLBACK' + end + @connection.query 'DISCARD ALL' + configure_connection end # Disconnects from the database if already connected. Otherwise, this diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb index 4715fa002d..aa4996133f 100644 --- a/activerecord/test/cases/adapters/postgresql/connection_test.rb +++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb @@ -45,6 +45,37 @@ module ActiveRecord assert_equal 'off', expect end + def test_reset + @connection.query('ROLLBACK') + @connection.query('SET geqo TO off') + + # Verify the setting has been applied. + expect = @connection.query('show geqo').first.first + assert_equal 'off', expect + + @connection.reset! + + # Verify the setting has been cleared. + expect = @connection.query('show geqo').first.first + assert_equal 'on', expect + end + + def test_reset_with_transaction + @connection.query('ROLLBACK') + @connection.query('SET geqo TO off') + + # Verify the setting has been applied. + expect = @connection.query('show geqo').first.first + assert_equal 'off', expect + + @connection.query('BEGIN') + @connection.reset! + + # Verify the setting has been cleared. + expect = @connection.query('show geqo').first.first + assert_equal 'on', expect + end + def test_tables_logs_name @connection.tables('hello') assert_equal 'SCHEMA', @subscriber.logged[0][1] -- cgit v1.2.3 From 9e457a8654fa89fe329719f88ae3679aefb21e56 Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Sat, 8 Mar 2014 00:06:09 +1030 Subject: Reap connections based on owning-thread death .. not a general timeout. Now, if a thread checks out a connection then dies, we can immediately recover that connection and re-use it. This should alleviate the pool exhaustion discussed in #12867. More importantly, it entirely avoids the potential issues of the reaper attempting to check whether connections are still active: as long as the owning thread is alive, the connection is its business alone. As a no-op reap is now trivial (only entails checking a thread status per connection), we can also perform one in-line any time we decide to sleep for a connection. --- activerecord/CHANGELOG.md | 8 ++++ .../abstract/connection_pool.rb | 56 +++++++++++----------- .../connection_adapters/abstract_adapter.rb | 20 +++----- .../connection_adapters/postgresql_adapter.rb | 4 -- .../connection_adapters/abstract_adapter_test.rb | 6 --- activerecord/test/cases/connection_pool_test.rb | 23 +++++---- activerecord/test/cases/reaper_test.rb | 17 ++++--- 7 files changed, 66 insertions(+), 68 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index b648eed06a..f5b8a3145d 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,11 @@ +* Reap connections that were checked out by now-dead threads, instead + of waiting until they disconnect by themselves. Before this change, + a suitably constructed series of short-lived threads could starve + the connection pool, without ever having more than a couple alive at + the same time. + + *Matthew Draper* + * `where.not` adds `references` for `includes` like normal `where` calls do. Fixes #14406. diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index fd185de589..db80c0faee 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -58,13 +58,11 @@ module ActiveRecord # * +checkout_timeout+: number of seconds to block and wait for a connection # before giving up and raising a timeout error (default 5 seconds). # * +reaping_frequency+: frequency in seconds to periodically run the - # Reaper, which attempts to find and close dead connections, which can - # occur if a programmer forgets to close a connection at the end of a - # thread or a thread dies unexpectedly. (Default nil, which means don't - # run the Reaper). - # * +dead_connection_timeout+: number of seconds from last checkout - # after which the Reaper will consider a connection reapable. (default - # 5 seconds). + # Reaper, which attempts to find and recover connections from dead + # threads, which can occur if a programmer forgets to close a + # connection at the end of a thread or a thread dies unexpectedly. + # Regardless of this setting, the Reaper will be invoked before every + # blocking wait. (Default nil, which means don't schedule the Reaper). class ConnectionPool # Threadsafe, fair, FIFO queue. Meant to be used by ConnectionPool # with which it shares a Monitor. But could be a generic Queue. @@ -222,7 +220,7 @@ module ActiveRecord include MonitorMixin - attr_accessor :automatic_reconnect, :checkout_timeout, :dead_connection_timeout + attr_accessor :automatic_reconnect, :checkout_timeout attr_reader :spec, :connections, :size, :reaper # Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification @@ -237,7 +235,6 @@ module ActiveRecord @spec = spec @checkout_timeout = spec.config[:checkout_timeout] || 5 - @dead_connection_timeout = spec.config[:dead_connection_timeout] || 5 @reaper = Reaper.new self, spec.config[:reaping_frequency] @reaper.run @@ -361,11 +358,13 @@ module ActiveRecord # calling +checkout+ on this pool. def checkin(conn) synchronize do + owner = conn.owner + conn.run_callbacks :checkin do conn.expire end - release conn + release conn, owner @available.add conn end @@ -378,22 +377,28 @@ module ActiveRecord @connections.delete conn @available.delete conn - # FIXME: we might want to store the key on the connection so that removing - # from the reserved hash will be a little easier. - release conn + release conn, conn.owner @available.add checkout_new_connection if @available.any_waiting? end end - # Removes dead connections from the pool. A dead connection can occur - # if a programmer forgets to close a connection at the end of a thread + # Recover lost connections for the pool. A lost connection can occur if + # a programmer forgets to checkin a connection at the end of a thread # or a thread dies unexpectedly. def reap - synchronize do - stale = Time.now - @dead_connection_timeout - connections.dup.each do |conn| - if conn.in_use? && stale > conn.last_use && !conn.active_threadsafe? + stale_connections = synchronize do + @connections.select do |conn| + conn.in_use? && !conn.owner.alive? + end + end + + stale_connections.each do |conn| + synchronize do + if conn.active? + conn.reset! + checkin conn + else remove conn end end @@ -415,20 +420,15 @@ module ActiveRecord elsif @connections.size < @size checkout_new_connection else + reap @available.poll(@checkout_timeout) end end - def release(conn) - thread_id = if @reserved_connections[current_connection_id] == conn - current_connection_id - else - @reserved_connections.keys.find { |k| - @reserved_connections[k] == conn - } - end + def release(conn, owner) + thread_id = owner.object_id - @reserved_connections.delete thread_id if thread_id + @reserved_connections.delete thread_id end def new_connection diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 496153af83..c7e5a18f02 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -71,8 +71,8 @@ module ActiveRecord define_callbacks :checkout, :checkin attr_accessor :visitor, :pool - attr_reader :schema_cache, :last_use, :in_use, :logger - alias :in_use? :in_use + attr_reader :schema_cache, :owner, :logger + alias :in_use? :owner def self.type_cast_config_to_integer(config) if config =~ SIMPLE_INT @@ -94,9 +94,8 @@ module ActiveRecord super() @connection = connection - @in_use = false + @owner = nil @instrumenter = ActiveSupport::Notifications.instrumenter - @last_use = false @logger = logger @pool = pool @schema_cache = SchemaCache.new self @@ -114,9 +113,8 @@ module ActiveRecord def lease synchronize do - unless in_use - @in_use = true - @last_use = Time.now + unless in_use? + @owner = Thread.current end end end @@ -127,7 +125,7 @@ module ActiveRecord end def expire - @in_use = false + @owner = nil end def unprepared_visitor @@ -262,12 +260,6 @@ module ActiveRecord def active? end - # Adapter should redefine this if it needs a threadsafe way to approximate - # if the connection is active - def active_threadsafe? - active? - end - # Disconnects from the database if already connected, and establishes a # new connection with the database. Implementors should call super if they # override the default implementation. diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 49d1a20659..bcad9f30d7 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -603,10 +603,6 @@ module ActiveRecord false end - def active_threadsafe? - @connection.connect_poll != PG::PGRES_POLLING_FAILED - end - # Close then reopen the connection. def reconnect! super diff --git a/activerecord/test/cases/connection_adapters/abstract_adapter_test.rb b/activerecord/test/cases/connection_adapters/abstract_adapter_test.rb index eb2fe5639b..deed226eab 100644 --- a/activerecord/test/cases/connection_adapters/abstract_adapter_test.rb +++ b/activerecord/test/cases/connection_adapters/abstract_adapter_test.rb @@ -29,12 +29,6 @@ module ActiveRecord assert_not adapter.lease, 'should not lease adapter' end - def test_last_use - assert_not adapter.last_use - adapter.lease - assert adapter.last_use - end - def test_expire_mutates_in_use assert adapter.lease, 'lease adapter' assert adapter.in_use?, 'adapter is in use' diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index c4108ad7f6..6300011f4a 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -124,7 +124,6 @@ module ActiveRecord @pool.checkout @pool.checkout @pool.checkout - @pool.dead_connection_timeout = 0 connections = @pool.connections.dup @@ -134,21 +133,25 @@ module ActiveRecord end def test_reap_inactive + ready = false @pool.checkout - @pool.checkout - @pool.checkout - @pool.dead_connection_timeout = 0 - - connections = @pool.connections.dup - connections.each do |conn| - conn.extend(Module.new { def active_threadsafe?; false; end; }) + child = Thread.new do + @pool.checkout + @pool.checkout + ready = true + Thread.stop end + Thread.pass until ready + + assert_equal 3, active_connections(@pool).size + child.terminate + child.join @pool.reap - assert_equal 0, @pool.connections.length + assert_equal 1, active_connections(@pool).size ensure - connections.each(&:close) + @pool.connections.each(&:close) end def test_remove_connection diff --git a/activerecord/test/cases/reaper_test.rb b/activerecord/test/cases/reaper_test.rb index 015c37cce8..f52fd22489 100644 --- a/activerecord/test/cases/reaper_test.rb +++ b/activerecord/test/cases/reaper_test.rb @@ -63,17 +63,22 @@ module ActiveRecord spec.config[:reaping_frequency] = 0.0001 pool = ConnectionPool.new spec - pool.dead_connection_timeout = 0 - conn = pool.checkout - count = pool.connections.length + conn = nil + child = Thread.new do + conn = pool.checkout + Thread.stop + end + Thread.pass while conn.nil? + + assert conn.in_use? - conn.extend(Module.new { def active_threadsafe?; false; end; }) + child.terminate - while count == pool.connections.length + while conn.in_use? Thread.pass end - assert_equal(count - 1, pool.connections.length) + assert !conn.in_use? end end end -- cgit v1.2.3 From 4db4f909174420904d48a9712e337b697d372ac3 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 17 Mar 2014 17:29:33 -0700 Subject: use a latch to avoid busy loops --- activerecord/test/cases/connection_pool_test.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index 6300011f4a..c0d5e3707c 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -1,4 +1,5 @@ require "cases/helper" +require 'active_support/concurrency/latch' module ActiveRecord module ConnectionAdapters @@ -133,15 +134,15 @@ module ActiveRecord end def test_reap_inactive - ready = false + ready = ActiveSupport::Concurrency::Latch.new @pool.checkout child = Thread.new do @pool.checkout @pool.checkout - ready = true + ready.release Thread.stop end - Thread.pass until ready + ready.await assert_equal 3, active_connections(@pool).size -- cgit v1.2.3 From 34e54fa0542ebb3403932ab785239119e449dc3c Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 17 Mar 2014 17:37:05 -0700 Subject: test should only pass if the pool.size+1 checkout fails Previously, any of the connection checkouts could have failed, and this test would pass. --- activerecord/test/cases/connection_pool_test.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index c0d5e3707c..8d15a76735 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -89,10 +89,9 @@ module ActiveRecord end def test_full_pool_exception + @pool.size.times { @pool.checkout } assert_raises(ConnectionTimeoutError) do - (@pool.size + 1).times do - @pool.checkout - end + @pool.checkout end end -- cgit v1.2.3 From e64875ffde5787eee24a96070f3cf51727347304 Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Mon, 17 Mar 2014 21:23:54 -0400 Subject: Add counter cache test for class_name Backport test from #14410 --- .../test/cases/associations/belongs_to_associations_test.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 9340bc0a83..56ac284331 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -824,6 +824,17 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal 0, comments(:greetings).reload.children_count end + def test_belongs_to_with_id_assigning + post = posts(:welcome) + comment = Comment.create! body: "foo", post: post + parent = comments(:greetings) + assert_equal 0, parent.reload.children_count + comment.parent_id = parent.id + + comment.save! + assert_equal 1, parent.reload.children_count + end + def test_polymorphic_with_custom_primary_key toy = Toy.create! sponsor = Sponsor.create!(:sponsorable => toy) -- cgit v1.2.3 From 4f90298d3752bb244d882374b16a0c6b06932b31 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Tue, 18 Mar 2014 21:16:36 +0100 Subject: Reorder conditional logic According to the best practice that "unless not" and "unless else" is hard to follow logically the link_to_unless and link_to_if were reversed. --- actionview/lib/action_view/helpers/url_helper.rb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 51379d433f..89c196e578 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -389,15 +389,7 @@ module ActionView # # If not... # # => Reply def link_to_unless(condition, name, options = {}, html_options = {}, &block) - if condition - if block_given? - block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block) - else - ERB::Util.html_escape(name) - end - else - link_to(name, options, html_options) - end + link_to_if !condition, name, options, html_options, &block end # Creates a link tag of the given +name+ using a URL created by the set of @@ -421,7 +413,15 @@ module ActionView # # If they are logged in... # # => my_username def link_to_if(condition, name, options = {}, html_options = {}, &block) - link_to_unless !condition, name, options, html_options, &block + if condition + link_to(name, options, html_options) + else + if block_given? + block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block) + else + ERB::Util.html_escape(name) + end + end end # Creates a mailto link tag to the specified +email_address+, which is -- cgit v1.2.3 From 2ec51d03ac30b8d86644a8e47872cb61f05d01f8 Mon Sep 17 00:00:00 2001 From: chriskohlbrenner Date: Wed, 19 Mar 2014 16:39:45 -0400 Subject: Fix a typo to make clause plural [ci skip] --- guides/source/active_record_querying.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 4900f176a6..0a332d7dd9 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -961,7 +961,7 @@ SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id = WARNING: This method only works with `INNER JOIN`. -Active Record lets you use the names of the [associations](association_basics.html) defined on the model as a shortcut for specifying `JOIN` clause for those associations when using the `joins` method. +Active Record lets you use the names of the [associations](association_basics.html) defined on the model as a shortcut for specifying `JOIN` clauses for those associations when using the `joins` method. For example, consider the following `Category`, `Post`, `Comment`, `Guest` and `Tag` models: -- cgit v1.2.3 From 3dad856a1a116b8c87c178c32d7dfec3b1241860 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Wed, 19 Mar 2014 15:19:44 -0700 Subject: Added a warning about serializing data with JSON cookie jars [skip ci] Closes #14409 --- guides/source/action_controller_overview.md | 24 ++++++++++++++++++++++++ guides/source/upgrading_ruby_on_rails.md | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md index 1f9342ca25..0f46ba8698 100644 --- a/guides/source/action_controller_overview.md +++ b/guides/source/action_controller_overview.md @@ -619,6 +619,30 @@ It is also possible to pass a custom serializer that responds to `load` and Rails.application.config.action_dispatch.cookies_serializer = MyCustomSerializer ``` +When using the `:json` or `:hybrid` serializer, you should beware that not all +Ruby objects can be serialized as JSON. For example, `Date` and `Time` objects +will be serialized as strings, and `Hash`es will have their keys stringified. + +```ruby +class CookiesController < ApplicationController + def set_cookie + cookies.encrypted[:expiration_date] = Date.tomorrow # => Thu, 20 Mar 2014 + redirect_to action: 'read_cookie' + end + + def read_cookie + cookies.encrypted[:expiration_date] # => "2014-03-20" + end +end +``` + +It's advisable that you only store simple data (strings and numbers) in cookies. +If you have to store complex objects, you would need to handle the conversion +manually when reading the values on subsequent requests. + +If you use the cookie session store, this would apply to the `session` and +`flash` hash as well. + Rendering XML and JSON data --------------------------- diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 7467648d49..d58024df3d 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -111,6 +111,30 @@ in your application, you can add an initializer file with the following content: This would transparently migrate your existing `Marshal`-serialized cookies into the new `JSON`-based format. +When using the `:json` or `:hybrid` serializer, you should beware that not all +Ruby objects can be serialized as JSON. For example, `Date` and `Time` objects +will be serialized as strings, and `Hash`es will have their keys stringified. + +```ruby +class CookiesController < ApplicationController + def set_cookie + cookies.encrypted[:expiration_date] = Date.tomorrow # => Thu, 20 Mar 2014 + redirect_to action: 'read_cookie' + end + + def read_cookie + cookies.encrypted[:expiration_date] # => "2014-03-20" + end +end +``` + +It's advisable that you only store simple data (strings and numbers) in cookies. +If you have to store complex objects, you would need to handle the conversion +manually when reading the values on subsequent requests. + +If you use the cookie session store, this would apply to the `session` and +`flash` hash as well. + ### Flash structure changes Flash message keys are -- cgit v1.2.3 From dcf7a166f231e58079fdd35a8dee814e1401f3d3 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Mon, 17 Mar 2014 20:12:53 -0300 Subject: Extract common setup for loading tasks in rake notes tests --- railties/test/application/rake/notes_test.rb | 43 +++++++++------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index df5615be1c..d535f51986 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -29,11 +29,7 @@ module ApplicationTests app_file "app/views/home/index.ruby", "# TODO: note in ruby" boot_rails - require 'rake' - require 'rdoc/task' - require 'rake/testtask' - - Rails.application.load_tasks + load_tasks Dir.chdir(app_path) do output = `bundle exec rake notes` @@ -67,12 +63,7 @@ module ApplicationTests app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" boot_rails - - require 'rake' - require 'rdoc/task' - require 'rake/testtask' - - Rails.application.load_tasks + load_tasks Dir.chdir(app_path) do output = `bundle exec rake notes` @@ -103,12 +94,7 @@ module ApplicationTests app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" boot_rails - - require 'rake' - require 'rdoc/task' - require 'rake/testtask' - - Rails.application.load_tasks + load_tasks Dir.chdir(app_path) do output = `SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bundle exec rake notes` @@ -145,12 +131,7 @@ module ApplicationTests EOS boot_rails - - require 'rake' - require 'rdoc/task' - require 'rake/testtask' - - Rails.application.load_tasks + load_tasks Dir.chdir(app_path) do output = `bundle exec rake notes_custom` @@ -175,12 +156,7 @@ module ApplicationTests app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass" boot_rails - - require 'rake' - require 'rdoc/task' - require 'rake/testtask' - - Rails.application.load_tasks + load_tasks Dir.chdir(app_path) do output = `bundle exec rake notes` @@ -192,6 +168,15 @@ module ApplicationTests end private + + def load_tasks + require 'rake' + require 'rdoc/task' + require 'rake/testtask' + + Rails.application.load_tasks + end + def boot_rails super require "#{app_path}/config/environment" -- cgit v1.2.3 From 3a3a386d4f6667c606fabdcb53c325e9d531d358 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Mon, 17 Mar 2014 20:56:10 -0300 Subject: Remove extra space assertion No need to check that each line contains an extra space, just matching the space in the regexp is enough to ensure that. --- railties/test/application/rake/notes_test.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index d535f51986..10e0d2568c 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -33,7 +33,7 @@ module ApplicationTests Dir.chdir(app_path) do output = `bundle exec rake notes` - lines = output.scan(/\[([0-9\s]+)\](\s)/) + lines = output.scan(/\[([0-9\s]+)\]\s/).flatten assert_match(/note in erb/, output) assert_match(/note in js/, output) @@ -47,8 +47,7 @@ module ApplicationTests assert_equal 9, lines.size lines.each do |line| - assert_equal 4, line[0].size - assert_equal ' ', line[1] + assert_equal 4, line.size end end end -- cgit v1.2.3 From 9c5c0bcfa6d81d45ef091dc8740623faa5e19784 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Mon, 17 Mar 2014 21:04:18 -0300 Subject: Extract rake notes command and lines scan boilerplate Refactor to a reusable method. --- railties/test/application/rake/notes_test.rb | 33 ++++++++++++---------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 10e0d2568c..23eb4c9939 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -31,10 +31,7 @@ module ApplicationTests boot_rails load_tasks - Dir.chdir(app_path) do - output = `bundle exec rake notes` - lines = output.scan(/\[([0-9\s]+)\]\s/).flatten - + run_rake_notes do |output, lines| assert_match(/note in erb/, output) assert_match(/note in js/, output) assert_match(/note in css/, output) @@ -64,10 +61,7 @@ module ApplicationTests boot_rails load_tasks - Dir.chdir(app_path) do - output = `bundle exec rake notes` - lines = output.scan(/\[([0-9\s]+)\]/).flatten - + run_rake_notes do |output, lines| assert_match(/note in app directory/, output) assert_match(/note in config directory/, output) assert_match(/note in db directory/, output) @@ -95,10 +89,7 @@ module ApplicationTests boot_rails load_tasks - Dir.chdir(app_path) do - output = `SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bundle exec rake notes` - lines = output.scan(/\[([0-9\s]+)\]/).flatten - + run_rake_notes "SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bundle exec rake notes" do |output, lines| assert_match(/note in app directory/, output) assert_match(/note in config directory/, output) assert_match(/note in db directory/, output) @@ -132,10 +123,7 @@ module ApplicationTests boot_rails load_tasks - Dir.chdir(app_path) do - output = `bundle exec rake notes_custom` - lines = output.scan(/\[([0-9\s]+)\]/).flatten - + run_rake_notes "bundle exec rake notes_custom" do |output, lines| assert_match(/\[FIXME\] note in lib directory/, output) assert_match(/\[TODO\] note in test directory/, output) assert_no_match(/OPTIMIZE/, output) @@ -157,9 +145,7 @@ module ApplicationTests boot_rails load_tasks - Dir.chdir(app_path) do - output = `bundle exec rake notes` - lines = output.scan(/\[([0-9\s]+)\]/).flatten + run_rake_notes do |output, lines| assert_match(/note in scss/, output) assert_match(/note in sass/, output) assert_equal 2, lines.size @@ -168,6 +154,15 @@ module ApplicationTests private + def run_rake_notes(command = 'bundle exec rake notes') + Dir.chdir(app_path) do + output = `#{command}` + lines = output.scan(/\[([0-9\s]+)\]\s/).flatten + + yield output, lines + end + end + def load_tasks require 'rake' require 'rdoc/task' -- cgit v1.2.3 From 29aff93dc4453cbe4c4cfa9e9c3dcf50338a6171 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Mon, 17 Mar 2014 21:05:10 -0300 Subject: Move booting/loading tasks setup to the rake notes helper method --- railties/test/application/rake/notes_test.rb | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 23eb4c9939..5a104e2ffe 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -28,9 +28,6 @@ module ApplicationTests app_file 'config/locales/en.yaml', '# TODO: note in yaml' app_file "app/views/home/index.ruby", "# TODO: note in ruby" - boot_rails - load_tasks - run_rake_notes do |output, lines| assert_match(/note in erb/, output) assert_match(/note in js/, output) @@ -58,9 +55,6 @@ module ApplicationTests app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" - boot_rails - load_tasks - run_rake_notes do |output, lines| assert_match(/note in app directory/, output) assert_match(/note in config directory/, output) @@ -86,9 +80,6 @@ module ApplicationTests app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" - boot_rails - load_tasks - run_rake_notes "SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bundle exec rake notes" do |output, lines| assert_match(/note in app directory/, output) assert_match(/note in config directory/, output) @@ -120,9 +111,6 @@ module ApplicationTests end EOS - boot_rails - load_tasks - run_rake_notes "bundle exec rake notes_custom" do |output, lines| assert_match(/\[FIXME\] note in lib directory/, output) assert_match(/\[TODO\] note in test directory/, output) @@ -142,9 +130,6 @@ module ApplicationTests app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss" app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass" - boot_rails - load_tasks - run_rake_notes do |output, lines| assert_match(/note in scss/, output) assert_match(/note in sass/, output) @@ -155,6 +140,9 @@ module ApplicationTests private def run_rake_notes(command = 'bundle exec rake notes') + boot_rails + load_tasks + Dir.chdir(app_path) do output = `#{command}` lines = output.scan(/\[([0-9\s]+)\]\s/).flatten -- cgit v1.2.3 From e0235c3721bf69be28f60819fa9695261fe387b5 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Mon, 17 Mar 2014 21:08:03 -0300 Subject: Refactor assertion of line numbers matching 4 spaces --- railties/test/application/rake/notes_test.rb | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 5a104e2ffe..95087bf29f 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -39,10 +39,7 @@ module ApplicationTests assert_match(/note in ruby/, output) assert_equal 9, lines.size - - lines.each do |line| - assert_equal 4, line.size - end + assert_equal [4], lines.map(&:size).uniq end end @@ -64,10 +61,7 @@ module ApplicationTests assert_no_match(/note in some_other directory/, output) assert_equal 5, lines.size - - lines.each do |line_number| - assert_equal 4, line_number.size - end + assert_equal [4], lines.map(&:size).uniq end end @@ -90,10 +84,7 @@ module ApplicationTests assert_match(/note in some_other directory/, output) assert_equal 6, lines.size - - lines.each do |line_number| - assert_equal 4, line_number.size - end + assert_equal [4], lines.map(&:size).uniq end end @@ -118,10 +109,7 @@ module ApplicationTests assert_no_match(/note in app directory/, output) assert_equal 2, lines.size - - lines.each do |line_number| - assert_equal 4, line_number.size - end + assert_equal [4], lines.map(&:size).uniq end end -- cgit v1.2.3 From c80ca4c7803b4e8ed7f125ada9acc6b7c499af5f Mon Sep 17 00:00:00 2001 From: Thiago Pinto Date: Wed, 19 Mar 2014 21:13:03 -0400 Subject: ActiveRecord#touch should accept multiple attributes #14423 --- activerecord/CHANGELOG.md | 12 ++++++++++++ activerecord/lib/active_record/persistence.rb | 5 +++-- activerecord/test/cases/timestamp_test.rb | 12 ++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index f5b8a3145d..b6748eb24d 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,15 @@ +* `ActiveRecord#touch` should accept many attributes at once. Suggested at #14423. + + Example: + + photo = Photo.last + photo.touch(:signed_at, :sealed_at) + photo.updated_at # was changed + photo.signed_at # was changed + photo.sealed_at # was changed + + *James Pinto* + * Reap connections that were checked out by now-dead threads, instead of waiting until they disconnect by themselves. Before this change, a suitably constructed series of short-lived threads could starve diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index d85fad1e13..eb45289b2e 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -412,6 +412,7 @@ module ActiveRecord # # product.touch # updates updated_at/on # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on + # product.touch(:started_at, :ended_at) # updates started_at, ended_at and updated_at/on attributes # # If used along with +belongs_to+ then +touch+ will invoke +touch+ method on associated object. # @@ -432,11 +433,11 @@ module ActiveRecord # ball = Ball.new # ball.touch(:updated_at) # => raises ActiveRecordError # - def touch(name = nil) + def touch(*names) raise ActiveRecordError, "cannot touch on a new record object" unless persisted? attributes = timestamp_attributes_for_update_in_model - attributes << name if name + attributes.concat(names) unless attributes.empty? current_time = current_time_from_proper_timezone diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb index 717e0e1866..5308fa8808 100644 --- a/activerecord/test/cases/timestamp_test.rb +++ b/activerecord/test/cases/timestamp_test.rb @@ -89,6 +89,18 @@ class TimestampTest < ActiveRecord::TestCase assert_in_delta Time.now, task.ending, 1 end + def test_touching_many_attributes_updates_them + task = Task.first + previous_starting = task.starting + previous_ending = task.ending + task.touch(:starting, :ending) + + assert_not_equal previous_starting, task.starting + assert_not_equal previous_ending, task.ending + assert_in_delta Time.now, task.starting, 1 + assert_in_delta Time.now, task.ending, 1 + end + def test_touching_a_record_without_timestamps_is_unexceptional assert_nothing_raised { Car.first.touch } end -- cgit v1.2.3 From 102c556e0b1d7e442075625163d57374e798982c Mon Sep 17 00:00:00 2001 From: Attila Domokos Date: Wed, 19 Mar 2014 21:01:08 -0500 Subject: Cleaning and adding tests for Session Adding tests for Session `destroy`, `update` and `delete` methods. No changes for code under test. --- actionpack/test/dispatch/request/session_test.rb | 41 ++++++++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/actionpack/test/dispatch/request/session_test.rb b/actionpack/test/dispatch/request/session_test.rb index df55fcc8bc..10fb04e230 100644 --- a/actionpack/test/dispatch/request/session_test.rb +++ b/actionpack/test/dispatch/request/session_test.rb @@ -36,29 +36,55 @@ module ActionDispatch assert_equal s, Session.find(env) end + def test_destroy + s = Session.create(store, {}, {}) + s['rails'] = 'ftw' + + s.destroy + + assert_empty s + end + def test_keys - env = {} - s = Session.create(store, env, {}) + s = Session.create(store, {}, {}) s['rails'] = 'ftw' s['adequate'] = 'awesome' assert_equal %w[rails adequate], s.keys end def test_values - env = {} - s = Session.create(store, env, {}) + s = Session.create(store, {}, {}) s['rails'] = 'ftw' s['adequate'] = 'awesome' assert_equal %w[ftw awesome], s.values end def test_clear - env = {} - s = Session.create(store, env, {}) + s = Session.create(store, {}, {}) s['rails'] = 'ftw' s['adequate'] = 'awesome' + s.clear - assert_equal([], s.values) + assert_empty(s.values) + end + + def test_update + s = Session.create(store, {}, {}) + s['rails'] = 'ftw' + + s.update(:rails => 'awesome') + + assert_equal(['rails'], s.keys) + assert_equal('awesome', s['rails']) + end + + def test_delete + s = Session.create(store, {}, {}) + s['rails'] = 'ftw' + + s.delete('rails') + + assert_empty(s.keys) end def test_fetch @@ -82,6 +108,7 @@ module ActionDispatch Class.new { def load_session(env); [1, {}]; end def session_exists?(env); true; end + def destroy_session(env, id, options); 123; end }.new end end -- cgit v1.2.3 From eafec4694c5b37eff9d83b1188b8e331fa6027fa Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Thu, 20 Mar 2014 10:30:30 +0100 Subject: only dump schema information if migration table exists. Closes #14217 --- activerecord/CHANGELOG.md | 7 +++++++ activerecord/lib/active_record/railties/databases.rake | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index f5b8a3145d..3aee68e3c9 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,10 @@ +* `rake db:structure:dump` only dumps schema information if the schema + migration table exists. + + Fixes #14217. + + *Yves Senn* + * Reap connections that were checked out by now-dead threads, instead of waiting until they disconnect by themselves. Before this change, a suitably constructed series of short-lived threads could starve diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 1d5c80bc01..ff1f0f5911 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -268,7 +268,8 @@ db_namespace = namespace :db do current_config = ActiveRecord::Tasks::DatabaseTasks.current_config ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename) - if ActiveRecord::Base.connection.supports_migrations? + if ActiveRecord::Base.connection.supports_migrations? && + ActiveRecord::SchemaMigration.table_exists? File.open(filename, "a") do |f| f.puts ActiveRecord::Base.connection.dump_schema_information f.print "\n" -- cgit v1.2.3 From bebe4a9ddde078c091e48ab06c4ca4c8da37203f Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 20 Mar 2014 08:08:22 -0300 Subject: Improve touch docs with extra attributes passed in [ci skip] --- activerecord/CHANGELOG.md | 9 +++------ activerecord/lib/active_record/persistence.rb | 12 +++++++----- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 28e81428c0..2334fef6ed 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,12 +1,9 @@ -* `ActiveRecord#touch` should accept many attributes at once. Suggested at #14423. +* `touch` accepts many attributes to be touched at once. Example: - photo = Photo.last - photo.touch(:signed_at, :sealed_at) - photo.updated_at # was changed - photo.signed_at # was changed - photo.sealed_at # was changed + # touches :signed_at, :sealed_at, and :updated_at/on attributes. + Photo.last.touch(:signed_at, :sealed_at) *James Pinto* diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index eb45289b2e..c20499d081 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -407,14 +407,16 @@ module ActiveRecord # Saves the record with the updated_at/on attributes set to the current time. # Please note that no validation is performed and only the +after_touch+, # +after_commit+ and +after_rollback+ callbacks are executed. - # If an attribute name is passed, that attribute is updated along with - # updated_at/on attributes. # - # product.touch # updates updated_at/on - # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on + # If attribute names are passed, they are updated along with updated_at/on + # attributes. + # + # product.touch # updates updated_at/on + # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on # product.touch(:started_at, :ended_at) # updates started_at, ended_at and updated_at/on attributes # - # If used along with +belongs_to+ then +touch+ will invoke +touch+ method on associated object. + # If used along with +belongs_to+ then +touch+ will invoke +touch+ method on + # associated object. # # class Brake < ActiveRecord::Base # belongs_to :car, touch: true -- cgit v1.2.3 From 66dc5762178dc2cf23349fd7de4bb3f97f9359ec Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 20 Mar 2014 08:19:33 -0300 Subject: Check if the output is empty rather than asserting for equality Also fix indent of test block. --- railties/test/application/rake/dbs_test.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb index 6bf49f3d67..7cc4ea0ce1 100644 --- a/railties/test/application/rake/dbs_test.rb +++ b/railties/test/application/rake/dbs_test.rb @@ -33,12 +33,11 @@ module ApplicationTests def db_create_and_drop Dir.chdir(app_path) do output = `bundle exec rake db:create` - assert_equal output, "" + assert_empty output assert File.exist?(expected[:database]) - assert_equal expected[:database], - ActiveRecord::Base.connection_config[:database] + assert_equal expected[:database], ActiveRecord::Base.connection_config[:database] output = `bundle exec rake db:drop` - assert_equal output, "" + assert_empty output assert !File.exist?(expected[:database]) end end @@ -47,7 +46,7 @@ module ApplicationTests require "#{app_path}/config/environment" expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database'] db_create_and_drop - end + end test 'db:create and db:drop with database url' do require "#{app_path}/config/environment" -- cgit v1.2.3 From 97229c69eaa6e4aec76e9ed1d14e8eba1c66d183 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 20 Mar 2014 08:27:22 -0300 Subject: Remove some indirection in rake dbs test Just pass in the expected database as argument rather than "caching" it in a hash and using the hash in the helper methods. --- railties/test/application/rake/dbs_test.rb | 54 +++++++++++------------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb index 7cc4ea0ce1..9a5c5ed223 100644 --- a/railties/test/application/rake/dbs_test.rb +++ b/railties/test/application/rake/dbs_test.rb @@ -26,56 +26,48 @@ module ApplicationTests FileUtils.rm_rf("#{app_path}/config/database.yml") end - def expected - @expected ||= {} - end - - def db_create_and_drop + def db_create_and_drop(expected_database) Dir.chdir(app_path) do output = `bundle exec rake db:create` assert_empty output - assert File.exist?(expected[:database]) - assert_equal expected[:database], ActiveRecord::Base.connection_config[:database] + assert File.exist?(expected_database) + assert_equal expected_database, ActiveRecord::Base.connection_config[:database] output = `bundle exec rake db:drop` assert_empty output - assert !File.exist?(expected[:database]) + assert !File.exist?(expected_database) end end test 'db:create and db:drop without database url' do require "#{app_path}/config/environment" - expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database'] - db_create_and_drop + db_create_and_drop ActiveRecord::Base.configurations[Rails.env]['database'] end test 'db:create and db:drop with database url' do require "#{app_path}/config/environment" set_database_url - expected[:database] = database_url_db_name - db_create_and_drop + db_create_and_drop database_url_db_name end - def db_migrate_and_status + def db_migrate_and_status(expected_database) Dir.chdir(app_path) do `rails generate model book title:string; bundle exec rake db:migrate` output = `bundle exec rake db:migrate:status` - assert_match(%r{database:\s+\S*#{Regexp.escape(expected[:database])}}, output) + assert_match(%r{database:\s+\S*#{Regexp.escape(expected_database)}}, output) assert_match(/up\s+\d{14}\s+Create books/, output) end end test 'db:migrate and db:migrate:status without database_url' do require "#{app_path}/config/environment" - expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database'] - db_migrate_and_status + db_migrate_and_status ActiveRecord::Base.configurations[Rails.env]['database'] end test 'db:migrate and db:migrate:status with database_url' do require "#{app_path}/config/environment" set_database_url - expected[:database] = database_url_db_name - db_migrate_and_status + db_migrate_and_status database_url_db_name end def db_schema_dump @@ -96,12 +88,11 @@ module ApplicationTests db_schema_dump end - def db_fixtures_load + def db_fixtures_load(expected_database) Dir.chdir(app_path) do `rails generate model book title:string; bundle exec rake db:migrate db:fixtures:load` - assert_match(/#{expected[:database]}/, - ActiveRecord::Base.connection_config[:database]) + assert_match expected_database, ActiveRecord::Base.connection_config[:database] require "#{app_path}/app/models/book" assert_equal 2, Book.count end @@ -109,26 +100,23 @@ module ApplicationTests test 'db:fixtures:load without database_url' do require "#{app_path}/config/environment" - expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database'] - db_fixtures_load + db_fixtures_load ActiveRecord::Base.configurations[Rails.env]['database'] end test 'db:fixtures:load with database_url' do require "#{app_path}/config/environment" set_database_url - expected[:database] = database_url_db_name - db_fixtures_load + db_fixtures_load database_url_db_name end - def db_structure_dump_and_load + def db_structure_dump_and_load(expected_database) Dir.chdir(app_path) do `rails generate model book title:string; bundle exec rake db:migrate db:structure:dump` structure_dump = File.read("db/structure.sql") assert_match(/CREATE TABLE \"books\"/, structure_dump) `bundle exec rake environment db:drop db:structure:load` - assert_match(/#{expected[:database]}/, - ActiveRecord::Base.connection_config[:database]) + assert_match expected_database, ActiveRecord::Base.connection_config[:database] require "#{app_path}/app/models/book" #if structure is not loaded correctly, exception would be raised assert_equal 0, Book.count @@ -137,15 +125,13 @@ module ApplicationTests test 'db:structure:dump and db:structure:load without database_url' do require "#{app_path}/config/environment" - expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database'] - db_structure_dump_and_load + db_structure_dump_and_load ActiveRecord::Base.configurations[Rails.env]['database'] end test 'db:structure:dump and db:structure:load with database_url' do require "#{app_path}/config/environment" set_database_url - expected[:database] = database_url_db_name - db_structure_dump_and_load + db_structure_dump_and_load database_url_db_name end def db_test_load_structure @@ -157,8 +143,8 @@ module ApplicationTests require "#{app_path}/app/models/book" #if structure is not loaded correctly, exception would be raised assert_equal 0, Book.count - assert_match(/#{ActiveRecord::Base.configurations['test']['database']}/, - ActiveRecord::Base.connection_config[:database]) + assert_match ActiveRecord::Base.configurations['test']['database'], + ActiveRecord::Base.connection_config[:database] end end -- cgit v1.2.3 From 0110d7b714a6ecc810a38ef5a27b66ec321995e5 Mon Sep 17 00:00:00 2001 From: Josh Williams Date: Tue, 19 Nov 2013 15:50:14 -0500 Subject: Postgres schema: Constrain sequence search classid The pk_an_sequence_for query previously joined against pg_class's oid for rows in pg_depend, but pg_depend's objid may point to other system tables, such as pg_attrdef. If a row in one of those other tables coincidentally has the same oid as an (unrelated) sequence, that sequence name may be returned instead of the real one. This ensures that only the pg_depend entries pointing to pg_class are considered. --- activerecord/CHANGELOG.md | 5 +++ .../postgresql/schema_statements.rb | 1 + .../adapters/postgresql/postgresql_adapter_test.rb | 45 ++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index f5b8a3145d..91a6f9e1ff 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -6,6 +6,11 @@ *Matthew Draper* +* `pk_and_sequence_for` now ensures that only the pg_depend entries + pointing to pg_class, and thus only sequence objects, are considered. + + *Josh Williams* + * `where.not` adds `references` for `includes` like normal `where` calls do. Fixes #14406. diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index ae8ede4b42..e0afa989cd 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -327,6 +327,7 @@ module ActiveRecord AND attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1] AND cons.contype = 'p' + AND dep.classid = 'pg_class'::regclass AND dep.refobjid = '#{quote_table_name(table)}'::regclass end_sql diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb index 019406dd84..de7acdf3ab 100644 --- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb +++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb @@ -176,6 +176,51 @@ module ActiveRecord assert_nil @connection.pk_and_sequence_for('unobtainium') end + def test_pk_and_sequence_for_with_collision_pg_class_oid + @connection.exec_query('create table ex(id serial primary key)') + @connection.exec_query('create table ex2(id serial primary key)') + + correct_depend_record = [ + "'pg_class'::regclass", + "'ex_id_seq'::regclass", + '0', + "'pg_class'::regclass", + "'ex'::regclass", + '1', + "'a'" + ] + + collision_depend_record = [ + "'pg_attrdef'::regclass", + "'ex2_id_seq'::regclass", + '0', + "'pg_class'::regclass", + "'ex'::regclass", + '1', + "'a'" + ] + + @connection.exec_query( + "DELETE FROM pg_depend WHERE objid = 'ex_id_seq'::regclass AND refobjid = 'ex'::regclass AND deptype = 'a'" + ) + @connection.exec_query( + "INSERT INTO pg_depend VALUES(#{collision_depend_record.join(',')})" + ) + @connection.exec_query( + "INSERT INTO pg_depend VALUES(#{correct_depend_record.join(',')})" + ) + + seq = @connection.pk_and_sequence_for('ex').last + assert_equal 'ex_id_seq', seq + + @connection.exec_query( + "DELETE FROM pg_depend WHERE objid = 'ex2_id_seq'::regclass AND refobjid = 'ex'::regclass AND deptype = 'a'" + ) + ensure + @connection.exec_query('DROP TABLE IF EXISTS ex') + @connection.exec_query('DROP TABLE IF EXISTS ex2') + end + def test_exec_insert_number with_example_table do insert(@connection, 'number' => 10) -- cgit v1.2.3 From 656f4f29fa497a13d13b39b12506e0505072b472 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 20 Mar 2014 08:40:31 -0300 Subject: Remove extra indirection for testing exceptions and messages assert_raise + assert_equal on the returned exception message work just fine, there is no need for extra work, specially like this overly complicated helper. --- activerecord/test/cases/nested_attributes_test.rb | 40 +++++++---------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 6bec760ea7..cf96c3fccf 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -11,23 +11,7 @@ require "models/owner" require "models/pet" require 'active_support/hash_with_indifferent_access' -module AssertRaiseWithMessage - def assert_raise_with_message(expected_exception, expected_message) - begin - error_raised = false - yield - rescue expected_exception => error - error_raised = true - actual_message = error.message - end - assert error_raised - assert_equal expected_message, actual_message - end -end - class TestNestedAttributesInGeneral < ActiveRecord::TestCase - include AssertRaiseWithMessage - teardown do Pirate.accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } end @@ -71,9 +55,10 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase end def test_should_raise_an_ArgumentError_for_non_existing_associations - assert_raise_with_message ArgumentError, "No association found for name `honesty'. Has it been defined yet?" do + exception = assert_raise ArgumentError do Pirate.accepts_nested_attributes_for :honesty end + assert_equal "No association found for name `honesty'. Has it been defined yet?", exception.message end def test_should_disable_allow_destroy_by_default @@ -213,17 +198,16 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase end class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase - include AssertRaiseWithMessage - def setup @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") @ship = @pirate.create_ship(:name => 'Nights Dirty Lightning') end def test_should_raise_argument_error_if_trying_to_build_polymorphic_belongs_to - assert_raise_with_message ArgumentError, "Cannot build association `looter'. Are you trying to build a polymorphic one-to-one association?" do + exception = assert_raise ArgumentError do Treasure.new(:name => 'pearl', :looter_attributes => {:catchphrase => "Arrr"}) end + assert_equal "Cannot build association `looter'. Are you trying to build a polymorphic one-to-one association?", exception.message end def test_should_define_an_attribute_writer_method_for_the_association @@ -275,9 +259,10 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase end def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record - assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Ship with ID=1234567890 for Pirate with ID=#{@pirate.id}" do + exception = assert_raise ActiveRecord::RecordNotFound do @pirate.ship_attributes = { :id => 1234567890 } end + assert_equal "Couldn't find Ship with ID=1234567890 for Pirate with ID=#{@pirate.id}", exception.message end def test_should_take_a_hash_with_string_keys_and_update_the_associated_model @@ -403,8 +388,6 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase end class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase - include AssertRaiseWithMessage - def setup @ship = Ship.new(:name => 'Nights Dirty Lightning') @pirate = @ship.build_pirate(:catchphrase => 'Aye') @@ -460,9 +443,10 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase end def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record - assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Pirate with ID=1234567890 for Ship with ID=#{@ship.id}" do + exception = assert_raise ActiveRecord::RecordNotFound do @ship.pirate_attributes = { :id => 1234567890 } end + assert_equal "Couldn't find Pirate with ID=1234567890 for Ship with ID=#{@ship.id}", exception.message end def test_should_take_a_hash_with_string_keys_and_update_the_associated_model @@ -579,8 +563,6 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase end module NestedAttributesOnACollectionAssociationTests - include AssertRaiseWithMessage - def test_should_define_an_attribute_writer_method_for_the_association assert_respond_to @pirate, association_setter end @@ -670,9 +652,10 @@ module NestedAttributesOnACollectionAssociationTests end def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record - assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find #{@child_1.class.name} with ID=1234567890 for Pirate with ID=#{@pirate.id}" do + exception = assert_raise ActiveRecord::RecordNotFound do @pirate.attributes = { association_getter => [{ :id => 1234567890 }] } end + assert_equal "Couldn't find #{@child_1.class.name} with ID=1234567890 for Pirate with ID=#{@pirate.id}", exception.message end def test_should_automatically_build_new_associated_models_for_each_entry_in_a_hash_where_the_id_is_missing @@ -727,9 +710,10 @@ module NestedAttributesOnACollectionAssociationTests assert_nothing_raised(ArgumentError) { @pirate.send(association_setter, {}) } assert_nothing_raised(ArgumentError) { @pirate.send(association_setter, Hash.new) } - assert_raise_with_message ArgumentError, 'Hash or Array expected, got String ("foo")' do + exception = assert_raise ArgumentError do @pirate.send(association_setter, "foo") end + assert_equal 'Hash or Array expected, got String ("foo")', exception.message end def test_should_work_with_update_as_well -- cgit v1.2.3 From 3980d403ce230e589a06ac9f8af01a3e0113cc04 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Thu, 20 Mar 2014 05:36:31 -0700 Subject: The digest option is no longer honoured since Rails 3.0 [ci skip] Closes #8513 --- actionpack/lib/action_dispatch/middleware/session/cookie_store.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index 1ebc189c28..3be0ce1860 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -51,7 +51,7 @@ module ActionDispatch # decode signed cookies generated by your app in external applications or # Javascript before upgrading. # - # Note that changing digest or secret invalidates all existing sessions! + # Note that changing the secret key will invalidate all existing sessions! class CookieStore < Rack::Session::Abstract::ID include Compatibility include StaleSessionCheck -- cgit v1.2.3 From 41548df342197ac5bf2556f3fa508be6e090ca70 Mon Sep 17 00:00:00 2001 From: Akshay Vishnoi Date: Thu, 20 Mar 2014 18:29:09 +0530 Subject: Deprecate Class#superclass_delegating_accessor --- activesupport/CHANGELOG.md | 4 +++ .../core_ext/class/delegating_attributes.rb | 4 +++ .../core_ext/class/delegating_attributes_test.rb | 34 ++++++++++++++++++---- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 4eccea2848..7feb820d4f 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,7 @@ +* Deprecate `Class#superclass_delegating_accessor`, use `Class#class_attribute` instead. + + *Akshay Vishnoi* + * Ensure classes which `include Enumerable` get `#to_json` in addition to `#as_json`. diff --git a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb index c2219beb5a..1c305c5970 100644 --- a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb +++ b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb @@ -1,5 +1,7 @@ require 'active_support/core_ext/kernel/singleton_class' require 'active_support/core_ext/module/remove_method' +require 'active_support/core_ext/module/deprecation' + class Class def superclass_delegating_accessor(name, options = {}) @@ -21,6 +23,8 @@ class Class end end + deprecate superclass_delegating_accessor: :class_attribute + private # Take the object being set and store it in a method. This gives us automatic # inheritance behavior, without having to store the object in an instance diff --git a/activesupport/test/core_ext/class/delegating_attributes_test.rb b/activesupport/test/core_ext/class/delegating_attributes_test.rb index 0e0742d147..86193c2b07 100644 --- a/activesupport/test/core_ext/class/delegating_attributes_test.rb +++ b/activesupport/test/core_ext/class/delegating_attributes_test.rb @@ -6,14 +6,18 @@ module DelegatingFixtures end class Child < Parent - superclass_delegating_accessor :some_attribute + ActiveSupport::Deprecation.silence do + superclass_delegating_accessor :some_attribute + end end class Mokopuna < Child end class PercysMom - superclass_delegating_accessor :superpower + ActiveSupport::Deprecation.silence do + superclass_delegating_accessor :superpower + end end class Percy < PercysMom @@ -29,7 +33,10 @@ class DelegatingAttributesTest < ActiveSupport::TestCase end def test_simple_accessor_declaration - single_class.superclass_delegating_accessor :both + ActiveSupport::Deprecation.silence do + single_class.superclass_delegating_accessor :both + end + # Class should have accessor and mutator # the instance should have an accessor only assert_respond_to single_class, :both @@ -40,7 +47,11 @@ class DelegatingAttributesTest < ActiveSupport::TestCase def test_simple_accessor_declaration_with_instance_reader_false _instance_methods = single_class.public_instance_methods - single_class.superclass_delegating_accessor :no_instance_reader, :instance_reader => false + + ActiveSupport::Deprecation.silence do + single_class.superclass_delegating_accessor :no_instance_reader, :instance_reader => false + end + assert_respond_to single_class, :no_instance_reader assert_respond_to single_class, :no_instance_reader= assert !_instance_methods.include?(:no_instance_reader) @@ -49,7 +60,9 @@ class DelegatingAttributesTest < ActiveSupport::TestCase end def test_working_with_simple_attributes - single_class.superclass_delegating_accessor :both + ActiveSupport::Deprecation.silence do + single_class.superclass_delegating_accessor :both + end single_class.both = "HMMM" @@ -65,7 +78,11 @@ class DelegatingAttributesTest < ActiveSupport::TestCase def test_child_class_delegates_to_parent_but_can_be_overridden parent = Class.new - parent.superclass_delegating_accessor :both + + ActiveSupport::Deprecation.silence do + parent.superclass_delegating_accessor :both + end + child = Class.new(parent) parent.both = "1" assert_equal "1", child.both @@ -97,4 +114,9 @@ class DelegatingAttributesTest < ActiveSupport::TestCase Child.some_attribute=nil end + def test_deprecation_warning + assert_deprecated(/superclass_delegating_accessor is deprecated/) do + single_class.superclass_delegating_accessor :test_attribute + end + end end -- cgit v1.2.3 From 886fcb0f7700f9cf8bb6c17f5f2f081d68f9c1a6 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Thu, 20 Mar 2014 21:01:00 +0530 Subject: Warning removed (...) interpreted as grouped expression --- actionview/lib/action_view/digestor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 40d493da64..e55b9108f0 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -42,7 +42,7 @@ module ActionView ':variant. Please update your code to pass a Hash argument. ' \ 'Support for the old method signature will be removed in Rails 5.0.' - _options_for_digest (deprecated_args[2] || {}).merge \ + _options_for_digest(deprecated_args[2] || {}).merge \ name: options_or_deprecated_name, format: deprecated_args[0], finder: deprecated_args[1] -- cgit v1.2.3 From 582cbff616a927df097353ea8f96c3c1b88f4847 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Thu, 20 Mar 2014 18:40:51 +0100 Subject: test for structure:dump without schema information table. refs eafec46 This is a test case for the fix provided in eafec4694c5b37eff9d83b1188b8e331fa6027fa --- railties/test/application/rake/dbs_test.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb index 9a5c5ed223..b2c52a092f 100644 --- a/railties/test/application/rake/dbs_test.rb +++ b/railties/test/application/rake/dbs_test.rb @@ -134,6 +134,18 @@ module ApplicationTests db_structure_dump_and_load database_url_db_name end + test 'db:structure:dump does not dump schema information when no migrations are used' do + Dir.chdir(app_path) do + # create table without migrations + `bundle exec rails runner 'ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }'` + + stderr_output = capture(:stderr) { `bundle exec rake db:structure:dump` } + assert_empty stderr_output + structure_dump = File.read("db/structure.sql") + assert_match(/CREATE TABLE \"posts\"/, structure_dump) + end + end + def db_test_load_structure Dir.chdir(app_path) do `rails generate model book title:string; -- cgit v1.2.3 From 79405a07a45dfaeb6c39d794b42b72ee73e420e9 Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Tue, 18 Mar 2014 19:06:44 -0700 Subject: Extract with_example_table into helper method. This setups the helper method which other tests can benefit from. --- .../test/cases/adapters/postgresql/postgresql_adapter_test.rb | 11 +++++------ activerecord/test/support/ddl_helper.rb | 8 ++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 activerecord/test/support/ddl_helper.rb diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb index de7acdf3ab..49d8ec238d 100644 --- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb +++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb @@ -1,9 +1,12 @@ # encoding: utf-8 require "cases/helper" +require 'support/ddl_helper' module ActiveRecord module ConnectionAdapters class PostgreSQLAdapterTest < ActiveRecord::TestCase + include DdlHelper + def setup @connection = ActiveRecord::Base.connection end @@ -369,12 +372,8 @@ module ActiveRecord ctx.exec_insert(sql, 'SQL', binds) end - def with_example_table(definition = nil) - definition ||= 'id serial primary key, number integer, data character varying(255)' - @connection.exec_query("create table ex(#{definition})") - yield - ensure - @connection.exec_query('drop table if exists ex') + def with_example_table(definition = 'id serial primary key, number integer, data character varying(255)', &block) + super(@connection, 'ex', definition, &block) end def connection_without_insert_returning diff --git a/activerecord/test/support/ddl_helper.rb b/activerecord/test/support/ddl_helper.rb new file mode 100644 index 0000000000..0107babaaf --- /dev/null +++ b/activerecord/test/support/ddl_helper.rb @@ -0,0 +1,8 @@ +module DdlHelper + def with_example_table(connection, table_name, definition = nil) + connection.exec_query("CREATE TABLE #{table_name}(#{definition})") + yield + ensure + connection.exec_query("DROP TABLE #{table_name}") + end +end -- cgit v1.2.3 From 3bbc96048d8de004ae5991f0d0399e4f8e4ce7fb Mon Sep 17 00:00:00 2001 From: Iain D Broadfoot Date: Fri, 21 Mar 2014 14:59:42 +0000 Subject: fix log_tags request object grammar --- guides/source/configuring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 2cece90294..460fd3c301 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -110,7 +110,7 @@ numbers. New applications filter out passwords by adding the following `config.f * `config.log_level` defines the verbosity of the Rails logger. This option defaults to `:debug` for all modes except production, where it defaults to `:info`. -* `config.log_tags` accepts a list of methods that respond to `request` object. This makes it easy to tag log lines with debug information like subdomain and request id - both very helpful in debugging multi-user production applications. +* `config.log_tags` accepts a list of methods that the `request` object responds to. This makes it easy to tag log lines with debug information like subdomain and request id - both very helpful in debugging multi-user production applications. * `config.logger` accepts a logger conforming to the interface of Log4r or the default Ruby `Logger` class. Defaults to an instance of `ActiveSupport::Logger`, with auto flushing off in production mode. -- cgit v1.2.3 From 06b4f01fca1a31f174e24852e0bc2728e136e0b6 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 19 Mar 2014 19:23:29 +0100 Subject: Fix for digestor to consider variants for partials -- this still needs more testing!! --- actionview/lib/action_view/digestor.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index e55b9108f0..af7cfcfb6b 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -100,7 +100,7 @@ module ActionView def nested_dependencies dependencies.collect do |dependency| - dependencies = PartialDigestor.new(name: dependency, format: format, finder: finder).nested_dependencies + dependencies = PartialDigestor.new(name: dependency, format: format, variant: variant, finder: finder).nested_dependencies dependencies.any? ? { dependency => dependencies } : dependency end end @@ -133,7 +133,7 @@ module ActionView def dependency_digest template_digests = dependencies.collect do |template_name| - Digestor.digest(name: template_name, format: format, finder: finder, partial: true) + Digestor.digest(name: template_name, format: format, variant: variant, finder: finder, partial: true) end (template_digests + injected_dependencies).join("-") -- cgit v1.2.3 From 4bca34750d718a6f7a9bacbe181460b4505c4ba7 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 19 Mar 2014 20:51:13 +0100 Subject: Log the full path, including variant, that the digestor is trying to find --- actionview/lib/action_view/digestor.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index af7cfcfb6b..5dbd86df29 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -75,20 +75,21 @@ module ActionView end end - attr_reader :name, :format, :variant, :finder, :options + attr_reader :name, :format, :variant, :path, :finder, :options def initialize(options_or_deprecated_name, *deprecated_args) options = self.class._options_for_digest(options_or_deprecated_name, *deprecated_args) @options = options.except(:name, :format, :variant, :finder) @name, @format, @variant, @finder = options.values_at(:name, :format, :variant, :finder) + @path = "#{@name}.#{format}".tap { |path| path << "+#{@variant}" if @variant } end def digest Digest::MD5.hexdigest("#{source}-#{dependency_digest}").tap do |digest| - logger.try :info, "Cache digest for #{name}.#{format}: #{digest}" + logger.try :info, "Cache digest for #{path}: #{digest}" end rescue ActionView::MissingTemplate - logger.try :error, "Couldn't find template for digesting: #{name}.#{format}" + logger.try :error, "Couldn't find template for digesting: #{path}" '' end -- cgit v1.2.3 From 637bb726cac60aaa1f7e482836458aa73e17fbb7 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 21 Mar 2014 16:29:00 +0100 Subject: Digestor should just rely on the finder to know about the format and the variant -- trying to pass it back in makes a mess of things (oh, and doesnt work) --- actionview/lib/action_view/digestor.rb | 89 +++++++--------------- actionview/lib/action_view/helpers/cache_helper.rb | 16 +--- actionview/test/template/digestor_test.rb | 17 ++--- 3 files changed, 39 insertions(+), 83 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 5dbd86df29..72d79735ae 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -12,17 +12,13 @@ module ActionView # Supported options: # # * name - Template name - # * format - Template format - # * variant - Variant of +format+ (optional) # * finder - An instance of ActionView::LookupContext # * dependencies - An array of dependent views # * partial - Specifies whether the template is a partial - def digest(options_or_deprecated_name, *deprecated_args) - options = _options_for_digest(options_or_deprecated_name, *deprecated_args) + def digest(options) + options.assert_valid_keys(:name, :finder, :dependencies, :partial) - details_key = options[:finder].details_key.hash - dependencies = Array.wrap(options[:dependencies]) - cache_key = ([options[:name], details_key, options[:format], options[:variant]].compact + dependencies).join('.') + cache_key = ([ options[:name], options[:finder].details_key.hash ].compact + Array.wrap(options[:dependencies])).join('.') # this is a correctly done double-checked locking idiom # (ThreadSafe::Cache's lookups have volatile semantics) @@ -33,63 +29,41 @@ module ActionView end end - def _options_for_digest(options_or_deprecated_name, *deprecated_args) - if !options_or_deprecated_name.is_a?(Hash) - ActiveSupport::Deprecation.warn \ - 'ActionView::Digestor.digest changed its method signature from ' \ - '#digest(name, format, finder, options) to #digest(options), ' \ - 'with options now including :name, :format, :finder, and ' \ - ':variant. Please update your code to pass a Hash argument. ' \ - 'Support for the old method signature will be removed in Rails 5.0.' - - _options_for_digest(deprecated_args[2] || {}).merge \ - name: options_or_deprecated_name, - format: deprecated_args[0], - finder: deprecated_args[1] - else - options_or_deprecated_name.assert_valid_keys(:name, :format, :variant, :finder, :dependencies, :partial) - options_or_deprecated_name - end - end - private + def compute_and_store_digest(cache_key, options) # called under @@digest_monitor lock + klass = if options[:partial] || options[:name].include?("/_") + # Prevent re-entry or else recursive templates will blow the stack. + # There is no need to worry about other threads seeing the +false+ value, + # as they will then have to wait for this thread to let go of the @@digest_monitor lock. + pre_stored = @@cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion + PartialDigestor + else + Digestor + end - def compute_and_store_digest(cache_key, options) # called under @@digest_monitor lock - klass = if options[:partial] || options[:name].include?("/_") - # Prevent re-entry or else recursive templates will blow the stack. - # There is no need to worry about other threads seeing the +false+ value, - # as they will then have to wait for this thread to let go of the @@digest_monitor lock. - pre_stored = @@cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion - PartialDigestor - else - Digestor + digest = klass.new(options).digest + # Store the actual digest if config.cache_template_loading is true + @@cache[cache_key] = stored_digest = digest if ActionView::Resolver.caching? + digest + ensure + # something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache + @@cache.delete_pair(cache_key, false) if pre_stored && !stored_digest end - - digest = klass.new(options).digest - # Store the actual digest if config.cache_template_loading is true - @@cache[cache_key] = stored_digest = digest if ActionView::Resolver.caching? - digest - ensure - # something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache - @@cache.delete_pair(cache_key, false) if pre_stored && !stored_digest - end end - attr_reader :name, :format, :variant, :path, :finder, :options + attr_reader :name, :finder, :options - def initialize(options_or_deprecated_name, *deprecated_args) - options = self.class._options_for_digest(options_or_deprecated_name, *deprecated_args) - @options = options.except(:name, :format, :variant, :finder) - @name, @format, @variant, @finder = options.values_at(:name, :format, :variant, :finder) - @path = "#{@name}.#{format}".tap { |path| path << "+#{@variant}" if @variant } + def initialize(options) + @name, @finder = options.values_at(:name, :finder) + @options = options.except(:name, :finder) end def digest Digest::MD5.hexdigest("#{source}-#{dependency_digest}").tap do |digest| - logger.try :info, "Cache digest for #{path}: #{digest}" + logger.try :info, " Cache digest for #{template.inspect}: #{digest}" end rescue ActionView::MissingTemplate - logger.try :error, "Couldn't find template for digesting: #{path}" + logger.try :error, " Couldn't find template for digesting: #{name}" '' end @@ -101,13 +75,12 @@ module ActionView def nested_dependencies dependencies.collect do |dependency| - dependencies = PartialDigestor.new(name: dependency, format: format, variant: variant, finder: finder).nested_dependencies + dependencies = PartialDigestor.new(name: dependency, finder: finder).nested_dependencies dependencies.any? ? { dependency => dependencies } : dependency end end private - def logger ActionView::Base.logger end @@ -121,11 +94,7 @@ module ActionView end def template - @template ||= begin - finder.disable_cache do - finder.find(logical_name, [], partial?, [], formats: [format], variants: [variant]) - end - end + @template ||= finder.disable_cache { finder.find(logical_name, [], partial?) } end def source @@ -134,7 +103,7 @@ module ActionView def dependency_digest template_digests = dependencies.collect do |template_name| - Digestor.digest(name: template_name, format: format, variant: variant, finder: finder, partial: true) + Digestor.digest(name: template_name, finder: finder, partial: true) end (template_digests + injected_dependencies).join("-") diff --git a/actionview/lib/action_view/helpers/cache_helper.rb b/actionview/lib/action_view/helpers/cache_helper.rb index 3177d18c4d..d1c268ec40 100644 --- a/actionview/lib/action_view/helpers/cache_helper.rb +++ b/actionview/lib/action_view/helpers/cache_helper.rb @@ -165,20 +165,10 @@ module ActionView def fragment_name_with_digest(name) #:nodoc: if @virtual_path - variant = request.variant.is_a?(Array) ? request.variant.first : request.variant + names = Array(name.is_a?(Hash) ? controller.url_for(name).split("://").last : name) + digest = Digestor.digest name: @virtual_path, finder: lookup_context, dependencies: view_cache_dependencies - options = { - name: @virtual_path, - format: formats.last.to_sym, - variant: variant, - finder: lookup_context, - dependencies: view_cache_dependencies - } - - names = Array(name.is_a?(Hash) ? controller.url_for(name).split("://").last : name) - digest = Digestor.digest(options) - - [*names, digest] + [ *names, digest ] else name end diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index 0cbfd14c94..47e1f6a6e5 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -100,13 +100,13 @@ class TemplateDigestorTest < ActionView::TestCase end def test_logging_of_missing_template - assert_logged "Couldn't find template for digesting: messages/something_missing.html" do + assert_logged "Couldn't find template for digesting: messages/something_missing" do digest("messages/show") end end def test_logging_of_missing_template_ending_with_number - assert_logged "Couldn't find template for digesting: messages/something_missing_1.html" do + assert_logged "Couldn't find template for digesting: messages/something_missing_1" do digest("messages/show") end end @@ -207,7 +207,7 @@ class TemplateDigestorTest < ActionView::TestCase end def test_variants - assert_digest_difference("messages/new", false, variant: :iphone) do + assert_digest_difference("messages/new", false, variants: [:iphone]) do change_template("messages/new", :iphone) change_template("messages/_header", :iphone) end @@ -261,10 +261,6 @@ class TemplateDigestorTest < ActionView::TestCase ActionView::Resolver.caching = resolver_before end - def test_arguments_deprecation - assert_deprecated(/will be removed/) { ActionView::Digestor.digest('messages/show', :html, finder) } - assert_deprecated(/will be removed/) { ActionView::Digestor.new('messages/show', :html, finder) } - end private def assert_logged(message) @@ -294,10 +290,11 @@ class TemplateDigestorTest < ActionView::TestCase def digest(template_name, options = {}) options = options.dup - finder.formats = [:html] - finder.variants = [options[:variant]] if options[:variant].present? - ActionView::Digestor.digest({ name: template_name, format: :html, finder: finder }.merge(options)) + finder.formats = [:html] + finder.variants = options.delete(:variants) || [] + + ActionView::Digestor.digest({ name: template_name, finder: finder }.merge(options)) end def finder -- cgit v1.2.3 From 9d44b3f886847eee9c70097165863f8e37d3d1d8 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 21 Mar 2014 17:37:23 +0100 Subject: Update test helper to use latest Digestor API --- actionpack/test/controller/caching_test.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 9923b90bae..58a86ce9af 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -197,7 +197,7 @@ CACHED assert_equal expected_body, @response.body assert_equal "This bit's fragment cached", - @store.read("views/test.host/functional_caching/fragment_cached/#{template_digest("functional_caching/fragment_cached", "html")}") + @store.read("views/test.host/functional_caching/fragment_cached/#{template_digest("functional_caching/fragment_cached")}") end def test_fragment_caching_in_partials @@ -206,7 +206,7 @@ CACHED assert_match(/Old fragment caching in a partial/, @response.body) assert_match("Old fragment caching in a partial", - @store.read("views/test.host/functional_caching/html_fragment_cached_with_partial/#{template_digest("functional_caching/_partial", "html")}")) + @store.read("views/test.host/functional_caching/html_fragment_cached_with_partial/#{template_digest("functional_caching/_partial")}")) end def test_skipping_fragment_cache_digesting @@ -224,7 +224,7 @@ CACHED assert_match(/Some inline content/, @response.body) assert_match(/Some cached content/, @response.body) assert_match("Some cached content", - @store.read("views/test.host/functional_caching/inline_fragment_cached/#{template_digest("functional_caching/inline_fragment_cached", "html")}")) + @store.read("views/test.host/functional_caching/inline_fragment_cached/#{template_digest("functional_caching/inline_fragment_cached")}")) end def test_html_formatted_fragment_caching @@ -235,7 +235,7 @@ CACHED assert_equal expected_body, @response.body assert_equal "

ERB

", - @store.read("views/test.host/functional_caching/formatted_fragment_cached/#{template_digest("functional_caching/formatted_fragment_cached", "html")}") + @store.read("views/test.host/functional_caching/formatted_fragment_cached/#{template_digest("functional_caching/formatted_fragment_cached")}") end def test_xml_formatted_fragment_caching @@ -246,7 +246,7 @@ CACHED assert_equal expected_body, @response.body assert_equal "

Builder

\n", - @store.read("views/test.host/functional_caching/formatted_fragment_cached/#{template_digest("functional_caching/formatted_fragment_cached", "xml")}") + @store.read("views/test.host/functional_caching/formatted_fragment_cached/#{template_digest("functional_caching/formatted_fragment_cached")}") end @@ -260,12 +260,12 @@ CACHED assert_equal expected_body, @response.body assert_equal "

PHONE

", - @store.read("views/test.host/functional_caching/formatted_fragment_cached_with_variant/#{template_digest("functional_caching/formatted_fragment_cached_with_variant", :html, :phone)}") + @store.read("views/test.host/functional_caching/formatted_fragment_cached_with_variant/#{template_digest("functional_caching/formatted_fragment_cached_with_variant")}") end private - def template_digest(name, format, variant = nil) - ActionView::Digestor.digest(name: name, format: format, variant: variant, finder: @controller.lookup_context) + def template_digest(name) + ActionView::Digestor.digest(name: name, finder: @controller.lookup_context) end end -- cgit v1.2.3 From 0ebae1dbc59c34f6b5ae87bf96b8848051a0254c Mon Sep 17 00:00:00 2001 From: Vishal Lal Date: Sat, 22 Mar 2014 22:50:55 +0000 Subject: Swapped parameters of assert_equal in assert_select --- actionpack/CHANGELOG.md | 7 +++++++ actionpack/lib/action_dispatch/testing/assertions/selector.rb | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 59460cbe82..fe5b38d29f 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,10 @@ +* Swapped the parameters of assert_equal in `assert_select` so that the + proper values were printed correctly + + Fixes #14422. + + *Vishal Lal* + * The method `shallow?` returns false if the parent resource is a singleton so we need to check if we're not inside a nested scope before copying the :path and :as options to their shallow equivalents. diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb index 3253a3d424..8a128427bf 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb @@ -291,7 +291,7 @@ module ActionDispatch # so is this custom message really needed? message = message || %(Expected #{count_description(min, max, count)} matching "#{selector.to_s}", found #{matches.size}.) if count - assert_equal matches.size, count, message + assert_equal count, matches.size, message else assert_operator matches.size, :>=, min, message if min assert_operator matches.size, :<=, max, message if max -- cgit v1.2.3 From 1db36c411ae91e9df7f899664f25019c5110d5eb Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Thu, 20 Mar 2014 14:41:09 -0700 Subject: Clean up tables after each test. Follow-Up to https://github.com/rails/rails/pull/14400 This ensures that all tables are removed after each test and thereby allowing us to run the tests in a random order. --- .../test/cases/adapters/mysql/connection_test.rb | 80 +++++++-------- .../cases/adapters/mysql/mysql_adapter_test.rb | 108 +++++++++++---------- 2 files changed, 96 insertions(+), 92 deletions(-) diff --git a/activerecord/test/cases/adapters/mysql/connection_test.rb b/activerecord/test/cases/adapters/mysql/connection_test.rb index 5cd5d8ac5f..42ffb91095 100644 --- a/activerecord/test/cases/adapters/mysql/connection_test.rb +++ b/activerecord/test/cases/adapters/mysql/connection_test.rb @@ -1,6 +1,9 @@ require "cases/helper" +require 'support/ddl_helper' class MysqlConnectionTest < ActiveRecord::TestCase + include DdlHelper + class Klass < ActiveRecord::Base end @@ -69,59 +72,50 @@ class MysqlConnectionTest < ActiveRecord::TestCase end def test_exec_no_binds - @connection.exec_query('drop table if exists ex') - @connection.exec_query(<<-eosql) - CREATE TABLE `ex` (`id` int(11) auto_increment PRIMARY KEY, - `data` varchar(255)) - eosql - result = @connection.exec_query('SELECT id, data FROM ex') - assert_equal 0, result.rows.length - assert_equal 2, result.columns.length - assert_equal %w{ id data }, result.columns + with_example_table do + result = @connection.exec_query('SELECT id, data FROM ex') + assert_equal 0, result.rows.length + assert_equal 2, result.columns.length + assert_equal %w{ id data }, result.columns - @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")') + @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")') - # if there are no bind parameters, it will return a string (due to - # the libmysql api) - result = @connection.exec_query('SELECT id, data FROM ex') - assert_equal 1, result.rows.length - assert_equal 2, result.columns.length + # if there are no bind parameters, it will return a string (due to + # the libmysql api) + result = @connection.exec_query('SELECT id, data FROM ex') + assert_equal 1, result.rows.length + assert_equal 2, result.columns.length - assert_equal [['1', 'foo']], result.rows + assert_equal [['1', 'foo']], result.rows + end end def test_exec_with_binds - @connection.exec_query('drop table if exists ex') - @connection.exec_query(<<-eosql) - CREATE TABLE `ex` (`id` int(11) auto_increment PRIMARY KEY, - `data` varchar(255)) - eosql - @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")') - result = @connection.exec_query( - 'SELECT id, data FROM ex WHERE id = ?', nil, [[nil, 1]]) + with_example_table do + @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")') + result = @connection.exec_query( + 'SELECT id, data FROM ex WHERE id = ?', nil, [[nil, 1]]) - assert_equal 1, result.rows.length - assert_equal 2, result.columns.length + assert_equal 1, result.rows.length + assert_equal 2, result.columns.length - assert_equal [[1, 'foo']], result.rows + assert_equal [[1, 'foo']], result.rows + end end def test_exec_typecasts_bind_vals - @connection.exec_query('drop table if exists ex') - @connection.exec_query(<<-eosql) - CREATE TABLE `ex` (`id` int(11) auto_increment PRIMARY KEY, - `data` varchar(255)) - eosql - @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")') - column = @connection.columns('ex').find { |col| col.name == 'id' } + with_example_table do + @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")') + column = @connection.columns('ex').find { |col| col.name == 'id' } - result = @connection.exec_query( - 'SELECT id, data FROM ex WHERE id = ?', nil, [[column, '1-fuu']]) + result = @connection.exec_query( + 'SELECT id, data FROM ex WHERE id = ?', nil, [[column, '1-fuu']]) - assert_equal 1, result.rows.length - assert_equal 2, result.columns.length + assert_equal 1, result.rows.length + assert_equal 2, result.columns.length - assert_equal [[1, 'foo']], result.rows + assert_equal [[1, 'foo']], result.rows + end end # Test that MySQL allows multiple results for stored procedures @@ -174,4 +168,12 @@ class MysqlConnectionTest < ActiveRecord::TestCase ActiveRecord::Base.establish_connection(original_connection) end end + + def with_example_table(&block) + definition ||= <<-SQL + `id` int(11) auto_increment PRIMARY KEY, + `data` varchar(255) + SQL + super(@connection, 'ex', definition, &block) + end end diff --git a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb index 578f6301bd..1699380eb3 100644 --- a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb +++ b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb @@ -1,19 +1,15 @@ # encoding: utf-8 require "cases/helper" +require 'support/ddl_helper' module ActiveRecord module ConnectionAdapters class MysqlAdapterTest < ActiveRecord::TestCase + include DdlHelper + def setup @conn = ActiveRecord::Base.connection - @conn.exec_query('drop table if exists ex') - @conn.exec_query(<<-eosql) - CREATE TABLE `ex` ( - `id` int(11) auto_increment PRIMARY KEY, - `number` integer, - `data` varchar(255)) - eosql end def test_bad_connection_mysql @@ -25,8 +21,10 @@ module ActiveRecord end def test_valid_column - column = @conn.columns('ex').find { |col| col.name == 'id' } - assert @conn.valid_type?(column.type) + with_example_table do + column = @conn.columns('ex').find { |col| col.name == 'id' } + assert @conn.valid_type?(column.type) + end end def test_invalid_column @@ -38,31 +36,35 @@ module ActiveRecord end def test_exec_insert_number - insert(@conn, 'number' => 10) + with_example_table do + insert(@conn, 'number' => 10) - result = @conn.exec_query('SELECT number FROM ex WHERE number = 10') + result = @conn.exec_query('SELECT number FROM ex WHERE number = 10') - assert_equal 1, result.rows.length - # if there are no bind parameters, it will return a string (due to - # the libmysql api) - assert_equal '10', result.rows.last.last + assert_equal 1, result.rows.length + # if there are no bind parameters, it will return a string (due to + # the libmysql api) + assert_equal '10', result.rows.last.last + end end def test_exec_insert_string - str = 'いただきます!' - insert(@conn, 'number' => 10, 'data' => str) + with_example_table do + str = 'いただきます!' + insert(@conn, 'number' => 10, 'data' => str) - result = @conn.exec_query('SELECT number, data FROM ex WHERE number = 10') + result = @conn.exec_query('SELECT number, data FROM ex WHERE number = 10') - value = result.rows.last.last + value = result.rows.last.last - # FIXME: this should probably be inside the mysql AR adapter? - value.force_encoding(@conn.client_encoding) + # FIXME: this should probably be inside the mysql AR adapter? + value.force_encoding(@conn.client_encoding) - # The strings in this file are utf-8, so transcode to utf-8 - value.encode!(Encoding::UTF_8) + # The strings in this file are utf-8, so transcode to utf-8 + value.encode!(Encoding::UTF_8) - assert_equal str, value + assert_equal str, value + end end def test_tables_quoting @@ -74,46 +76,37 @@ module ActiveRecord end def test_pk_and_sequence_for - pk, seq = @conn.pk_and_sequence_for('ex') - assert_equal 'id', pk - assert_equal @conn.default_sequence_name('ex', 'id'), seq + with_example_table do + pk, seq = @conn.pk_and_sequence_for('ex') + assert_equal 'id', pk + assert_equal @conn.default_sequence_name('ex', 'id'), seq + end end def test_pk_and_sequence_for_with_non_standard_primary_key - @conn.exec_query('drop table if exists ex_with_non_standard_pk') - @conn.exec_query(<<-eosql) - CREATE TABLE `ex_with_non_standard_pk` ( - `code` INT(11) auto_increment, - PRIMARY KEY (`code`)) - eosql - pk, seq = @conn.pk_and_sequence_for('ex_with_non_standard_pk') - assert_equal 'code', pk - assert_equal @conn.default_sequence_name('ex_with_non_standard_pk', 'code'), seq + with_example_table '`code` INT(11) auto_increment, PRIMARY KEY (`code`)' do + pk, seq = @conn.pk_and_sequence_for('ex') + assert_equal 'code', pk + assert_equal @conn.default_sequence_name('ex', 'code'), seq + end end def test_pk_and_sequence_for_with_custom_index_type_pk - @conn.exec_query('drop table if exists ex_with_custom_index_type_pk') - @conn.exec_query(<<-eosql) - CREATE TABLE `ex_with_custom_index_type_pk` ( - `id` INT(11) auto_increment, - PRIMARY KEY USING BTREE (`id`)) - eosql - pk, seq = @conn.pk_and_sequence_for('ex_with_custom_index_type_pk') - assert_equal 'id', pk - assert_equal @conn.default_sequence_name('ex_with_custom_index_type_pk', 'id'), seq + with_example_table '`id` INT(11) auto_increment, PRIMARY KEY USING BTREE (`id`)' do + pk, seq = @conn.pk_and_sequence_for('ex') + assert_equal 'id', pk + assert_equal @conn.default_sequence_name('ex', 'id'), seq + end end def test_tinyint_integer_typecasting - @conn.exec_query('drop table if exists ex_with_non_boolean_tinyint_column') - @conn.exec_query(<<-eosql) - CREATE TABLE `ex_with_non_boolean_tinyint_column` ( - `status` TINYINT(4)) - eosql - insert(@conn, { 'status' => 2 }, 'ex_with_non_boolean_tinyint_column') + with_example_table '`status` TINYINT(4)' do + insert(@conn, { 'status' => 2 }, 'ex') - result = @conn.exec_query('SELECT status FROM ex_with_non_boolean_tinyint_column') + result = @conn.exec_query('SELECT status FROM ex') - assert_equal 2, result.column_types['status'].type_cast(result.last['status']) + assert_equal 2, result.column_types['status'].type_cast(result.last['status']) + end end def test_supports_extensions @@ -140,6 +133,15 @@ module ActiveRecord ctx.exec_insert(sql, 'SQL', binds) end + + def with_example_table(definition = nil, &block) + definition ||= <<-SQL + `id` int(11) auto_increment PRIMARY KEY, + `number` integer, + `data` varchar(255) + SQL + super(@conn, 'ex', definition, &block) + end end end end -- cgit v1.2.3 From 23eafe88778349e66772b3dc9257c8f257acb6bd Mon Sep 17 00:00:00 2001 From: Ankit Gupta Date: Sun, 23 Mar 2014 23:55:03 -0400 Subject: Adding active_model in Rails::Info --- railties/lib/rails/info.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb index edadeaca0e..9502876ebb 100644 --- a/railties/lib/rails/info.rb +++ b/railties/lib/rails/info.rb @@ -23,7 +23,7 @@ module Rails end def frameworks - %w( active_record action_pack action_view action_mailer active_support ) + %w( active_record action_pack action_view action_mailer active_support active_model ) end def framework_version(framework) -- cgit v1.2.3 From f42c7eee7e63d9ac4426259f6b1b424b3f759faa Mon Sep 17 00:00:00 2001 From: Dmitrii Golub Date: Sat, 22 Mar 2014 03:26:02 +0400 Subject: Remove sqlite3 lines from .gitignore if the application is not using sqlite3. --- railties/CHANGELOG.md | 4 ++++ railties/lib/rails/generators/app_base.rb | 4 ++++ .../rails/generators/rails/app/app_generator.rb | 2 +- .../rails/generators/rails/app/templates/gitignore | 2 ++ railties/test/generators/app_generator_test.rb | 26 +++++++++++++++++++++- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index b52b80e802..6cf8714177 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,7 @@ +* Remove sqlite3 lines from `.gitignore` if the application is not using sqlite3. + + *Dmitrii Golub* + * Add public API to register new extensions for `rake notes`. Example: diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index fbdc47ea44..dd1438800c 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -172,6 +172,10 @@ module Rails options[value] ? '# ' : '' end + def sqlite3? + !options[:skip_active_record] && options[:database] == 'sqlite3' + end + class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out) def initialize(name, version, comment, options = {}, commented_out = false) super diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 83cb1dc0d5..abf6909a7f 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -50,7 +50,7 @@ module Rails end def gitignore - copy_file "gitignore", ".gitignore" + template "gitignore", ".gitignore" end def app diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore index 6a502e997f..8775e5e235 100644 --- a/railties/lib/rails/generators/rails/app/templates/gitignore +++ b/railties/lib/rails/generators/rails/app/templates/gitignore @@ -7,10 +7,12 @@ # Ignore bundler config. /.bundle +<% if sqlite3? -%> # Ignore the default SQLite database. /db/*.sqlite3 /db/*.sqlite3-journal +<% end -%> # Ignore all logfiles and tempfiles. /log/*.log /tmp diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 5ebdadacbf..48b40d39e4 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -408,7 +408,31 @@ class AppGeneratorTest < Rails::Generators::TestCase end end -protected + def test_gitignore_when_sqlite3 + run_generator + + assert_file '.gitignore' do |content| + assert_match(/sqlite3/, content) + end + end + + def test_gitignore_when_no_active_record + run_generator [destination_root, '--skip-active-record'] + + assert_file '.gitignore' do |content| + assert_no_match(/sqlite3/, content) + end + end + + def test_gitignore_when_non_sqlite3_db + run_generator([destination_root, "-d", "mysql"]) + + assert_file '.gitignore' do |content| + assert_no_match(/sqlite3/, content) + end + end + + protected def action(*args, &block) silence(:stdout) { generator.send(*args, &block) } -- cgit v1.2.3 From b9440c36dd881ca2643127ba372b2a40e2a4d37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 24 Mar 2014 09:24:47 -0300 Subject: Check if any sqlite files are not included in the gitignore If the sqlite file name change in future version we this regexp should catch --- railties/test/generators/app_generator_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 48b40d39e4..8e1aeddb2b 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -420,7 +420,7 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, '--skip-active-record'] assert_file '.gitignore' do |content| - assert_no_match(/sqlite3/, content) + assert_no_match(/sqlite/i, content) end end @@ -428,7 +428,7 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator([destination_root, "-d", "mysql"]) assert_file '.gitignore' do |content| - assert_no_match(/sqlite3/, content) + assert_no_match(/sqlite/i, content) end end -- cgit v1.2.3 From ab6deeef9bfcd52e364ef83e01be1127121accd9 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Mon, 24 Mar 2014 19:41:43 +0530 Subject: - Rename `increment_or_decrement` to an apt `set_cache_value` since it actually doesn't increment/decrement in localstore. --- activesupport/lib/active_support/cache/strategy/local_cache.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb index 6afb07bd72..e9ee98a128 100644 --- a/activesupport/lib/active_support/cache/strategy/local_cache.rb +++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb @@ -85,13 +85,13 @@ module ActiveSupport def increment(name, amount = 1, options = nil) # :nodoc: value = bypass_local_cache{super} - increment_or_decrement(value, name, amount, options) + set_cache_value(value, name, amount, options) value end def decrement(name, amount = 1, options = nil) # :nodoc: value = bypass_local_cache{super} - increment_or_decrement(value, name, amount, options) + set_cache_value(value, name, amount, options) value end @@ -119,8 +119,7 @@ module ActiveSupport super end - private - def increment_or_decrement(value, name, amount, options) + def set_cache_value(value, name, amount, options) if local_cache local_cache.mute do if value @@ -132,6 +131,8 @@ module ActiveSupport end end + private + def local_cache_key @local_cache_key ||= "#{self.class.name.underscore}_local_cache_#{object_id}".gsub(/[\/-]/, '_').to_sym end -- cgit v1.2.3 From 60ed9d62826678006f0c8abde25ee779b1740c3a Mon Sep 17 00:00:00 2001 From: Izumi Wong-Horiuchi Date: Fri, 21 Mar 2014 16:28:47 -0400 Subject: Fix date_select option overwriting html classes with_css_classes: true option overwrites other html classes. Concatenate day month and year classes rather than overwriting. --- actionview/CHANGELOG.md | 4 ++++ actionview/lib/action_view/helpers/date_helper.rb | 2 +- actionview/test/template/date_helper_test.rb | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index db3fa3be86..8c6db33be7 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,7 @@ +* `date_select` helper with option `with_css_classes: true` does not overwrite other classes. + + *Izumi Wong-Horiuchi* + * `number_to_percentage` does not crash with `Float::NAN` or `Float::INFINITY` as input. diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb index 1738df9cac..2efb9612ac 100644 --- a/actionview/lib/action_view/helpers/date_helper.rb +++ b/actionview/lib/action_view/helpers/date_helper.rb @@ -965,7 +965,7 @@ module ActionView :name => input_name_from_type(type) }.merge!(@html_options) select_options[:disabled] = 'disabled' if @options[:disabled] - select_options[:class] = type if @options[:with_css_classes] + select_options[:class] = [select_options[:class], type].compact.join(' ') if @options[:with_css_classes] select_html = "\n" select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank] diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb index 6f77c3c99d..b86ae910c4 100644 --- a/actionview/test/template/date_helper_test.rb +++ b/actionview/test/template/date_helper_test.rb @@ -1040,6 +1040,22 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), {:start_year => 2003, :end_year => 2005, :prefix => "date[first]", :with_css_classes => true}) end + def test_select_date_with_css_classes_option_and_html_class_option + expected = %(\n" + + expected << %(\n" + + expected << %(\n" + + assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), {:start_year => 2003, :end_year => 2005, :prefix => "date[first]", :with_css_classes => true}, { class: 'datetime optional' }) + end + def test_select_datetime expected = %(