aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/actionmailer.gemspec2
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/abstract_controller/base.rb33
-rw-r--r--actionpack/lib/action_controller/metal/implicit_render.rb10
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb4
-rw-r--r--actionpack/lib/action_controller/metal/responder.rb45
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb6
-rw-r--r--actionpack/test/controller/mime_responds_test.rb57
-rw-r--r--actionpack/test/controller/new_base/render_implicit_action_test.rb5
-rw-r--r--actionpack/test/fixtures/respond_with/using_invalid_resource_with_template.xml.erb1
-rw-r--r--actionpack/test/fixtures/respond_with/using_options_with_template.xml.erb1
-rw-r--r--activemodel/activemodel.gemspec2
-rw-r--r--activemodel/lib/active_model/errors.rb4
-rw-r--r--activemodel/lib/active_model/naming.rb15
-rw-r--r--activemodel/lib/active_model/translation.rb2
-rw-r--r--activerecord/activerecord.gemspec1
-rw-r--r--activerecord/lib/active_record/associations/join_dependency/join_part.rb2
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb35
-rw-r--r--activerecord/test/cases/calculations_test.rb37
-rw-r--r--activerecord/test/cases/finder_test.rb4
-rw-r--r--activerecord/test/cases/relations_test.rb28
-rw-r--r--activeresource/activeresource.gemspec1
-rw-r--r--activesupport/activesupport.gemspec2
-rw-r--r--activesupport/lib/active_support/test_case.rb9
-rw-r--r--activesupport/lib/active_support/testing/mochaing.rb7
-rw-r--r--activesupport/lib/active_support/testing/pending.rb46
-rw-r--r--rails.gemspec1
-rw-r--r--railties/CHANGELOG4
-rw-r--r--railties/lib/rails/commands/console.rb4
-rw-r--r--railties/lib/rails/test_help.rb8
-rw-r--r--railties/railties.gemspec2
31 files changed, 275 insertions, 105 deletions
diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec
index 2ae85f8b57..ee02cf6945 100644
--- a/actionmailer/actionmailer.gemspec
+++ b/actionmailer/actionmailer.gemspec
@@ -17,8 +17,6 @@ Gem::Specification.new do |s|
s.require_path = 'lib'
s.requirements << 'none'
- s.has_rdoc = true
-
s.add_dependency('actionpack', version)
s.add_dependency('mail', '~> 2.2.15')
end
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index 651f3b164a..6c55842eea 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -17,8 +17,6 @@ Gem::Specification.new do |s|
s.require_path = 'lib'
s.requirements << 'none'
- s.has_rdoc = true
-
s.add_dependency('activesupport', version)
s.add_dependency('activemodel', version)
s.add_dependency('rack-cache', '~> 1.0.0')
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb
index c384fd0978..07ff5ad9f3 100644
--- a/actionpack/lib/abstract_controller/base.rb
+++ b/actionpack/lib/abstract_controller/base.rb
@@ -128,20 +128,23 @@ module AbstractController
self.class.action_methods
end
- private
+ # Returns true if the name can be considered an action. This can
+ # be overridden in subclasses to modify the semantics of what
+ # can be considered an action.
+ #
+ # For instance, this is overriden by ActionController to add
+ # the implicit rendering feature.
+ #
+ # ==== Parameters
+ # * <tt>name</tt> - The name of an action to be tested
+ #
+ # ==== Returns
+ # * <tt>TrueClass</tt>, <tt>FalseClass</tt>
+ def action_method?(name)
+ self.class.action_methods.include?(name)
+ end
- # Returns true if the name can be considered an action. This can
- # be overridden in subclasses to modify the semantics of what
- # can be considered an action.
- #
- # ==== Parameters
- # * <tt>name</tt> - The name of an action to be tested
- #
- # ==== Returns
- # * <tt>TrueClass</tt>, <tt>FalseClass</tt>
- def action_method?(name)
- self.class.action_methods.include?(name)
- end
+ private
# Call the action. Override this in a subclass to modify the
# behavior around processing an action. This, and not #process,
@@ -160,8 +163,8 @@ module AbstractController
# If the action name was not found, but a method called "action_missing"
# was found, #method_for_action will return "_handle_action_missing".
# This method calls #action_missing with the current action name.
- def _handle_action_missing
- action_missing(@_action_name)
+ def _handle_action_missing(*args)
+ action_missing(@_action_name, *args)
end
# Takes an action name and returns the name of the method that will
diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb
index 4b301c0d90..3ec0c4c6a4 100644
--- a/actionpack/lib/action_controller/metal/implicit_render.rb
+++ b/actionpack/lib/action_controller/metal/implicit_render.rb
@@ -10,14 +10,12 @@ module ActionController
end
end
- def default_render
- render
+ def default_render(*args)
+ render(*args)
end
- def method_for_action(action_name)
- super || if template_exists?(action_name.to_s, _prefixes)
- action_name.to_s
- end
+ def action_method?(action_name)
+ super || template_exists?(action_name.to_s, _prefixes)
end
end
end
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index a2e06fe0a6..7a8fa7bd86 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -189,7 +189,7 @@ module ActionController #:nodoc:
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
if response = retrieve_response_from_mimes(mimes, &block)
- response.call
+ response.call(nil)
end
end
@@ -259,7 +259,7 @@ module ActionController #:nodoc:
#
def retrieve_response_from_mimes(mimes=nil, &block)
mimes ||= collect_mimes_from_class_level
- collector = Collector.new(mimes) { default_render }
+ collector = Collector.new(mimes) { |options| default_render(options || {}) }
block.call(collector) if block_given?
if format = request.negotiate_mime(collector.order)
diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb
index 4b45413cf8..59a3621f72 100644
--- a/actionpack/lib/action_controller/metal/responder.rb
+++ b/actionpack/lib/action_controller/metal/responder.rb
@@ -77,6 +77,37 @@ module ActionController #:nodoc:
#
# respond_with(@project, :manager, @task)
#
+ # === Custom options
+ #
+ # <code>respond_with</code> also allow you to pass options that are forwarded
+ # to the underlying render call. Those options are only applied success
+ # scenarios. For instance, you can do the following in the create method above:
+ #
+ # def create
+ # @project = Project.find(params[:project_id])
+ # @task = @project.comments.build(params[:task])
+ # flash[:notice] = 'Task was successfully created.' if @task.save
+ # respond_with(@project, @task, :status => 201)
+ # end
+ #
+ # This will return status 201 if the task was saved with success. If not,
+ # it will simply ignore the given options and return status 422 and the
+ # resource errors. To customize the failure scenario, you can pass a
+ # a block to <code>respond_with</code>:
+ #
+ # def create
+ # @project = Project.find(params[:project_id])
+ # @task = @project.comments.build(params[:task])
+ # respond_with(@project, @task, :status => 201) do |format|
+ # if @task.save
+ # flash[:notice] = 'Task was successfully created.'
+ # else
+ # format.html { render "some_special_template" }
+ # end
+ # end
+ # end
+ #
+ # Using <code>respond_with</code> with a block follows the same syntax as <code>respond_to</code>.
class Responder
attr_reader :controller, :request, :format, :resource, :resources, :options
@@ -131,7 +162,11 @@ module ActionController #:nodoc:
# responds to :to_format and display it.
#
def to_format
- default_render
+ if get? || !has_errors?
+ default_render
+ else
+ display_errors
+ end
rescue ActionView::MissingTemplate => e
api_behavior(e)
end
@@ -155,8 +190,6 @@ module ActionController #:nodoc:
if get?
display resource
- elsif has_errors?
- display resource.errors, :status => :unprocessable_entity
elsif post?
display resource, :status => :created, :location => api_location
elsif has_empty_resource_definition?
@@ -185,7 +218,7 @@ module ActionController #:nodoc:
# controller.
#
def default_render
- @default_response.call
+ @default_response.call(options)
end
# Display is just a shortcut to render a resource with the current format.
@@ -209,6 +242,10 @@ module ActionController #:nodoc:
controller.render given_options.merge!(options).merge!(format => resource)
end
+ def display_errors
+ controller.render format => resource.errors, :status => :unprocessable_entity
+ end
+
# Check whether the resource has errors.
#
def has_errors?
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index 11e8c63fa0..b760db42e2 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -46,7 +46,7 @@ module ActionDispatch
expected_options.stringify_keys!
msg = build_message(message, "The recognized options <?> did not match <?>, difference: <?>",
request.path_parameters, expected_options, expected_options.diff(request.path_parameters))
- assert_block(msg) { request.path_parameters == expected_options }
+ assert_equal(expected_options, request.path_parameters, msg)
end
# Asserts that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+.
@@ -84,11 +84,11 @@ module ActionDispatch
found_extras = options.reject {|k, v| ! extra_keys.include? k}
msg = build_message(message, "found extras <?>, not <?>", found_extras, extras)
- assert_block(msg) { found_extras == extras }
+ assert_equal(extras, found_extras, msg)
msg = build_message(message, "The generated path <?> did not match <?>", generated_path,
expected_path)
- assert_block(msg) { expected_path == generated_path }
+ assert_equal(expected_path, generated_path, msg)
end
# Asserts that path and options match both ways; in other words, it verifies that <tt>path</tt> generates
diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb
index 5debf96232..41f80d0784 100644
--- a/actionpack/test/controller/mime_responds_test.rb
+++ b/actionpack/test/controller/mime_responds_test.rb
@@ -558,6 +558,15 @@ class RespondWithController < ActionController::Base
respond_with(resource, :location => "http://test.host/", :status => :created)
end
+ def using_invalid_resource_with_template
+ respond_with(resource)
+ end
+
+ def using_options_with_template
+ @customer = resource
+ respond_with(@customer, :status => 123, :location => "http://test.host/")
+ end
+
def using_resource_with_responder
responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" }
respond_with(resource, :responder => responder)
@@ -953,6 +962,54 @@ class RespondWithControllerTest < ActionController::TestCase
assert_equal 201, @response.status
end
+ def test_using_resource_with_status_and_location_with_invalid_resource
+ errors = { :name => :invalid }
+ Customer.any_instance.stubs(:errors).returns(errors)
+
+ @request.accept = "text/xml"
+
+ post :using_resource_with_status_and_location
+ assert_equal errors.to_xml, @response.body
+ assert_equal 422, @response.status
+ assert_equal nil, @response.location
+
+ put :using_resource_with_status_and_location
+ assert_equal errors.to_xml, @response.body
+ assert_equal 422, @response.status
+ assert_equal nil, @response.location
+ end
+
+ def test_using_invalid_resource_with_template
+ errors = { :name => :invalid }
+ Customer.any_instance.stubs(:errors).returns(errors)
+
+ @request.accept = "text/xml"
+
+ post :using_invalid_resource_with_template
+ assert_equal errors.to_xml, @response.body
+ assert_equal 422, @response.status
+ assert_equal nil, @response.location
+
+ put :using_invalid_resource_with_template
+ assert_equal errors.to_xml, @response.body
+ assert_equal 422, @response.status
+ assert_equal nil, @response.location
+ end
+
+ def test_using_options_with_template
+ @request.accept = "text/xml"
+
+ post :using_options_with_template
+ assert_equal "<customer-name>david</customer-name>", @response.body
+ assert_equal 123, @response.status
+ assert_equal "http://test.host/", @response.location
+
+ put :using_options_with_template
+ assert_equal "<customer-name>david</customer-name>", @response.body
+ assert_equal 123, @response.status
+ assert_equal "http://test.host/", @response.location
+ end
+
def test_using_resource_with_responder
get :using_resource_with_responder
assert_equal "Resource name is david", @response.body
diff --git a/actionpack/test/controller/new_base/render_implicit_action_test.rb b/actionpack/test/controller/new_base/render_implicit_action_test.rb
index 9f69d20329..667a9021be 100644
--- a/actionpack/test/controller/new_base/render_implicit_action_test.rb
+++ b/actionpack/test/controller/new_base/render_implicit_action_test.rb
@@ -24,5 +24,10 @@ module RenderImplicitAction
assert_body "Hello hyphen-ated!"
assert_status 200
end
+
+ test "action_method? returns true for implicit actions" do
+ assert SimpleController.new.action_method?(:hello_world)
+ assert SimpleController.new.action_method?(:"hyphen-ated")
+ end
end
end
diff --git a/actionpack/test/fixtures/respond_with/using_invalid_resource_with_template.xml.erb b/actionpack/test/fixtures/respond_with/using_invalid_resource_with_template.xml.erb
new file mode 100644
index 0000000000..bf5869ed22
--- /dev/null
+++ b/actionpack/test/fixtures/respond_with/using_invalid_resource_with_template.xml.erb
@@ -0,0 +1 @@
+<content>I should not be displayed</content> \ No newline at end of file
diff --git a/actionpack/test/fixtures/respond_with/using_options_with_template.xml.erb b/actionpack/test/fixtures/respond_with/using_options_with_template.xml.erb
new file mode 100644
index 0000000000..b313017913
--- /dev/null
+++ b/actionpack/test/fixtures/respond_with/using_options_with_template.xml.erb
@@ -0,0 +1 @@
+<customer-name><%= @customer.name %></customer-name> \ No newline at end of file
diff --git a/activemodel/activemodel.gemspec b/activemodel/activemodel.gemspec
index fec9c7ff8b..9f80673bb8 100644
--- a/activemodel/activemodel.gemspec
+++ b/activemodel/activemodel.gemspec
@@ -17,8 +17,6 @@ Gem::Specification.new do |s|
s.files = Dir['CHANGELOG', 'MIT-LICENSE', 'README.rdoc', 'lib/**/*']
s.require_path = 'lib'
- s.has_rdoc = true
-
s.add_dependency('activesupport', version)
s.add_dependency('builder', '~> 3.0.0')
s.add_dependency('i18n', '~> 0.5.0')
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index c2f0228785..5e3cf510b0 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -295,8 +295,8 @@ module ActiveModel
type = options.delete(:message) if options[:message].is_a?(Symbol)
defaults = @base.class.lookup_ancestors.map do |klass|
- [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.attributes.#{attribute}.#{type}",
- :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.#{type}" ]
+ [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}",
+ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ]
end
defaults << options.delete(:message)
diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb
index eb9b847509..315ccd40e9 100644
--- a/activemodel/lib/active_model/naming.rb
+++ b/activemodel/lib/active_model/naming.rb
@@ -4,7 +4,7 @@ require 'active_support/core_ext/module/introspection'
module ActiveModel
class Name < String
- attr_reader :singular, :plural, :element, :collection, :partial_path, :route_key, :param_key
+ attr_reader :singular, :plural, :element, :collection, :partial_path, :route_key, :param_key, :i18n_key
alias_method :cache_key, :collection
def initialize(klass, namespace = nil)
@@ -20,6 +20,7 @@ module ActiveModel
@partial_path = "#{@collection}/#{@element}".freeze
@param_key = (namespace ? _singularize(@unnamespaced) : @singular).freeze
@route_key = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural).freeze
+ @i18n_key = self.underscore.to_sym
end
# Transform the model name into a more humane format, using I18n. By default,
@@ -33,7 +34,7 @@ module ActiveModel
@klass.respond_to?(:i18n_scope)
defaults = @klass.lookup_ancestors.map do |klass|
- klass.model_name.underscore.to_sym
+ klass.model_name.i18n_key
end
defaults << options[:default] if options[:default]
@@ -44,9 +45,10 @@ module ActiveModel
end
private
- def _singularize(str)
- ActiveSupport::Inflector.underscore(str).tr('/', '_')
- end
+
+ def _singularize(string, replacement='_')
+ ActiveSupport::Inflector.underscore(string).tr('/', replacement)
+ end
end
# == Active Model Naming
@@ -62,6 +64,9 @@ module ActiveModel
# BookCover.model_name # => "BookCover"
# BookCover.model_name.human # => "Book cover"
#
+ # BookCover.model_name.i18n_key # => "book_cover"
+ # BookModule::BookCover.model_name.i18n_key # => "book_module.book_cover"
+ #
# Providing the functionality that ActiveModel::Naming provides in your object
# is required to pass the Active Model Lint test. So either extending the provided
# method below, or rolling your own is required.
diff --git a/activemodel/lib/active_model/translation.rb b/activemodel/lib/active_model/translation.rb
index dbb76244e4..920a133159 100644
--- a/activemodel/lib/active_model/translation.rb
+++ b/activemodel/lib/active_model/translation.rb
@@ -44,7 +44,7 @@ module ActiveModel
# Specify +options+ with additional translating options.
def human_attribute_name(attribute, options = {})
defaults = lookup_ancestors.map do |klass|
- :"#{self.i18n_scope}.attributes.#{klass.model_name.underscore}.#{attribute}"
+ :"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key}.#{attribute}"
end
defaults << :"attributes.#{attribute}"
diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec
index b1df24844a..c3cd76a714 100644
--- a/activerecord/activerecord.gemspec
+++ b/activerecord/activerecord.gemspec
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
s.files = Dir['CHANGELOG', 'README.rdoc', 'examples/**/*', 'lib/**/*']
s.require_path = 'lib'
- s.has_rdoc = true
s.extra_rdoc_files = %w( README.rdoc )
s.rdoc_options.concat ['--main', 'README.rdoc']
diff --git a/activerecord/lib/active_record/associations/join_dependency/join_part.rb b/activerecord/lib/active_record/associations/join_dependency/join_part.rb
index 3279e56e7d..2b1d888a9a 100644
--- a/activerecord/lib/active_record/associations/join_dependency/join_part.rb
+++ b/activerecord/lib/active_record/associations/join_dependency/join_part.rb
@@ -22,7 +22,7 @@ module ActiveRecord
end
def aliased_table
- Arel::Nodes::TableAlias.new aliased_table_name, table
+ Arel::Nodes::TableAlias.new table, aliased_table_name
end
def ==(other)
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index c1842b1a96..869eebfa34 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -196,24 +196,22 @@ module ActiveRecord
end
def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
- column = aggregate_column(column_name)
-
# Postgresql doesn't like ORDER BY when there are no GROUP BY
relation = except(:order)
- select_value = operation_over_aggregate_column(column, operation, distinct)
- relation.select_values = [select_value]
+ if operation == "count" && (relation.limit_value || relation.offset_value)
+ # Shortcut when limit is zero.
+ return 0 if relation.limit_value == 0
- query_builder = relation.arel
+ query_builder = build_count_subquery(relation, column_name, distinct)
+ else
+ column = aggregate_column(column_name)
- if operation == "count"
- limit = relation.limit_value
- offset = relation.offset_value
+ select_value = operation_over_aggregate_column(column, operation, distinct)
- unless limit && offset
- query_builder.limit = nil
- query_builder.offset = nil
- end
+ relation.select_values = [select_value]
+
+ query_builder = relation.arel
end
type_cast_calculated_value(@klass.connection.select_value(query_builder.to_sql), column_for(column_name), operation)
@@ -312,5 +310,18 @@ module ActiveRecord
select if select !~ /(,|\*)/
end
end
+
+ def build_count_subquery(relation, column_name, distinct)
+ column_alias = Arel.sql('count_column')
+ subquery_alias = Arel.sql('subquery_for_count')
+
+ aliased_column = aggregate_column(column_name == :all ? 1 : column_name).as(column_alias)
+ relation.select_values = [aliased_column]
+ subquery = relation.arel.as(subquery_alias)
+
+ sm = Arel::SelectManager.new relation.engine
+ select_value = operation_over_aggregate_column(column_alias, 'count', distinct)
+ sm.project(select_value).from(subquery)
+ end
end
end
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index c97f1ae634..654c4c9010 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -65,7 +65,7 @@ class CalculationsTest < ActiveRecord::TestCase
c = Account.sum(:credit_limit, :group => :firm_id)
[1,6,2].each { |firm_id| assert c.keys.include?(firm_id) }
end
-
+
def test_should_group_by_multiple_fields
c = Account.count(:all, :group => ['firm_id', :credit_limit])
[ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert c.keys.include?(firm_and_limit) }
@@ -109,27 +109,42 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal [2, 6], c.keys.compact
end
- def test_limit_with_offset_is_kept
+ def test_limit_should_apply_before_count
+ accounts = Account.limit(3).where('firm_id IS NOT NULL')
+
+ assert_equal 3, accounts.count(:firm_id)
+ assert_equal 3, accounts.select(:firm_id).count
+ end
+
+ def test_count_should_shortcut_with_limit_zero
+ accounts = Account.limit(0)
+
+ assert_no_queries { assert_equal 0, accounts.count }
+ end
+
+ def test_limit_is_kept
return if current_adapter?(:OracleAdapter)
- queries = assert_sql { Account.limit(1).offset(1).count }
+ queries = assert_sql { Account.limit(1).count }
assert_equal 1, queries.length
assert_match(/LIMIT/, queries.first)
- assert_match(/OFFSET/, queries.first)
end
- def test_offset_without_limit_removes_offset
+ def test_offset_is_kept
+ return if current_adapter?(:OracleAdapter)
+
queries = assert_sql { Account.offset(1).count }
assert_equal 1, queries.length
- assert_no_match(/LIMIT/, queries.first)
- assert_no_match(/OFFSET/, queries.first)
+ assert_match(/OFFSET/, queries.first)
end
- def test_limit_without_offset_removes_limit
- queries = assert_sql { Account.limit(1).count }
+ def test_limit_with_offset_is_kept
+ return if current_adapter?(:OracleAdapter)
+
+ queries = assert_sql { Account.limit(1).offset(1).count }
assert_equal 1, queries.length
- assert_no_match(/LIMIT/, queries.first)
- assert_no_match(/OFFSET/, queries.first)
+ assert_match(/LIMIT/, queries.first)
+ assert_match(/OFFSET/, queries.first)
end
def test_no_limit_no_offset
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 014588b6d9..3c242667eb 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -209,9 +209,9 @@ class FinderTest < ActiveRecord::TestCase
end
def test_model_class_responds_to_first_bang
- assert_equal topics(:first), Topic.order(:id).first!
+ assert Topic.first!
+ Topic.delete_all
assert_raises ActiveRecord::RecordNotFound do
- Topic.delete_all
Topic.first!
end
end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index 2304c20a5f..fc9df8c7a3 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -672,6 +672,34 @@ class RelationTest < ActiveRecord::TestCase
assert_no_queries { assert_equal 9, best_posts.size }
end
+ def test_size_with_limit
+ posts = Post.limit(10)
+
+ assert_queries(1) { assert_equal 10, posts.size }
+ assert ! posts.loaded?
+
+ best_posts = posts.where(:comments_count => 0)
+ best_posts.to_a # force load
+ assert_no_queries { assert_equal 9, best_posts.size }
+ end
+
+ def test_size_with_zero_limit
+ posts = Post.limit(0)
+
+ assert_no_queries { assert_equal 0, posts.size }
+ assert ! posts.loaded?
+
+ posts.to_a # force load
+ assert_no_queries { assert_equal 0, posts.size }
+ end
+
+ def test_empty_with_zero_limit
+ posts = Post.limit(0)
+
+ assert_no_queries { assert_equal true, posts.empty? }
+ assert ! posts.loaded?
+ end
+
def test_count_complex_chained_relations
posts = Post.select('comments_count').where('id is not null').group("author_id").where("comments_count > 0")
diff --git a/activeresource/activeresource.gemspec b/activeresource/activeresource.gemspec
index a71168722b..c2fd707e9b 100644
--- a/activeresource/activeresource.gemspec
+++ b/activeresource/activeresource.gemspec
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
s.files = Dir['CHANGELOG', 'README.rdoc', 'examples/**/*', 'lib/**/*']
s.require_path = 'lib'
- s.has_rdoc = true
s.extra_rdoc_files = %w( README.rdoc )
s.rdoc_options.concat ['--main', 'README.rdoc']
diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec
index df7f68fecf..eaecb30090 100644
--- a/activesupport/activesupport.gemspec
+++ b/activesupport/activesupport.gemspec
@@ -16,6 +16,4 @@ Gem::Specification.new do |s|
s.files = Dir['CHANGELOG', 'README.rdoc', 'lib/**/*']
s.require_path = 'lib'
-
- s.has_rdoc = true
end
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index fb52fc7083..8d6c27e381 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -5,16 +5,9 @@ require 'active_support/testing/deprecation'
require 'active_support/testing/declarative'
require 'active_support/testing/pending'
require 'active_support/testing/isolation'
+require 'active_support/testing/mochaing'
require 'active_support/core_ext/kernel/reporting'
-begin
- silence_warnings { require 'mocha' }
-rescue LoadError
- # Fake Mocha::ExpectationError so we can rescue it in #run. Bleh.
- Object.const_set :Mocha, Module.new
- Mocha.const_set :ExpectationError, Class.new(StandardError)
-end
-
module ActiveSupport
class TestCase < ::Test::Unit::TestCase
if defined? MiniTest
diff --git a/activesupport/lib/active_support/testing/mochaing.rb b/activesupport/lib/active_support/testing/mochaing.rb
new file mode 100644
index 0000000000..4ad75a6681
--- /dev/null
+++ b/activesupport/lib/active_support/testing/mochaing.rb
@@ -0,0 +1,7 @@
+begin
+ silence_warnings { require 'mocha' }
+rescue LoadError
+ # Fake Mocha::ExpectationError so we can rescue it in #run. Bleh.
+ Object.const_set :Mocha, Module.new
+ Mocha.const_set :ExpectationError, Class.new(StandardError)
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/testing/pending.rb b/activesupport/lib/active_support/testing/pending.rb
index 3d119e2fba..feac7bc347 100644
--- a/activesupport/lib/active_support/testing/pending.rb
+++ b/activesupport/lib/active_support/testing/pending.rb
@@ -11,32 +11,36 @@ module ActiveSupport
@@at_exit = false
def pending(description = "", &block)
- if description.is_a?(Symbol)
- is_pending = $tags[description]
- return block.call unless is_pending
- end
+ if defined?(::MiniTest)
+ skip(description.blank? ? nil : description)
+ else
+ if description.is_a?(Symbol)
+ is_pending = $tags[description]
+ return block.call unless is_pending
+ end
- if block_given?
- failed = false
+ if block_given?
+ failed = false
- begin
- block.call
- rescue Exception
- failed = true
- end
+ begin
+ block.call
+ rescue Exception
+ failed = true
+ end
- flunk("<#{description}> did not fail.") unless failed
- end
+ flunk("<#{description}> did not fail.") unless failed
+ end
- caller[0] =~ (/(.*):(.*):in `(.*)'/)
- @@pending_cases << "#{$3} at #{$1}, line #{$2}"
- print "P"
+ caller[0] =~ (/(.*):(.*):in `(.*)'/)
+ @@pending_cases << "#{$3} at #{$1}, line #{$2}"
+ print "P"
- @@at_exit ||= begin
- at_exit do
- puts "\nPending Cases:"
- @@pending_cases.each do |test_case|
- puts test_case
+ @@at_exit ||= begin
+ at_exit do
+ puts "\nPending Cases:"
+ @@pending_cases.each do |test_case|
+ puts test_case
+ end
end
end
end
diff --git a/rails.gemspec b/rails.gemspec
index 98b5f46554..4ee814c507 100644
--- a/rails.gemspec
+++ b/rails.gemspec
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
s.bindir = 'bin'
s.executables = ['rails']
- s.default_executable = 'rails'
s.add_dependency('activesupport', version)
s.add_dependency('actionpack', version)
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index c1e0a214d2..f159247308 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -1,5 +1,9 @@
*Rails 3.1.0 (unreleased)*
+* Add using Turn with natural language test case names for test_help.rb when running with minitest (Ruby 1.9.2+) [DHH]
+
+* Direct logging of Active Record to STDOUT so it's shown inline with the results in the console [DHH]
+
* Added `config.force_ssl` configuration which loads Rack::SSL middleware and force all requests to be under HTTPS protocol [DHH, Prem Sichanugrist, and Josh Peek]
* Added `rails plugin new` command which generates rails plugin with gemspec, tests and dummy application for testing [Piotr Sarnacki]
diff --git a/railties/lib/rails/commands/console.rb b/railties/lib/rails/commands/console.rb
index de2f190ad5..2b7faf9715 100644
--- a/railties/lib/rails/commands/console.rb
+++ b/railties/lib/rails/commands/console.rb
@@ -34,6 +34,10 @@ module Rails
exit
end
end
+
+ if defined?(ActiveRecord)
+ ActiveRecord::Base.logger = Logger.new(STDERR)
+ end
if options[:sandbox]
puts "Loading #{Rails.env} environment in sandbox (Rails #{Rails.version})"
diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb
index 00029e627e..b9f7bdc2eb 100644
--- a/railties/lib/rails/test_help.rb
+++ b/railties/lib/rails/test_help.rb
@@ -13,6 +13,14 @@ if defined?(Test::Unit::Util::BacktraceFilter) && ENV['BACKTRACE'].nil?
Test::Unit::Util::BacktraceFilter.module_eval { include Rails::BacktraceFilterForTestUnit }
end
+if defined?(MiniTest)
+ require 'turn'
+
+ if MiniTest::Unit.respond_to?(:use_natural_language_case_names=)
+ MiniTest::Unit.use_natural_language_case_names = true
+ end
+end
+
if defined?(ActiveRecord)
require 'active_record/test_case'
diff --git a/railties/railties.gemspec b/railties/railties.gemspec
index c51fe856be..b1eda71c7f 100644
--- a/railties/railties.gemspec
+++ b/railties/railties.gemspec
@@ -17,11 +17,11 @@ Gem::Specification.new do |s|
s.require_path = 'lib'
s.rdoc_options << '--exclude' << '.'
- s.has_rdoc = false
s.add_dependency('rake', '>= 0.8.7')
s.add_dependency('thor', '~> 0.14.4')
s.add_dependency('rack-ssl', '~> 1.3.2')
+ s.add_dependency('turn', '~> 0.8.2')
s.add_dependency('activesupport', version)
s.add_dependency('actionpack', version)
end