aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile3
-rw-r--r--actionpack/CHANGELOG2
-rw-r--r--actionpack/actionpack.gemspec4
-rw-r--r--actionpack/lib/action_controller/metal/params_wrapper.rb13
-rw-r--r--actionpack/lib/action_controller/test_case.rb7
-rw-r--r--actionpack/lib/action_dispatch/http/rack_cache.rb8
-rw-r--r--actionpack/lib/action_dispatch/testing/performance_test.rb19
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb62
-rw-r--r--actionpack/lib/sprockets/railtie.rb12
-rw-r--r--actionpack/test/controller/params_wrapper_test.rb81
-rw-r--r--actionpack/test/dispatch/rack_cache_test.rb21
-rw-r--r--actionpack/test/template/form_helper_test.rb14
-rw-r--r--activemodel/lib/active_model/serializers/xml.rb2
-rw-r--r--activemodel/lib/active_model/validations/length.rb4
-rw-r--r--activemodel/lib/active_model/validations/numericality.rb4
-rw-r--r--activemodel/test/cases/serializers/xml_serialization_test.rb8
-rw-r--r--activerecord/CHANGELOG12
-rw-r--r--activerecord/activerecord.gemspec2
-rw-r--r--activerecord/lib/active_record/associations/alias_tracker.rb2
-rw-r--r--activerecord/lib/active_record/associations/builder/singular_association.rb12
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb8
-rw-r--r--activerecord/lib/active_record/associations/singular_association.rb21
-rw-r--r--activerecord/lib/active_record/base.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb41
-rw-r--r--activerecord/lib/active_record/railties/controller_runtime.rb1
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb21
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb13
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb37
-rw-r--r--activerecord/test/cases/associations/inner_join_association_test.rb2
-rw-r--r--activerecord/test/cases/associations/join_model_test.rb12
-rw-r--r--activerecord/test/cases/base_test.rb13
-rw-r--r--activerecord/test/models/aircraft.rb3
-rw-r--r--activerecord/test/models/bulb.rb13
-rw-r--r--activerecord/test/schema/schema.rb4
-rw-r--r--activeresource/CHANGELOG12
-rw-r--r--activeresource/examples/simple.rb15
-rw-r--r--activeresource/lib/active_resource/base.rb89
-rw-r--r--activeresource/lib/active_resource/connection.rb2
-rw-r--r--activeresource/lib/active_resource/custom_methods.rb24
-rw-r--r--activeresource/lib/active_resource/formats.rb8
-rw-r--r--activeresource/lib/active_resource/formats/json_format.rb2
-rw-r--r--activeresource/lib/active_resource/formats/xml_format.rb13
-rw-r--r--activeresource/lib/active_resource/http_mock.rb46
-rw-r--r--activeresource/test/abstract_unit.rb127
-rw-r--r--activeresource/test/cases/authorization_test.rb104
-rw-r--r--activeresource/test/cases/base/custom_methods_test.rb56
-rw-r--r--activeresource/test/cases/base/load_test.rb31
-rw-r--r--activeresource/test/cases/base/schema_test.rb4
-rw-r--r--activeresource/test/cases/base_test.rb115
-rw-r--r--activeresource/test/cases/connection_test.rb (renamed from activeresource/test/connection_test.rb)86
-rw-r--r--activeresource/test/cases/finder_test.rb16
-rw-r--r--activeresource/test/cases/format_test.rb20
-rw-r--r--activeresource/test/cases/http_mock_test.rb56
-rw-r--r--activeresource/test/cases/log_subscriber_test.rb8
-rw-r--r--activeresource/test/cases/observing_test.rb10
-rw-r--r--activeresource/test/cases/validations_test.rb4
-rw-r--r--activeresource/test/setter_trap.rb2
-rw-r--r--activesupport/lib/active_support/buffered_logger.rb15
-rw-r--r--activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/numeric/time.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb1
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb12
-rw-r--r--activesupport/lib/active_support/testing/performance.rb637
-rw-r--r--activesupport/lib/active_support/testing/performance/jruby.rb115
-rw-r--r--activesupport/lib/active_support/testing/performance/rubinius.rb113
-rw-r--r--activesupport/lib/active_support/testing/performance/ruby.rb152
-rw-r--r--activesupport/lib/active_support/testing/performance/ruby/mri.rb59
-rw-r--r--activesupport/lib/active_support/testing/performance/ruby/yarv.rb57
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb5
-rw-r--r--activesupport/test/core_ext/module/attr_accessor_with_default_test.rb16
-rw-r--r--activesupport/test/option_merger_test.rb8
-rw-r--r--railties/guides/source/configuring.textile46
-rw-r--r--railties/guides/source/performance_testing.textile243
-rw-r--r--railties/lib/rails/commands/benchmarker.rb47
-rw-r--r--railties/lib/rails/commands/profiler.rb70
-rw-r--r--railties/lib/rails/engine.rb6
-rw-r--r--railties/lib/rails/generators/actions.rb2
-rw-r--r--railties/lib/rails/generators/app_base.rb4
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb4
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/show.html.erb2
-rw-r--r--railties/lib/rails/generators/generated_attribute.rb13
-rw-r--r--railties/lib/rails/generators/named_base.rb1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb5
-rw-r--r--railties/lib/rails/generators/rails/controller/templates/controller.rb2
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb1
-rw-r--r--railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/model/templates/fixtures.yml6
-rw-r--r--railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb5
-rw-r--r--railties/test/application/assets_test.rb32
-rw-r--r--railties/test/application/configuration_test.rb2
-rw-r--r--railties/test/generators/actions_test.rb4
-rw-r--r--railties/test/generators/app_generator_test.rb45
-rw-r--r--railties/test/generators/controller_generator_test.rb4
-rw-r--r--railties/test/generators/generated_attribute_test.rb6
-rw-r--r--railties/test/generators/helper_generator_test.rb6
-rw-r--r--railties/test/generators/mailer_generator_test.rb48
-rw-r--r--railties/test/generators/migration_generator_test.rb16
-rw-r--r--railties/test/generators/model_generator_test.rb33
-rw-r--r--railties/test/generators/namespaced_generators_test.rb28
-rw-r--r--railties/test/generators/observer_generator_test.rb2
-rw-r--r--railties/test/generators/plugin_generator_test.rb6
-rw-r--r--railties/test/generators/plugin_new_generator_test.rb5
-rw-r--r--railties/test/generators/resource_generator_test.rb14
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb46
-rw-r--r--railties/test/generators/session_migration_generator_test.rb4
-rw-r--r--railties/test/generators_test.rb30
118 files changed, 2057 insertions, 1310 deletions
diff --git a/Gemfile b/Gemfile
index 7199301b90..e2128abd9f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,7 +10,8 @@ end
gem "coffee-script"
gem "sass"
-gem "uglifier", :git => 'git://github.com/lautis/uglifier.git'
+gem "uglifier", :git => "git://github.com/lautis/uglifier.git"
+gem "rack", :git => "git://github.com/rack/rack.git"
gem "rake", ">= 0.8.7"
gem "mocha", ">= 0.9.8"
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 68076b794e..15abfb8369 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -17,7 +17,7 @@
class PostsController < ActionController::Base
stream :only => :index
end
-
+
Please read the docs at `ActionController::Streaming` for more information.
* Added `ActionDispatch::Request.ignore_accept_header` to ignore accept headers and only consider the format given as parameter [José Valim]
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index 606abac83a..0b4e7027ed 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -24,8 +24,8 @@ Gem::Specification.new do |s|
s.add_dependency('i18n', '~> 0.6.0beta1')
s.add_dependency('rack', '~> 1.3.0.beta')
s.add_dependency('rack-test', '~> 0.6.0')
- s.add_dependency('rack-mount', '~> 0.8.0')
- s.add_dependency('sprockets', '~> 2.0.0.beta.2')
+ s.add_dependency('rack-mount', '~> 0.8.1')
+ s.add_dependency('sprockets', '~> 2.0.0.beta.3')
s.add_dependency('tzinfo', '~> 0.3.27')
s.add_dependency('erubis', '~> 2.7.0')
end
diff --git a/actionpack/lib/action_controller/metal/params_wrapper.rb b/actionpack/lib/action_controller/metal/params_wrapper.rb
index b18be60201..93241fc056 100644
--- a/actionpack/lib/action_controller/metal/params_wrapper.rb
+++ b/actionpack/lib/action_controller/metal/params_wrapper.rb
@@ -2,6 +2,7 @@ require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/array/wrap'
+require 'active_support/core_ext/module/anonymous'
require 'action_dispatch/http/mime_types'
module ActionController
@@ -140,12 +141,14 @@ module ActionController
# This method also does namespace lookup. Foo::Bar::UsersController will
# try to find Foo::Bar::User, Foo::User and finally User.
def _default_wrap_model #:nodoc:
+ return nil if self.anonymous?
+
model_name = self.name.sub(/Controller$/, '').singularize
begin
model_klass = model_name.constantize
rescue NameError, ArgumentError => e
- if e.message =~ /is not missing constant|uninitialized constant #{model_name}/
+ if e.message =~ /is not missing constant|uninitialized constant #{model_name}/
namespaces = model_name.split("::")
namespaces.delete_at(-2)
break if namespaces.last == model_name
@@ -163,12 +166,12 @@ module ActionController
unless options[:only] || options[:except]
model ||= _default_wrap_model
- if !(model.respond_to?(:abstract_class?) && model.abstract_class?) && model.respond_to?(:column_names)
- options[:only] = model.column_names
+ if model.respond_to?(:attribute_names) && model.attribute_names.present?
+ options[:only] = model.attribute_names
end
end
- unless options[:name]
+ unless options[:name] || self.anonymous?
model ||= _default_wrap_model
options[:name] = model ? model.to_s.demodulize.underscore :
controller_name.singularize
@@ -226,7 +229,7 @@ module ActionController
# Checks if we should perform parameters wrapping.
def _wrapper_enabled?
ref = request.content_mime_type.try(:ref)
- _wrapper_formats.include?(ref) && !request.request_parameters[_wrapper_key]
+ _wrapper_formats.include?(ref) && _wrapper_key && !request.request_parameters[_wrapper_key]
end
end
end
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 0085f542aa..89ff5ba174 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -2,6 +2,7 @@ require 'rack/session/abstract/id'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/module/anonymous'
module ActionController
module TemplateAssertions
@@ -413,7 +414,11 @@ module ActionController
@request.env['REQUEST_METHOD'] = http_method
parameters ||= {}
- @request.assign_parameters(@routes, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
+ controller_class_name = @controller.class.anonymous? ?
+ "anonymous_controller" :
+ @controller.class.name.underscore.sub(/_controller$/, '')
+
+ @request.assign_parameters(@routes, controller_class_name, action.to_s, parameters)
@request.session = ActionController::TestSession.new(session) if session
@request.session["flash"] = @request.flash.update(flash || {})
diff --git a/actionpack/lib/action_dispatch/http/rack_cache.rb b/actionpack/lib/action_dispatch/http/rack_cache.rb
index b5c1435903..cc8edee300 100644
--- a/actionpack/lib/action_dispatch/http/rack_cache.rb
+++ b/actionpack/lib/action_dispatch/http/rack_cache.rb
@@ -14,11 +14,15 @@ module ActionDispatch
end
def read(key)
- @store.read(key) || []
+ if data = @store.read(key)
+ Marshal.load(data)
+ else
+ []
+ end
end
def write(key, value)
- @store.write(key, value)
+ @store.write(key, Marshal.dump(value))
end
::Rack::Cache::MetaStore::RAILS = self
diff --git a/actionpack/lib/action_dispatch/testing/performance_test.rb b/actionpack/lib/action_dispatch/testing/performance_test.rb
index e7aeb45fb3..13fe693c32 100644
--- a/actionpack/lib/action_dispatch/testing/performance_test.rb
+++ b/actionpack/lib/action_dispatch/testing/performance_test.rb
@@ -1,17 +1,10 @@
require 'active_support/testing/performance'
-begin
- module ActionDispatch
- # An integration test that runs a code profiler on your test methods.
- # Profiling output for combinations of each test method, measurement, and
- # output format are written to your tmp/performance directory.
- #
- # By default, process_time is measured and both flat and graph_html output
- # formats are written, so you'll have two output files per test method.
- class PerformanceTest < ActionDispatch::IntegrationTest
- include ActiveSupport::Testing::Performance
- end
+module ActionDispatch
+ # An integration test that runs a code profiler on your test methods.
+ # Profiling output for combinations of each test method, measurement, and
+ # output format are written to your tmp/performance directory.
+ class PerformanceTest < ActionDispatch::IntegrationTest
+ include ActiveSupport::Testing::Performance
end
-rescue NameError
- $stderr.puts "Specify ruby-prof as application's dependency in Gemfile to run benchmarks."
end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index b6bb90a3ce..07e2c8d341 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -243,7 +243,7 @@ module ActionView
#
# === Setting the method
#
- # You can force the form to use the full array of HTTP verbs by setting
+ # You can force the form to use the full array of HTTP verbs by setting
#
# :method => (:get|:post|:put|:delete)
#
@@ -584,8 +584,8 @@ module ActionView
# <% end %>
# ...
# <% end %>
- def fields_for(record, record_object = nil, options = {}, &block)
- builder = instantiate_builder(record, record_object, options, &block)
+ def fields_for(record_name, record_object = nil, options = {}, &block)
+ builder = instantiate_builder(record_name, record_object, options, &block)
output = capture(builder, &block)
output.concat builder.hidden_field(:id) if output && options[:hidden_field_id] && !builder.emitted_hidden_id?
output
@@ -898,16 +898,13 @@ module ActionView
private
- def instantiate_builder(record, *args, &block)
- options = args.extract_options!
- record_object = args.shift
-
- case record
+ def instantiate_builder(record_name, record_object, options, &block)
+ case record_name
when String, Symbol
object = record_object
- object_name = record
+ object_name = record_name
else
- object = record
+ object = record_name
object_name = ActiveModel::Naming.param_key(object)
end
@@ -1219,35 +1216,30 @@ module ActionView
RUBY_EVAL
end
- def fields_for(record_or_name_or_array, *args, &block)
- if options.has_key?(:index)
- index = "[#{options[:index]}]"
- elsif defined?(@auto_index)
- self.object_name = @object_name.to_s.sub(/\[\]$/,"")
- index = "[#{@auto_index}]"
- else
- index = ""
- end
-
- args << {} unless args.last.is_a?(Hash)
- args.last[:builder] ||= options[:builder]
- args.last[:parent_builder] = self
+ def fields_for(record_name, record_object = nil, fields_options = {}, &block)
+ fields_options, record_object = record_object, nil if record_object.is_a?(Hash)
+ fields_options[:builder] ||= options[:builder]
+ fields_options[:parent_builder] = self
- case record_or_name_or_array
+ case record_name
when String, Symbol
- if nested_attributes_association?(record_or_name_or_array)
- return fields_for_with_nested_attributes(record_or_name_or_array, args, block)
- else
- name = record_or_name_or_array
+ if nested_attributes_association?(record_name)
+ return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
end
else
- object = record_or_name_or_array.is_a?(Array) ? record_or_name_or_array.last : record_or_name_or_array
- name = ActiveModel::Naming.param_key(object)
- args.unshift(object)
+ record_object = record_name.is_a?(Array) ? record_name.last : record_name
+ record_name = ActiveModel::Naming.param_key(record_object)
+ end
+
+ index = if options.has_key?(:index)
+ "[#{options[:index]}]"
+ elsif defined?(@auto_index)
+ self.object_name = @object_name.to_s.sub(/\[\]$/,"")
+ "[#{@auto_index}]"
end
- name = "#{object_name}#{index}[#{name}]"
+ record_name = "#{object_name}#{index}[#{record_name}]"
- @template.fields_for(name, *args, &block)
+ @template.fields_for(record_name, record_object, fields_options, &block)
end
def label(method, text = nil, options = {}, &block)
@@ -1336,10 +1328,8 @@ module ActionView
@object.respond_to?("#{association_name}_attributes=")
end
- def fields_for_with_nested_attributes(association_name, args, block)
+ def fields_for_with_nested_attributes(association_name, association, options, block)
name = "#{object_name}[#{association_name}_attributes]"
- options = args.extract_options!
- association = args.shift
association = convert_to_model(association)
if association.respond_to?(:persisted?)
diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb
index c75b7d4de0..8cee3babe2 100644
--- a/actionpack/lib/sprockets/railtie.rb
+++ b/actionpack/lib/sprockets/railtie.rb
@@ -34,15 +34,7 @@ module Sprockets
app.assets = asset_environment(app)
ActiveSupport.on_load(:action_view) do
- if app.assets.respond_to?(:context_class)
- context = app.assets.context_class
-
- # TODO: Remove this condition when Sprockets 2.0.beta.3 is released
- else
- context = app.assets.context
- end
-
- context.instance_eval do
+ app.assets.context_class.instance_eval do
include ::ActionView::Helpers::SprocketsHelper
end
end
@@ -99,7 +91,7 @@ module Sprockets
compressor
when :yui
require 'yui/compressor'
- YUI::JavaScriptCompressor.new(:munge => true)
+ YUI::CssCompressor.new
else
sym
end
diff --git a/actionpack/test/controller/params_wrapper_test.rb b/actionpack/test/controller/params_wrapper_test.rb
index bed4a6a553..a50065bcc7 100644
--- a/actionpack/test/controller/params_wrapper_test.rb
+++ b/actionpack/test/controller/params_wrapper_test.rb
@@ -2,7 +2,21 @@ require 'abstract_unit'
module Admin; class User; end; end
+module ParamsWrapperTestHelp
+ def with_default_wrapper_options(&block)
+ @controller.class._wrapper_options = {:format => [:json]}
+ @controller.class.inherited(@controller.class)
+ yield
+ end
+
+ def assert_parameters(expected)
+ assert_equal expected, self.class.controller_class.last_parameters
+ end
+end
+
class ParamsWrapperTest < ActionController::TestCase
+ include ParamsWrapperTestHelp
+
class UsersController < ActionController::Base
class << self
attr_accessor :last_parameters
@@ -133,9 +147,8 @@ class ParamsWrapperTest < ActionController::TestCase
end
def test_derived_wrapped_keys_from_matching_model
- User.expects(:respond_to?).with(:abstract_class?).returns(false)
- User.expects(:respond_to?).with(:column_names).returns(true)
- User.expects(:column_names).returns(["username"])
+ User.expects(:respond_to?).with(:attribute_names).returns(true)
+ User.expects(:attribute_names).twice.returns(["username"])
with_default_wrapper_options do
@request.env['CONTENT_TYPE'] = 'application/json'
@@ -146,9 +159,8 @@ class ParamsWrapperTest < ActionController::TestCase
def test_derived_wrapped_keys_from_specified_model
with_default_wrapper_options do
- Person.expects(:respond_to?).with(:abstract_class?).returns(false)
- Person.expects(:respond_to?).with(:column_names).returns(true)
- Person.expects(:column_names).returns(["username"])
+ Person.expects(:respond_to?).with(:attribute_names).returns(true)
+ Person.expects(:attribute_names).twice.returns(["username"])
UsersController.wrap_parameters Person
@@ -159,8 +171,8 @@ class ParamsWrapperTest < ActionController::TestCase
end
def test_not_wrapping_abstract_model
- User.expects(:respond_to?).with(:abstract_class?).returns(true)
- User.expects(:abstract_class?).returns(true)
+ User.expects(:respond_to?).with(:attribute_names).returns(true)
+ User.expects(:attribute_names).returns([])
with_default_wrapper_options do
@request.env['CONTENT_TYPE'] = 'application/json'
@@ -168,20 +180,11 @@ class ParamsWrapperTest < ActionController::TestCase
assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu', 'title' => 'Developer' }})
end
end
-
- private
- def with_default_wrapper_options(&block)
- @controller.class._wrapper_options = {:format => [:json]}
- @controller.class.inherited(@controller.class)
- yield
- end
-
- def assert_parameters(expected)
- assert_equal expected, UsersController.last_parameters
- end
end
class NamespacedParamsWrapperTest < ActionController::TestCase
+ include ParamsWrapperTestHelp
+
module Admin
module Users
class UsersController < ActionController::Base;
@@ -198,13 +201,13 @@ class NamespacedParamsWrapperTest < ActionController::TestCase
end
class SampleOne
- def self.column_names
+ def self.attribute_names
["username"]
end
end
class SampleTwo
- def self.column_names
+ def self.attribute_names
["title"]
end
end
@@ -249,14 +252,36 @@ class NamespacedParamsWrapperTest < ActionController::TestCase
end
end
- private
- def with_default_wrapper_options(&block)
- @controller.class._wrapper_options = {:format => [:json]}
- @controller.class.inherited(@controller.class)
- yield
+end
+
+class AnonymousControllerParamsWrapperTest < ActionController::TestCase
+ include ParamsWrapperTestHelp
+
+ tests(Class.new(ActionController::Base) do
+ class << self
+ attr_accessor :last_parameters
end
- def assert_parameters(expected)
- assert_equal expected, Admin::Users::UsersController.last_parameters
+ def parse
+ self.class.last_parameters = request.params.except(:controller, :action)
+ head :ok
+ end
+ end)
+
+ def test_does_not_implicitly_wrap_params
+ with_default_wrapper_options do
+ @request.env['CONTENT_TYPE'] = 'application/json'
+ post :parse, { 'username' => 'sikachu' }
+ assert_parameters({ 'username' => 'sikachu' })
end
+ end
+
+ def test_does_wrap_params_if_name_provided
+ with_default_wrapper_options do
+ @controller.class.wrap_parameters(:name => "guest")
+ @request.env['CONTENT_TYPE'] = 'application/json'
+ post :parse, { 'username' => 'sikachu' }
+ assert_parameters({ 'username' => 'sikachu', 'guest' => { 'username' => 'sikachu' }})
+ end
+ end
end
diff --git a/actionpack/test/dispatch/rack_cache_test.rb b/actionpack/test/dispatch/rack_cache_test.rb
new file mode 100644
index 0000000000..79d8a64d29
--- /dev/null
+++ b/actionpack/test/dispatch/rack_cache_test.rb
@@ -0,0 +1,21 @@
+require 'abstract_unit'
+require 'action_dispatch/http/rack_cache'
+
+class RackCacheMetaStoreTest < ActiveSupport::TestCase
+ class ReadWriteHash < ::Hash
+ alias :read :[]
+ alias :write :[]=
+ end
+
+ setup do
+ @store = ActionDispatch::RailsMetaStore.new(ReadWriteHash.new)
+ end
+
+ test "stuff is deep duped" do
+ @store.write(:foo, { :bar => :original })
+ hash = @store.read(:foo)
+ hash[:bar] = :changed
+ hash = @store.read(:foo)
+ assert_equal :original, hash[:bar]
+ end
+end
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index c25c850eb3..286bfb4d04 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -1725,6 +1725,20 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_for_and_fields_for_with_non_nested_association_and_without_object
+ form_for(@post) do |f|
+ concat f.fields_for(:category) { |c|
+ concat c.text_field(:name)
+ }
+ end
+
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'put') do
+ "<input name='post[category][name]' type='text' size='30' id='post_category_name' />"
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
class LabelledFormBuilder < ActionView::Helpers::FormBuilder
(field_helpers - %w(hidden_field)).each do |selector|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb
index 19639b1363..eb3975f86b 100644
--- a/activemodel/lib/active_model/serializers/xml.rb
+++ b/activemodel/lib/active_model/serializers/xml.rb
@@ -25,7 +25,7 @@ module ActiveModel
def decorations
decorations = {}
decorations[:encoding] = 'base64' if type == :binary
- decorations[:type] = type unless type == :string
+ decorations[:type] = (type == :string) ? nil : type
decorations[:nil] = true if value.nil?
decorations
end
diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb
index 72735cfb89..d595a5fb43 100644
--- a/activemodel/lib/active_model/validations/length.rb
+++ b/activemodel/lib/active_model/validations/length.rb
@@ -16,7 +16,7 @@ module ActiveModel
options[:maximum] -= 1 if range.exclude_end?
end
- super(options.reverse_merge(:tokenizer => DEFAULT_TOKENIZER))
+ super
end
def check_validity!
@@ -36,7 +36,7 @@ module ActiveModel
end
def validate_each(record, attribute, value)
- value = options[:tokenizer].call(value) if value.kind_of?(String)
+ value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String)
CHECKS.each do |key, validity_check|
next unless check_value = options[key]
diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb
index ae576462e6..42556c80a9 100644
--- a/activemodel/lib/active_model/validations/numericality.rb
+++ b/activemodel/lib/active_model/validations/numericality.rb
@@ -9,10 +9,6 @@ module ActiveModel
RESERVED_OPTIONS = CHECKS.keys + [:only_integer]
- def initialize(options)
- super(options.reverse_merge(:only_integer => false, :allow_nil => false))
- end
-
def check_validity!
keys = CHECKS.keys - [:odd, :even]
options.slice(*keys).each do |option, value|
diff --git a/activemodel/test/cases/serializers/xml_serialization_test.rb b/activemodel/test/cases/serializers/xml_serialization_test.rb
index 8f5c196850..f978191d22 100644
--- a/activemodel/test/cases/serializers/xml_serialization_test.rb
+++ b/activemodel/test/cases/serializers/xml_serialization_test.rb
@@ -92,7 +92,7 @@ class XmlSerializationTest < ActiveModel::TestCase
test "should serialize string" do
assert_match %r{<name>aaron stack</name>}, @contact.to_xml
end
-
+
test "should serialize nil" do
assert_match %r{<pseudonyms nil=\"true\"></pseudonyms>}, @contact.to_xml(:methods => :pseudonyms)
end
@@ -132,4 +132,10 @@ class XmlSerializationTest < ActiveModel::TestCase
xml = @contact.to_xml(:procs => [ proc ])
assert_match %r{<name-reverse>kcats noraa</name-reverse>}, xml
end
+
+ test "should serialize string correctly when type passed" do
+ xml = @contact.to_xml :type => 'Contact'
+ assert_match %r{<contact type="Contact">}, xml
+ assert_match %r{<name>aaron stack</name>}, xml
+ end
end
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 32bcf02139..502a7e43de 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,17 @@
*Rails 3.1.0 (unreleased)*
+* Add block setting of attributes to singular associations:
+
+ class User < ActiveRecord::Base
+ has_one :account
+ end
+
+ user.build_account{ |a| a.credit_limit => 100.0 }
+
+ The block is called after the instance has been initialized. [Andrew White]
+
+* Add ActiveRecord::Base.attribute_names to return a list of attribute names. This will return an empty array if the model is abstract or table does not exists. [Prem Sichanugrist]
+
* CSV Fixtures are deprecated and support will be removed in Rails 3.2.0
* AR#new, AR#create, AR#create!, AR#update_attributes and AR#update_attributes! all accept a second hash as option that allows you
diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec
index 3a5035305b..335127f38e 100644
--- a/activerecord/activerecord.gemspec
+++ b/activerecord/activerecord.gemspec
@@ -22,6 +22,6 @@ Gem::Specification.new do |s|
s.add_dependency('activesupport', version)
s.add_dependency('activemodel', version)
- s.add_dependency('arel', '~> 2.1.0')
+ s.add_dependency('arel', '~> 2.1.1')
s.add_dependency('tzinfo', '~> 0.3.27')
end
diff --git a/activerecord/lib/active_record/associations/alias_tracker.rb b/activerecord/lib/active_record/associations/alias_tracker.rb
index 634dee2289..44e2ee141e 100644
--- a/activerecord/lib/active_record/associations/alias_tracker.rb
+++ b/activerecord/lib/active_record/associations/alias_tracker.rb
@@ -50,7 +50,7 @@ module ActiveRecord
end
def pluralize(table_name)
- ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name
+ ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name.to_s
end
private
diff --git a/activerecord/lib/active_record/associations/builder/singular_association.rb b/activerecord/lib/active_record/associations/builder/singular_association.rb
index 62d48d3a2c..638a2ec72a 100644
--- a/activerecord/lib/active_record/associations/builder/singular_association.rb
+++ b/activerecord/lib/active_record/associations/builder/singular_association.rb
@@ -29,16 +29,16 @@ module ActiveRecord::Associations::Builder
def define_constructors
name = self.name
- model.redefine_method("build_#{name}") do |*params|
- association(name).build(*params)
+ model.redefine_method("build_#{name}") do |*params, &block|
+ association(name).build(*params, &block)
end
- model.redefine_method("create_#{name}") do |*params|
- association(name).create(*params)
+ model.redefine_method("create_#{name}") do |*params, &block|
+ association(name).create(*params, &block)
end
- model.redefine_method("create_#{name}!") do |*params|
- association(name).create!(*params)
+ model.redefine_method("create_#{name}!") do |*params, &block|
+ association(name).create!(*params, &block)
end
end
end
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 525ac65722..902ad8cb64 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -423,9 +423,13 @@ module ActiveRecord
raise NotImplementedError
end
+ def create_scope
+ scoped.scope_for_create.stringify_keys
+ end
+
def build_record(attributes, options)
- record = reflection.build_association
- record.assign_attributes(scoped.scope_for_create, :without_protection => true)
+ record = reflection.build_association(attributes, options)
+ record.assign_attributes(create_scope.except(*record.changed), :without_protection => true)
record.assign_attributes(attributes, options)
record
end
diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb
index 877ddf3ee1..ce1f2a5543 100644
--- a/activerecord/lib/active_record/associations/singular_association.rb
+++ b/activerecord/lib/active_record/associations/singular_association.rb
@@ -17,27 +17,28 @@ module ActiveRecord
replace(record)
end
- def create(attributes = {}, options = {})
- build(attributes, options).tap { |record| record.save }
+ def create(attributes = {}, options = {}, &block)
+ build(attributes, options, &block).tap { |record| record.save }
end
- def create!(attributes = {}, options = {})
- build(attributes, options).tap { |record| record.save! }
+ def create!(attributes = {}, options = {}, &block)
+ build(attributes, options, &block).tap { |record| record.save! }
end
def build(attributes = {}, options = {})
- record = reflection.build_association
- record.assign_attributes(
- scoped.scope_for_create.except(klass.primary_key),
- :without_protection => true
- )
- record.assign_attributes(attributes, options)
+ record = reflection.build_association(attributes, options)
+ record.assign_attributes(create_scope.except(*record.changed), :without_protection => true)
+ yield(record) if block_given?
set_new_record(record)
record
end
private
+ def create_scope
+ scoped.scope_for_create.stringify_keys.except(klass.primary_key)
+ end
+
def find_target
scoped.first.tap { |record| set_inverse_instance(record) }
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index e1bf2ccc8a..cd16b8d3ca 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -767,6 +767,17 @@ module ActiveRecord #:nodoc:
super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
end
+ # Returns an array of column names as strings if it's not
+ # an abstract class and table exists.
+ # Otherwise it returns an empty array.
+ def attribute_names
+ @attribute_names ||= if !abstract_class? && table_exists?
+ column_names
+ else
+ []
+ end
+ end
+
# Set the lookup ancestors for ActiveModel.
def lookup_ancestors #:nodoc:
klass = self
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index f4beeceb61..0a460bc086 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -701,11 +701,11 @@ module ActiveRecord
schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
result = query(<<-SQL, name)
SELECT distinct i.relname, d.indisunique, d.indkey, t.oid
- FROM pg_class t, pg_class i, pg_index d
+ FROM pg_class t
+ INNER JOIN pg_index d ON t.oid = d.indrelid
+ INNER JOIN pg_class i ON d.indexrelid = i.oid
WHERE i.relkind = 'i'
- AND d.indexrelid = i.oid
AND d.indisprimary = 'f'
- AND t.oid = d.indrelid
AND t.relname = '#{table_name}'
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname IN (#{schemas}) )
ORDER BY i.relname
@@ -820,19 +820,13 @@ module ActiveRecord
# given table's primary key.
result = exec_query(<<-end_sql, 'SCHEMA').rows.first
SELECT attr.attname, seq.relname
- FROM pg_class seq,
- pg_attribute attr,
- pg_depend dep,
- pg_namespace name,
- pg_constraint cons
- WHERE seq.oid = dep.objid
- AND seq.relkind = 'S'
- AND attr.attrelid = dep.refobjid
- AND attr.attnum = dep.refobjsubid
- AND attr.attrelid = cons.conrelid
- AND attr.attnum = cons.conkey[1]
- AND cons.contype = 'p'
- AND dep.refobjid = '#{quote_table_name(table)}'::regclass
+ FROM pg_class seq
+ INNER JOIN pg_depend dep ON seq.oid = dep.objid
+ INNER JOIN pg_attribute attr ON attr.attrelid = dep.refobjid AND attr.attnum = dep.refobjsubid
+ INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1]
+ WHERE seq.relkind = 'S'
+ AND cons.contype = 'p'
+ AND dep.refobjid = '#{quote_table_name(table)}'::regclass
end_sql
# [primary_key, sequence]
@@ -845,16 +839,11 @@ module ActiveRecord
def primary_key(table)
row = exec_query(<<-end_sql, 'SCHEMA', [[nil, table]]).rows.first
SELECT DISTINCT(attr.attname)
- FROM pg_attribute attr,
- pg_depend dep,
- pg_namespace name,
- pg_constraint cons
- WHERE attr.attrelid = dep.refobjid
- AND attr.attnum = dep.refobjsubid
- AND attr.attrelid = cons.conrelid
- AND attr.attnum = cons.conkey[1]
- AND cons.contype = 'p'
- AND dep.refobjid = $1::regclass
+ FROM pg_attribute attr
+ INNER JOIN pg_depend dep ON attr.attrelid = dep.refobjid AND attr.attnum = dep.refobjsubid
+ INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1]
+ WHERE cons.contype = 'p'
+ AND dep.refobjid = $1::regclass
end_sql
row && row.first
diff --git a/activerecord/lib/active_record/railties/controller_runtime.rb b/activerecord/lib/active_record/railties/controller_runtime.rb
index 9e3b3429e4..fb3fd34665 100644
--- a/activerecord/lib/active_record/railties/controller_runtime.rb
+++ b/activerecord/lib/active_record/railties/controller_runtime.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/module/attr_internal'
+require 'active_record/log_subscriber'
module ActiveRecord
module Railties
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index ddcc36c841..b993bf6e90 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -626,4 +626,25 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal "Bob", firm.name
end
+
+ def test_build_with_block
+ client = Client.create(:name => 'Client Company')
+
+ firm = client.build_firm{ |f| f.name = 'Agency Company' }
+ assert_equal 'Agency Company', firm.name
+ end
+
+ def test_create_with_block
+ client = Client.create(:name => 'Client Company')
+
+ firm = client.create_firm{ |f| f.name = 'Agency Company' }
+ assert_equal 'Agency Company', firm.name
+ end
+
+ def test_create_bang_with_block
+ client = Client.create(:name => 'Client Company')
+
+ firm = client.create_firm!{ |f| f.name = 'Agency Company' }
+ assert_equal 'Agency Company', firm.name
+ end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 0e33fa9c8e..522ac56d82 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -1455,4 +1455,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal "RED!", car.bulbs.to_a.first.color
end
+
+ def test_new_is_called_with_attributes_and_options
+ car = Car.create(:name => 'honda')
+
+ bulb = car.bulbs.build
+ assert_equal Bulb, bulb.class
+
+ bulb = car.bulbs.build(:bulb_type => :custom)
+ assert_equal Bulb, bulb.class
+
+ bulb = car.bulbs.build({ :bulb_type => :custom }, :as => :admin)
+ assert_equal CustomBulb, bulb.class
+ end
end
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index 356a4a7a09..f3bf5baa95 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -410,4 +410,41 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
bulb = car.create_frickinawesome_bulb(:frickinawesome => false)
assert_equal true, bulb.frickinawesome?
end
+
+ def test_new_is_called_with_attributes_and_options
+ car = Car.create(:name => 'honda')
+
+ bulb = car.build_bulb
+ assert_equal Bulb, bulb.class
+
+ bulb = car.build_bulb
+ assert_equal Bulb, bulb.class
+
+ bulb = car.build_bulb(:bulb_type => :custom)
+ assert_equal Bulb, bulb.class
+
+ bulb = car.build_bulb({ :bulb_type => :custom }, :as => :admin)
+ assert_equal CustomBulb, bulb.class
+ end
+
+ def test_build_with_block
+ car = Car.create(:name => 'honda')
+
+ bulb = car.build_bulb{ |b| b.color = 'Red' }
+ assert_equal 'RED!', bulb.color
+ end
+
+ def test_create_with_block
+ car = Car.create(:name => 'honda')
+
+ bulb = car.create_bulb{ |b| b.color = 'Red' }
+ assert_equal 'RED!', bulb.color
+ end
+
+ def test_create_bang_with_block
+ car = Car.create(:name => 'honda')
+
+ bulb = car.create_bulb!{ |b| b.color = 'Red' }
+ assert_equal 'RED!', bulb.color
+ end
end
diff --git a/activerecord/test/cases/associations/inner_join_association_test.rb b/activerecord/test/cases/associations/inner_join_association_test.rb
index 55d9a328a7..e5e9ca6131 100644
--- a/activerecord/test/cases/associations/inner_join_association_test.rb
+++ b/activerecord/test/cases/associations/inner_join_association_test.rb
@@ -10,7 +10,7 @@ require 'models/tagging'
require 'models/tag'
class InnerJoinAssociationTest < ActiveRecord::TestCase
- fixtures :authors, :posts, :comments, :categories, :categories_posts, :categorizations,
+ fixtures :authors, :essays, :posts, :comments, :categories, :categories_posts, :categorizations,
:taggings, :tags
def test_construct_finder_sql_applies_aliases_tables_on_association_conditions
diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb
index 49a1c117bc..8e23ab78be 100644
--- a/activerecord/test/cases/associations/join_model_test.rb
+++ b/activerecord/test/cases/associations/join_model_test.rb
@@ -13,6 +13,9 @@ require 'models/vertex'
require 'models/edge'
require 'models/book'
require 'models/citation'
+require 'models/aircraft'
+require 'models/engine'
+require 'models/car'
class AssociationsJoinModelTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false unless supports_savepoints?
@@ -704,6 +707,15 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort
end
+ def test_has_many_with_pluralize_table_names_false
+ engine = Engine.create(:car_id => 1)
+ Aircraft.pluralize_table_names = false
+ aircraft = Aircraft.create!(:name => "Airbus 380", :id => 1)
+ assert_equal aircraft.engines, [engine]
+ ensure
+ ActiveRecord::Base.pluralize_table_names = true
+ end
+
private
# create dynamic Post models to allow different dependency options
def find_post_with_dependency(post_id, association, association_name, dependency)
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 9bc04ed29c..bfb66f07da 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1790,4 +1790,17 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal expected.attributes, actual.attributes
end
+
+ def test_attribute_names
+ assert_equal ["id", "type", "ruby_type", "firm_id", "firm_name", "name", "client_of", "rating", "account_id"],
+ Company.attribute_names
+ end
+
+ def test_attribute_names_on_table_not_exists
+ assert_equal [], NonExistentTable.attribute_names
+ end
+
+ def test_attribtue_names_on_abstract_class
+ assert_equal [], AbstractCompany.attribute_names
+ end
end
diff --git a/activerecord/test/models/aircraft.rb b/activerecord/test/models/aircraft.rb
new file mode 100644
index 0000000000..0c47aab539
--- /dev/null
+++ b/activerecord/test/models/aircraft.rb
@@ -0,0 +1,3 @@
+class Aircraft < ActiveRecord::Base
+ has_many :engines, :foreign_key => "car_id"
+end
diff --git a/activerecord/test/models/bulb.rb b/activerecord/test/models/bulb.rb
index 7d90963720..0dcc8d5970 100644
--- a/activerecord/test/models/bulb.rb
+++ b/activerecord/test/models/bulb.rb
@@ -15,4 +15,17 @@ class Bulb < ActiveRecord::Base
self[:color] = color.upcase + "!"
end
+ def self.new(attributes = {}, options = {}, &block)
+ bulb_type = (attributes || {}).delete(:bulb_type)
+
+ if options && options[:as] == :admin && bulb_type.present?
+ bulb_class = "#{bulb_type.to_s.camelize}Bulb".constantize
+ bulb_class.new(attributes, options, &block)
+ else
+ super
+ end
+ end
end
+
+class CustomBulb < Bulb
+end \ No newline at end of file
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index d56cdd57b2..4fe311b441 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -40,6 +40,10 @@ ActiveRecord::Schema.define do
t.references :account
end
+ create_table :aircraft, :force => true do |t|
+ t.string :name
+ end
+
create_table :audit_logs, :force => true do |t|
t.column :message, :string, :null=>false
t.column :developer_id, :integer, :null=>false
diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG
index a4e79f3d77..25f9242b98 100644
--- a/activeresource/CHANGELOG
+++ b/activeresource/CHANGELOG
@@ -1,11 +1,15 @@
*Rails 3.1.0 (unreleased)*
-* No changes
+* The default format has been changed to JSON for all requests. If you want to continue to use XML you will need to set `self.format = :xml` in the class. eg.
+
+class User < ActiveResource::Base
+ self.format = :xml
+end
*Rails 3.0.7 (April 18, 2011)*
-*No changes.
+* No changes.
*Rails 3.0.6 (April 5, 2011)
@@ -95,14 +99,14 @@
* Ruby 1.9 compatibility. [Jeremy Kemper]
-*2.0.2* (December 16th, 2007)
+*2.0.2 (December 16th, 2007)*
* Added more specific exceptions for 400, 401, and 403 (all descending from ClientError so existing rescues will work) #10326 [trek]
* Correct empty response handling. #10445 [seangeo]
-*2.0.1* (December 7th, 2007)
+*2.0.1 (December 7th, 2007)*
* Don't cache net/http object so that ActiveResource is more thread-safe. Closes #10142 [kou]
diff --git a/activeresource/examples/simple.rb b/activeresource/examples/simple.rb
deleted file mode 100644
index 6d2c6e3b1b..0000000000
--- a/activeresource/examples/simple.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
-require 'active_resource'
-require 'active_support/core_ext/hash/conversions'
-
-ActiveSupport::XmlMini.backend = ENV['XMLMINI'] || 'REXML'
-ActiveResource::HttpMock.respond_to do |mock|
- mock.get '/people/1.xml', {}, { :id => 1, :name => 'bob' }.to_xml(:root => 'person')
-end
-
-class Person < ActiveResource::Base
- self.site = 'http://localhost/'
-end
-
-bob = Person.find(1)
-puts bob.inspect
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index 7f2a844723..65d285249b 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -81,19 +81,19 @@ module ActiveResource
# <tt>post</tt>, <tt>put</tt> and <tt>\delete</tt> methods where you can specify a custom REST method
# name to invoke.
#
- # # POST to the custom 'register' REST method, i.e. POST /people/new/register.xml.
+ # # POST to the custom 'register' REST method, i.e. POST /people/new/register.json.
# Person.new(:name => 'Ryan').post(:register)
# # => { :id => 1, :name => 'Ryan', :position => 'Clerk' }
#
- # # PUT an update by invoking the 'promote' REST method, i.e. PUT /people/1/promote.xml?position=Manager.
+ # # PUT an update by invoking the 'promote' REST method, i.e. PUT /people/1/promote.json?position=Manager.
# Person.find(1).put(:promote, :position => 'Manager')
# # => { :id => 1, :name => 'Ryan', :position => 'Manager' }
#
- # # GET all the positions available, i.e. GET /people/positions.xml.
+ # # GET all the positions available, i.e. GET /people/positions.json.
# Person.get(:positions)
# # => [{:name => 'Manager'}, {:name => 'Clerk'}]
#
- # # DELETE to 'fire' a person, i.e. DELETE /people/1/fire.xml.
+ # # DELETE to 'fire' a person, i.e. DELETE /people/1/fire.json.
# Person.find(1).delete(:fire)
#
# For more information on using custom REST methods, see the
@@ -164,7 +164,7 @@ module ActiveResource
# response code will be returned from the server which will raise an ActiveResource::ResourceNotFound
# exception.
#
- # # GET http://api.people.com:3000/people/999.xml
+ # # GET http://api.people.com:3000/people/999.json
# ryan = Person.find(999) # 404, raises ActiveResource::ResourceNotFound
#
#
@@ -218,7 +218,7 @@ module ActiveResource
# ryan.save # => false
#
# # When
- # # PUT http://api.people.com:3000/people/1.xml
+ # # PUT http://api.people.com:3000/people/1.json
# # or
# # PUT http://api.people.com:3000/people/1.json
# # is requested with invalid values, the response is:
@@ -489,7 +489,7 @@ module ActiveResource
# Person.format = ActiveResource::Formats::XmlFormat
# Person.find(1) # => GET /people/1.xml
#
- # Default format is <tt>:xml</tt>.
+ # Default format is <tt>:json</tt>.
def format=(mime_type_reference_or_format)
format = mime_type_reference_or_format.is_a?(Symbol) ?
ActiveResource::Formats[mime_type_reference_or_format] : mime_type_reference_or_format
@@ -498,9 +498,9 @@ module ActiveResource
connection.format = format if site
end
- # Returns the current format, default is ActiveResource::Formats::XmlFormat.
+ # Returns the current format, default is ActiveResource::Formats::JsonFormat.
def format
- self._format || ActiveResource::Formats::XmlFormat
+ self._format || ActiveResource::Formats::JsonFormat
end
# Sets the number of seconds after which requests to the REST API should time out.
@@ -570,7 +570,7 @@ module ActiveResource
attr_accessor_with_default(:primary_key, 'id') #:nodoc:
- # Gets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.xml</tt>)
+ # Gets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.json</tt>)
# This method is regenerated at runtime based on what the \prefix is set to.
def prefix(options={})
default = site.path
@@ -587,7 +587,7 @@ module ActiveResource
prefix_source
end
- # Sets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.xml</tt>).
+ # Sets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.json</tt>).
# Default value is <tt>site.path</tt>.
def prefix=(value = '/')
# Replace :placeholders with '#{embedded options[:lookups]}'
@@ -618,21 +618,21 @@ module ActiveResource
#
# ==== Options
# +prefix_options+ - A \hash to add a \prefix to the request for nested URLs (e.g., <tt>:account_id => 19</tt>
- # would yield a URL like <tt>/accounts/19/purchases.xml</tt>).
+ # would yield a URL like <tt>/accounts/19/purchases.json</tt>).
# +query_options+ - A \hash to add items to the query string for the request.
#
# ==== Examples
# Post.element_path(1)
- # # => /posts/1.xml
+ # # => /posts/1.json
#
# Comment.element_path(1, :post_id => 5)
- # # => /posts/5/comments/1.xml
+ # # => /posts/5/comments/1.json
#
# Comment.element_path(1, :post_id => 5, :active => 1)
- # # => /posts/5/comments/1.xml?active=1
+ # # => /posts/5/comments/1.json?active=1
#
# Comment.element_path(1, {:post_id => 5}, {:active => 1})
- # # => /posts/5/comments/1.xml?active=1
+ # # => /posts/5/comments/1.json?active=1
#
def element_path(id, prefix_options = {}, query_options = nil)
check_prefix_options(prefix_options)
@@ -645,14 +645,14 @@ module ActiveResource
#
# ==== Options
# * +prefix_options+ - A hash to add a prefix to the request for nested URLs (e.g., <tt>:account_id => 19</tt>
- # would yield a URL like <tt>/accounts/19/purchases/new.xml</tt>).
+ # would yield a URL like <tt>/accounts/19/purchases/new.json</tt>).
#
# ==== Examples
# Post.new_element_path
- # # => /posts/new.xml
+ # # => /posts/new.json
#
# Comment.collection_path(:post_id => 5)
- # # => /posts/5/comments/new.xml
+ # # => /posts/5/comments/new.json
def new_element_path(prefix_options = {})
"#{prefix(prefix_options)}#{collection_name}/new.#{format.extension}"
end
@@ -662,21 +662,21 @@ module ActiveResource
#
# ==== Options
# * +prefix_options+ - A hash to add a prefix to the request for nested URLs (e.g., <tt>:account_id => 19</tt>
- # would yield a URL like <tt>/accounts/19/purchases.xml</tt>).
+ # would yield a URL like <tt>/accounts/19/purchases.json</tt>).
# * +query_options+ - A hash to add items to the query string for the request.
#
# ==== Examples
# Post.collection_path
- # # => /posts.xml
+ # # => /posts.json
#
# Comment.collection_path(:post_id => 5)
- # # => /posts/5/comments.xml
+ # # => /posts/5/comments.json
#
# Comment.collection_path(:post_id => 5, :active => 1)
- # # => /posts/5/comments.xml?active=1
+ # # => /posts/5/comments.json?active=1
#
# Comment.collection_path({:post_id => 5}, {:active => 1})
- # # => /posts/5/comments.xml?active=1
+ # # => /posts/5/comments.json?active=1
#
def collection_path(prefix_options = {}, query_options = nil)
check_prefix_options(prefix_options)
@@ -745,34 +745,34 @@ module ActiveResource
#
# ==== Examples
# Person.find(1)
- # # => GET /people/1.xml
+ # # => GET /people/1.json
#
# Person.find(:all)
- # # => GET /people.xml
+ # # => GET /people.json
#
# Person.find(:all, :params => { :title => "CEO" })
- # # => GET /people.xml?title=CEO
+ # # => GET /people.json?title=CEO
#
# Person.find(:first, :from => :managers)
- # # => GET /people/managers.xml
+ # # => GET /people/managers.json
#
# Person.find(:last, :from => :managers)
- # # => GET /people/managers.xml
+ # # => GET /people/managers.json
#
- # Person.find(:all, :from => "/companies/1/people.xml")
- # # => GET /companies/1/people.xml
+ # Person.find(:all, :from => "/companies/1/people.json")
+ # # => GET /companies/1/people.json
#
# Person.find(:one, :from => :leader)
- # # => GET /people/leader.xml
+ # # => GET /people/leader.json
#
# Person.find(:all, :from => :developers, :params => { :language => 'ruby' })
- # # => GET /people/developers.xml?language=ruby
+ # # => GET /people/developers.json?language=ruby
#
- # Person.find(:one, :from => "/companies/1/manager.xml")
- # # => GET /companies/1/manager.xml
+ # Person.find(:one, :from => "/companies/1/manager.json")
+ # # => GET /companies/1/manager.json
#
# StreetAddress.find(1, :params => { :person_id => 1 })
- # # => GET /people/1/street_addresses/1.xml
+ # # => GET /people/1/street_addresses/1.json
#
# == Failure or missing data
# A failure to find the requested object raises a ResourceNotFound
@@ -833,7 +833,7 @@ module ActiveResource
# my_event = Event.find(:first) # let's assume this is event with ID 7
# Event.delete(my_event.id) # sends DELETE /events/7
#
- # # Let's assume a request to events/5/cancel.xml
+ # # Let's assume a request to events/5/cancel.json
# Event.delete(params[:id]) # sends DELETE /events/5
def delete(id, options = {})
connection.delete(element_path(id, options))
@@ -1121,7 +1121,7 @@ module ActiveResource
# Saves (+POST+) or \updates (+PUT+) a resource. Delegates to +create+ if the object is \new,
# +update+ if it exists. If the response to the \save includes a body, it will be assumed that this body
- # is XML for the final object as it looked after the \save (which would include attributes like +created_at+
+ # is Json for the final object as it looked after the \save (which would include attributes like +created_at+
# that weren't part of the original submit).
#
# ==== Examples
@@ -1232,9 +1232,16 @@ module ActiveResource
# your_supplier = Supplier.new
# your_supplier.load(my_attrs)
# your_supplier.save
- def load(attributes)
+ def load(attributes, remove_root = false)
raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
@prefix_options, attributes = split_options(attributes)
+
+ if attributes.keys.size == 1
+ remove_root = self.class.element_name == attributes.keys.first.to_s
+ end
+
+ attributes = Formats.remove_root(attributes) if remove_root
+
attributes.each do |key, value|
@attributes[key.to_s] =
case value
@@ -1285,7 +1292,7 @@ module ActiveResource
# resource's attributes, the full body of the request will still be sent
# in the save request to the remote service.
def update_attributes(attributes)
- load(attributes) && save
+ load(attributes, false) && save
end
# For checking <tt>respond_to?</tt> without searching the attributes (which is faster).
@@ -1339,7 +1346,7 @@ module ActiveResource
def load_attributes_from_response(response)
if !response['Content-Length'].blank? && response['Content-Length'] != "0" && !response.body.nil? && response.body.strip.size > 0
- load(self.class.format.decode(response.body))
+ load(self.class.format.decode(response.body), true)
@persisted = true
end
end
diff --git a/activeresource/lib/active_resource/connection.rb b/activeresource/lib/active_resource/connection.rb
index 765575d866..d923204dde 100644
--- a/activeresource/lib/active_resource/connection.rb
+++ b/activeresource/lib/active_resource/connection.rb
@@ -30,7 +30,7 @@ module ActiveResource
# The +site+ parameter is required and will set the +site+
# attribute to the URI for the remote resource service.
- def initialize(site, format = ActiveResource::Formats::XmlFormat)
+ def initialize(site, format = ActiveResource::Formats::JsonFormat)
raise ArgumentError, 'Missing site URI' unless site
@user = @password = nil
self.site = site
diff --git a/activeresource/lib/active_resource/custom_methods.rb b/activeresource/lib/active_resource/custom_methods.rb
index 9879f8cded..c1931b2758 100644
--- a/activeresource/lib/active_resource/custom_methods.rb
+++ b/activeresource/lib/active_resource/custom_methods.rb
@@ -11,10 +11,10 @@ module ActiveResource
#
# This route set creates routes for the following HTTP requests:
#
- # POST /people/new/register.xml # PeopleController.register
- # PUT /people/1/promote.xml # PeopleController.promote with :id => 1
- # DELETE /people/1/deactivate.xml # PeopleController.deactivate with :id => 1
- # GET /people/active.xml # PeopleController.active
+ # POST /people/new/register.json # PeopleController.register
+ # PUT /people/1/promote.json # PeopleController.promote with :id => 1
+ # DELETE /people/1/deactivate.json # PeopleController.deactivate with :id => 1
+ # GET /people/active.json # PeopleController.active
#
# Using this module, Active Resource can use these custom REST methods just like the
# standard methods.
@@ -23,13 +23,13 @@ module ActiveResource
# self.site = "http://37s.sunrise.i:3000"
# end
#
- # Person.new(:name => 'Ryan).post(:register) # POST /people/new/register.xml
+ # Person.new(:name => 'Ryan).post(:register) # POST /people/new/register.json
# # => { :id => 1, :name => 'Ryan' }
#
- # Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.xml
- # Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.xml
+ # Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.json
+ # Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.json
#
- # Person.get(:active) # GET /people/active.xml
+ # Person.get(:active) # GET /people/active.json
# # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
#
module CustomMethods
@@ -41,10 +41,10 @@ module ActiveResource
# Invokes a GET to a given custom REST method. For example:
#
- # Person.get(:active) # GET /people/active.xml
+ # Person.get(:active) # GET /people/active.json
# # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
#
- # Person.get(:active, :awesome => true) # GET /people/active.xml?awesome=true
+ # Person.get(:active, :awesome => true) # GET /people/active.json?awesome=true
# # => [{:id => 1, :name => 'Ryan'}]
#
# Note: the objects returned from this method are not automatically converted
@@ -54,7 +54,9 @@ module ActiveResource
#
# Person.find(:all, :from => :active)
def get(custom_method_name, options = {})
- format.decode(connection.get(custom_method_collection_url(custom_method_name, options), headers).body)
+ hashified = format.decode(connection.get(custom_method_collection_url(custom_method_name, options), headers).body)
+ derooted = Formats.remove_root(hashified)
+ derooted.is_a?(Array) ? derooted.map { |e| Formats.remove_root(e) } : derooted
end
def post(custom_method_name, options = {}, body = '')
diff --git a/activeresource/lib/active_resource/formats.rb b/activeresource/lib/active_resource/formats.rb
index 53b75b34e7..f7ad689cc5 100644
--- a/activeresource/lib/active_resource/formats.rb
+++ b/activeresource/lib/active_resource/formats.rb
@@ -10,5 +10,13 @@ module ActiveResource
def self.[](mime_type_reference)
ActiveResource::Formats.const_get(ActiveSupport::Inflector.camelize(mime_type_reference.to_s) + "Format")
end
+
+ def self.remove_root(data)
+ if data.is_a?(Hash) && data.keys.size == 1
+ data.values.first
+ else
+ data
+ end
+ end
end
end
diff --git a/activeresource/lib/active_resource/formats/json_format.rb b/activeresource/lib/active_resource/formats/json_format.rb
index 9980634921..827d1cc23a 100644
--- a/activeresource/lib/active_resource/formats/json_format.rb
+++ b/activeresource/lib/active_resource/formats/json_format.rb
@@ -18,7 +18,7 @@ module ActiveResource
end
def decode(json)
- ActiveSupport::JSON.decode(json)
+ Formats.remove_root(ActiveSupport::JSON.decode(json))
end
end
end
diff --git a/activeresource/lib/active_resource/formats/xml_format.rb b/activeresource/lib/active_resource/formats/xml_format.rb
index 3b2575cfa1..49cb9aa1ac 100644
--- a/activeresource/lib/active_resource/formats/xml_format.rb
+++ b/activeresource/lib/active_resource/formats/xml_format.rb
@@ -18,19 +18,8 @@ module ActiveResource
end
def decode(xml)
- from_xml_data(Hash.from_xml(xml))
+ Formats.remove_root(Hash.from_xml(xml))
end
-
- private
- # Manipulate from_xml Hash, because xml_simple is not exactly what we
- # want for Active Resource.
- def from_xml_data(data)
- if data.is_a?(Hash) && data.keys.size == 1
- data.values.first
- else
- data
- end
- end
end
end
end
diff --git a/activeresource/lib/active_resource/http_mock.rb b/activeresource/lib/active_resource/http_mock.rb
index 3bfd536b29..e90580be4f 100644
--- a/activeresource/lib/active_resource/http_mock.rb
+++ b/activeresource/lib/active_resource/http_mock.rb
@@ -20,10 +20,10 @@ module ActiveResource
# * <tt>path</tt> - A string, starting with a "/", defining the URI that is expected to be
# called.
# * <tt>request_headers</tt> - Headers that are expected along with the request. This argument uses a
- # hash format, such as <tt>{ "Content-Type" => "application/xml" }</tt>. This mock will only trigger
+ # hash format, such as <tt>{ "Content-Type" => "application/json" }</tt>. This mock will only trigger
# if your tests sends a request with identical headers.
# * <tt>body</tt> - The data to be returned. This should be a string of Active Resource parseable content,
- # such as XML.
+ # such as Json.
# * <tt>status</tt> - The HTTP response code, as an integer, to return with the response.
# * <tt>response_headers</tt> - Headers to be returned with the response. Uses the same hash format as
# <tt>request_headers</tt> listed above.
@@ -35,12 +35,12 @@ module ActiveResource
#
# ==== Example
# def setup
- # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
+ # @matz = { :person => { :id => 1, :name => "Matz" } }.to_json
# ActiveResource::HttpMock.respond_to do |mock|
- # mock.post "/people.xml", {}, @matz, 201, "Location" => "/people/1.xml"
- # mock.get "/people/1.xml", {}, @matz
- # mock.put "/people/1.xml", {}, nil, 204
- # mock.delete "/people/1.xml", {}, nil, 200
+ # mock.post "/people.json", {}, @matz, 201, "Location" => "/people/1.json"
+ # mock.get "/people/1.json", {}, @matz
+ # mock.put "/people/1.json", {}, nil, 204
+ # mock.delete "/people/1.json", {}, nil, 200
# end
# end
#
@@ -85,9 +85,9 @@ module ActiveResource
#
# ==== Example
# def setup
- # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
+ # @matz = { :person => { :id => 1, :name => "Matz" } }.to_json
# ActiveResource::HttpMock.respond_to do |mock|
- # mock.get "/people/1.xml", {}, @matz
+ # mock.get "/people/1.json", {}, @matz
# end
# end
#
@@ -95,7 +95,7 @@ module ActiveResource
# person = Person.find(1) # Call the remote service
#
# # This request object has the same HTTP method and path as declared by the mock
- # expected_request = ActiveResource::Request.new(:get, "/people/1.xml")
+ # expected_request = ActiveResource::Request.new(:get, "/people/1.json")
#
# # Assert that the mock received, and responded to, the expected request from the model
# assert ActiveResource::HttpMock.requests.include?(expected_request)
@@ -117,12 +117,12 @@ module ActiveResource
#
# === Example
#
- # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
+ # @matz = { :person => { :id => 1, :name => "Matz" } }.to_json
# ActiveResource::HttpMock.respond_to do |mock|
- # mock.post "/people.xml", {}, @matz, 201, "Location" => "/people/1.xml"
- # mock.get "/people/1.xml", {}, @matz
- # mock.put "/people/1.xml", {}, nil, 204
- # mock.delete "/people/1.xml", {}, nil, 200
+ # mock.post "/people.json", {}, @matz, 201, "Location" => "/people/1.json"
+ # mock.get "/people/1.json", {}, @matz
+ # mock.put "/people/1.json", {}, nil, 204
+ # mock.delete "/people/1.json", {}, nil, 200
# end
#
# Alternatively, accepts a hash of <tt>{Request => Response}</tt> pairs allowing you to generate
@@ -135,11 +135,11 @@ module ActiveResource
#
# Request.new(:#{method}, path, nil, request_headers)
#
- # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
+ # @matz = { :person => { :id => 1, :name => "Matz" } }.to_json
#
- # create_matz = ActiveResource::Request.new(:post, '/people.xml', @matz, {})
- # created_response = ActiveResource::Response.new("", 201, {"Location" => "/people/1.xml"})
- # get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil)
+ # create_matz = ActiveResource::Request.new(:post, '/people.json', @matz, {})
+ # created_response = ActiveResource::Response.new("", 201, {"Location" => "/people/1.json"})
+ # get_matz = ActiveResource::Request.new(:get, '/people/1.json', nil)
# ok_response = ActiveResource::Response.new("", 200, {})
#
# pairs = {create_matz => created_response, get_matz => ok_response}
@@ -154,12 +154,12 @@ module ActiveResource
# === Example
#
# ActiveResource::HttpMock.respond_to do |mock|
- # mock.send(:get, "/people/1", {}, "XML1")
+ # mock.send(:get, "/people/1", {}, "JSON1")
# end
# ActiveResource::HttpMock.responses.length #=> 1
#
# ActiveResource::HttpMock.respond_to(false) do |mock|
- # mock.send(:get, "/people/2", {}, "XML2")
+ # mock.send(:get, "/people/2", {}, "JSON2")
# end
# ActiveResource::HttpMock.responses.length #=> 2
#
@@ -169,11 +169,11 @@ module ActiveResource
# === Example
#
# ActiveResource::HttpMock.respond_to do |mock|
- # mock.send(:get, "/people/1", {}, "XML1")
+ # mock.send(:get, "/people/1", {}, "JSON1")
# end
# ActiveResource::HttpMock.responses.length #=> 1
#
- # get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil)
+ # get_matz = ActiveResource::Request.new(:get, '/people/1.json', nil)
# ok_response = ActiveResource::Response.new("", 200, {})
#
# pairs = {get_matz => ok_response}
diff --git a/activeresource/test/abstract_unit.rb b/activeresource/test/abstract_unit.rb
index 195f93f2a6..948dd94a1d 100644
--- a/activeresource/test/abstract_unit.rb
+++ b/activeresource/test/abstract_unit.rb
@@ -20,16 +20,19 @@ rescue LoadError
end
def setup_response
- @default_request_headers = { 'Content-Type' => 'application/xml' }
- @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
- @david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
- @greg = { :id => 3, :name => 'Greg' }.to_xml(:root => 'person')
- @addy = { :id => 1, :street => '12345 Street', :country => 'Australia' }.to_xml(:root => 'address')
- @rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person")
- @joe = { 'person' => { :id => 6, :name => 'Joe' }}.to_json
- @people = [{ :id => 1, :name => 'Matz' }, { :id => 2, :name => 'David' }].to_xml(:root => 'people')
- @people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people')
- @addresses = [{ :id => 1, :street => '12345 Street', :country => 'Australia' }].to_xml(:root => 'addresses')
+ matz_hash = { 'person' => { :id => 1, :name => 'Matz' } }
+
+ @default_request_headers = { 'Content-Type' => 'application/json' }
+ @matz = matz_hash.to_json
+ @matz_xml = matz_hash.to_xml
+ @david = { :person => { :id => 2, :name => 'David' } }.to_json
+ @greg = { :person => { :id => 3, :name => 'Greg' } }.to_json
+ @addy = { :address => { :id => 1, :street => '12345 Street', :country => 'Australia' } }.to_json
+ @rick = { :person => { :name => "Rick", :age => 25 } }.to_json
+ @joe = { :person => { :id => 6, :name => 'Joe', :likes_hats => true }}.to_json
+ @people = { :people => [ { :person => { :id => 1, :name => 'Matz' } }, { :person => { :id => 2, :name => 'David' } }] }.to_json
+ @people_david = { :people => [ { :person => { :id => 2, :name => 'David' } }] }.to_json
+ @addresses = { :addresses => [{ :address => { :id => 1, :street => '12345 Street', :country => 'Australia' } }] }.to_json
# - deep nested resource -
# - Luis (Customer)
@@ -48,19 +51,38 @@ def setup_response
# - Natacha (Customer::Friend::Brother::Child)
# - Milena (Customer::Friend::Brother)
#
- @luis = {:id => 1, :name => 'Luis',
- :friends => [{:name => 'JK',
- :brothers => [{:name => 'Mateo',
- :children => [{:name => 'Edith'},{:name => 'Martha'}]},
- {:name => 'Felipe',
- :children => [{:name => 'Bryan'},{:name => 'Luke'}]}]},
- {:name => 'Eduardo',
- :brothers => [{:name => 'Sebas',
- :children => [{:name => 'Andres'},{:name => 'Jorge'}]},
- {:name => 'Elsa',
- :children => [{:name => 'Natacha'}]},
- {:name => 'Milena',
- :children => []}]}]}.to_xml(:root => 'customer')
+ @luis = {
+ :customer => {
+ :id => 1,
+ :name => 'Luis',
+ :friends => [{
+ :name => 'JK',
+ :brothers => [
+ {
+ :name => 'Mateo',
+ :children => [{ :name => 'Edith' },{ :name => 'Martha' }]
+ }, {
+ :name => 'Felipe',
+ :children => [{ :name => 'Bryan' },{ :name => 'Luke' }]
+ }
+ ]
+ }, {
+ :name => 'Eduardo',
+ :brothers => [
+ {
+ :name => 'Sebas',
+ :children => [{ :name => 'Andres' },{ :name => 'Jorge' }]
+ }, {
+ :name => 'Elsa',
+ :children => [{ :name => 'Natacha' }]
+ }, {
+ :name => 'Milena',
+ :children => []
+ }
+ ]
+ }]
+ }
+ }.to_json
# - resource with yaml array of strings; for ARs using serialize :bar, Array
@marty = <<-eof.strip
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
@@ -75,49 +97,52 @@ def setup_response
</person>
eof
- @startup_sound = {
- :name => "Mac Startup Sound", :author => { :name => "Jim Reekes" }
- }.to_xml(:root => 'sound')
+ @startup_sound = {
+ :sound => {
+ :name => "Mac Startup Sound", :author => { :name => "Jim Reekes" }
+ }
+ }.to_json
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1.xml", {}, @matz
+ mock.get "/people/1.json", {}, @matz
+ mock.get "/people/1.xml", {}, @matz_xml
mock.get "/people/2.xml", {}, @david
mock.get "/people/5.xml", {}, @marty
- mock.get "/people/Greg.xml", {}, @greg
+ mock.get "/people/Greg.json", {}, @greg
mock.get "/people/6.json", {}, @joe
- mock.get "/people/4.xml", {'key' => 'value'}, nil, 404
- mock.put "/people/1.xml", {}, nil, 204
- mock.delete "/people/1.xml", {}, nil, 200
+ mock.get "/people/4.json", { 'key' => 'value' }, nil, 404
+ mock.put "/people/1.json", {}, nil, 204
+ mock.delete "/people/1.json", {}, nil, 200
mock.delete "/people/2.xml", {}, nil, 400
- mock.get "/people/99.xml", {}, nil, 404
- mock.post "/people.xml", {}, @rick, 201, 'Location' => '/people/5.xml'
- mock.get "/people.xml", {}, @people
- mock.get "/people/1/addresses.xml", {}, @addresses
- mock.get "/people/1/addresses/1.xml", {}, @addy
+ mock.get "/people/99.json", {}, nil, 404
+ mock.post "/people.json", {}, @rick, 201, 'Location' => '/people/5.xml'
+ mock.get "/people.json", {}, @people
+ mock.get "/people/1/addresses.json", {}, @addresses
+ mock.get "/people/1/addresses/1.json", {}, @addy
mock.get "/people/1/addresses/2.xml", {}, nil, 404
- mock.get "/people/2/addresses.xml", {}, nil, 404
+ mock.get "/people/2/addresses.json", {}, nil, 404
mock.get "/people/2/addresses/1.xml", {}, nil, 404
- mock.get "/people/Greg/addresses/1.xml", {}, @addy
- mock.put "/people/1/addresses/1.xml", {}, nil, 204
- mock.delete "/people/1/addresses/1.xml", {}, nil, 200
- mock.post "/people/1/addresses.xml", {}, nil, 201, 'Location' => '/people/1/addresses/5'
- mock.get "/people/1/addresses/99.xml", {}, nil, 404
+ mock.get "/people/Greg/addresses/1.json", {}, @addy
+ mock.put "/people/1/addresses/1.json", {}, nil, 204
+ mock.delete "/people/1/addresses/1.json", {}, nil, 200
+ mock.post "/people/1/addresses.json", {}, nil, 201, 'Location' => '/people/1/addresses/5'
+ mock.get "/people/1/addresses/99.json", {}, nil, 404
mock.get "/people//addresses.xml", {}, nil, 404
mock.get "/people//addresses/1.xml", {}, nil, 404
mock.put "/people//addresses/1.xml", {}, nil, 404
mock.delete "/people//addresses/1.xml", {}, nil, 404
mock.post "/people//addresses.xml", {}, nil, 404
- mock.head "/people/1.xml", {}, nil, 200
- mock.head "/people/Greg.xml", {}, nil, 200
- mock.head "/people/99.xml", {}, nil, 404
- mock.head "/people/1/addresses/1.xml", {}, nil, 200
- mock.head "/people/1/addresses/2.xml", {}, nil, 404
- mock.head "/people/2/addresses/1.xml", {}, nil, 404
- mock.head "/people/Greg/addresses/1.xml", {}, nil, 200
+ mock.head "/people/1.json", {}, nil, 200
+ mock.head "/people/Greg.json", {}, nil, 200
+ mock.head "/people/99.json", {}, nil, 404
+ mock.head "/people/1/addresses/1.json", {}, nil, 200
+ mock.head "/people/1/addresses/2.json", {}, nil, 404
+ mock.head "/people/2/addresses/1.json", {}, nil, 404
+ mock.head "/people/Greg/addresses/1.json", {}, nil, 200
# customer
- mock.get "/customers/1.xml", {}, @luis
+ mock.get "/customers/1.json", {}, @luis
# sound
- mock.get "/sounds/1.xml", {}, @startup_sound
+ mock.get "/sounds/1.json", {}, @startup_sound
end
Person.user = nil
diff --git a/activeresource/test/cases/authorization_test.rb b/activeresource/test/cases/authorization_test.rb
index a6797643e1..69ef9a2821 100644
--- a/activeresource/test/cases/authorization_test.rb
+++ b/activeresource/test/cases/authorization_test.rb
@@ -5,36 +5,36 @@ class AuthorizationTest < Test::Unit::TestCase
def setup
@conn = ActiveResource::Connection.new('http://localhost')
- @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
- @david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
+ @matz = { :person => { :id => 1, :name => 'Matz' } }.to_json
+ @david = { :person => { :id => 2, :name => 'David' } }.to_json
@authenticated_conn = ActiveResource::Connection.new("http://david:test123@localhost")
@basic_authorization_request_header = { 'Authorization' => 'Basic ZGF2aWQ6dGVzdDEyMw==' }
@nonce = "MTI0OTUxMzc4NzpjYWI3NDM3NDNmY2JmODU4ZjQ2ZjcwNGZkMTJiMjE0NA=="
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/2.xml", @basic_authorization_request_header, @david
- mock.get "/people/1.xml", @basic_authorization_request_header, nil, 401, { 'WWW-Authenticate' => 'i_should_be_ignored' }
- mock.put "/people/2.xml", @basic_authorization_request_header, nil, 204
- mock.delete "/people/2.xml", @basic_authorization_request_header, nil, 200
- mock.post "/people/2/addresses.xml", @basic_authorization_request_header, nil, 201, 'Location' => '/people/1/addresses/5'
- mock.head "/people/2.xml", @basic_authorization_request_header, nil, 200
+ mock.get "/people/2.json", @basic_authorization_request_header, @david
+ mock.get "/people/1.json", @basic_authorization_request_header, nil, 401, { 'WWW-Authenticate' => 'i_should_be_ignored' }
+ mock.put "/people/2.json", @basic_authorization_request_header, nil, 204
+ mock.delete "/people/2.json", @basic_authorization_request_header, nil, 200
+ mock.post "/people/2/addresses.json", @basic_authorization_request_header, nil, 201, 'Location' => '/people/1/addresses/5'
+ mock.head "/people/2.json", @basic_authorization_request_header, nil, 200
- mock.get "/people/2.xml", { 'Authorization' => blank_digest_auth_header("/people/2.xml", "a10c9bd131c9d4d7755b8f4706fd04af") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
- mock.get "/people/2.xml", { 'Authorization' => request_digest_auth_header("/people/2.xml", "912c7a643f18cda562b8d9662c47b6f5") }, @david, 200
- mock.get "/people/1.xml", { 'Authorization' => request_digest_auth_header("/people/1.xml", "d76e675c0ecfa2bb1abe01491b068a06") }, @matz, 200
+ mock.get "/people/2.json", { 'Authorization' => blank_digest_auth_header("/people/2.json", "fad396f6a34aeba28e28b9b96ddbb671") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
+ mock.get "/people/2.json", { 'Authorization' => request_digest_auth_header("/people/2.json", "c064d5ba8891a25290c76c8c7d31fb7b") }, @david, 200
+ mock.get "/people/1.json", { 'Authorization' => request_digest_auth_header("/people/1.json", "f9c0b594257bb8422af4abd429c5bb70") }, @matz, 200
- mock.put "/people/2.xml", { 'Authorization' => blank_digest_auth_header("/people/2.xml", "7de8a265a5be3c4c2d3a246562ecd6bd") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
- mock.put "/people/2.xml", { 'Authorization' => request_digest_auth_header("/people/2.xml", "3fb3b33d9d0b869cc75815aa11faacd9") }, nil, 204
+ mock.put "/people/2.json", { 'Authorization' => blank_digest_auth_header("/people/2.json", "50a685d814f94665b9d160fbbaa3958a") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
+ mock.put "/people/2.json", { 'Authorization' => request_digest_auth_header("/people/2.json", "5a75cde841122d8e0f20f8fd1f98a743") }, nil, 204
- mock.delete "/people/2.xml", { 'Authorization' => blank_digest_auth_header("/people/2.xml", "07dfc32769a34ea3510d3a77d64ca495") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
- mock.delete "/people/2.xml", { 'Authorization' => request_digest_auth_header("/people/2.xml", "5d438610de7ec163b29096c9afcbb254") }, nil, 200
+ mock.delete "/people/2.json", { 'Authorization' => blank_digest_auth_header("/people/2.json", "846f799107eab5ca4285b909ee299a33") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
+ mock.delete "/people/2.json", { 'Authorization' => request_digest_auth_header("/people/2.json", "9f5b155224edbbb69fd99d8ce094681e") }, nil, 200
- mock.post "/people/2/addresses.xml", { 'Authorization' => blank_digest_auth_header("/people/2/addresses.xml", "966dab13620421f928d051f2b9d7b9af") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
- mock.post "/people/2/addresses.xml", { 'Authorization' => request_digest_auth_header("/people/2/addresses.xml", "ed540d032c63f8ee34959116c090ec45") }, nil, 201, 'Location' => '/people/1/addresses/5'
+ mock.post "/people/2/addresses.json", { 'Authorization' => blank_digest_auth_header("/people/2/addresses.json", "6984d405ff3d9ed07bbf747dcf16afb0") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
+ mock.post "/people/2/addresses.json", { 'Authorization' => request_digest_auth_header("/people/2/addresses.json", "4bda6a28dbf930b5af9244073623bd04") }, nil, 201, 'Location' => '/people/1/addresses/5'
- mock.head "/people/2.xml", { 'Authorization' => blank_digest_auth_header("/people/2.xml", "2854eeb92cce2aed29350ea0ce7ba1e2") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
- mock.head "/people/2.xml", { 'Authorization' => request_digest_auth_header("/people/2.xml", "07cd4d247e9c130f92ba2501a080b328") }, nil, 200
+ mock.head "/people/2.json", { 'Authorization' => blank_digest_auth_header("/people/2.json", "15e5ed84ba5c4cfcd5c98a36c2e4f421") }, nil, 401, { 'WWW-Authenticate' => response_digest_auth_header }
+ mock.head "/people/2.json", { 'Authorization' => request_digest_auth_header("/people/2.json", "d4c6d2bcc8717abb2e2ccb8c49ee6a91") }, nil, 200
end
# Make client nonce deterministic
@@ -48,7 +48,7 @@ class AuthorizationTest < Test::Unit::TestCase
end
def test_authorization_header
- authorization_header = @authenticated_conn.__send__(:authorization_header, :get, URI.parse('/people/2.xml'))
+ authorization_header = @authenticated_conn.__send__(:authorization_header, :get, URI.parse('/people/2.json'))
assert_equal @basic_authorization_request_header['Authorization'], authorization_header['Authorization']
authorization = authorization_header["Authorization"].to_s.split
@@ -58,7 +58,7 @@ class AuthorizationTest < Test::Unit::TestCase
def test_authorization_header_with_username_but_no_password
@conn = ActiveResource::Connection.new("http://david:@localhost")
- authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.xml'))
+ authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.json'))
authorization = authorization_header["Authorization"].to_s.split
assert_equal "Basic", authorization[0]
@@ -67,7 +67,7 @@ class AuthorizationTest < Test::Unit::TestCase
def test_authorization_header_with_password_but_no_username
@conn = ActiveResource::Connection.new("http://:test123@localhost")
- authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.xml'))
+ authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.json'))
authorization = authorization_header["Authorization"].to_s.split
assert_equal "Basic", authorization[0]
@@ -76,7 +76,7 @@ class AuthorizationTest < Test::Unit::TestCase
def test_authorization_header_with_decoded_credentials_from_url
@conn = ActiveResource::Connection.new("http://my%40email.com:%31%32%33@localhost")
- authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.xml'))
+ authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.json'))
authorization = authorization_header["Authorization"].to_s.split
assert_equal "Basic", authorization[0]
@@ -87,7 +87,7 @@ class AuthorizationTest < Test::Unit::TestCase
@authenticated_conn = ActiveResource::Connection.new("http://@localhost")
@authenticated_conn.user = 'david'
@authenticated_conn.password = 'test123'
- authorization_header = @authenticated_conn.__send__(:authorization_header, :get, URI.parse('/people/2.xml'))
+ authorization_header = @authenticated_conn.__send__(:authorization_header, :get, URI.parse('/people/2.json'))
assert_equal @basic_authorization_request_header['Authorization'], authorization_header['Authorization']
authorization = authorization_header["Authorization"].to_s.split
@@ -98,7 +98,7 @@ class AuthorizationTest < Test::Unit::TestCase
def test_authorization_header_explicitly_setting_username_but_no_password
@conn = ActiveResource::Connection.new("http://@localhost")
@conn.user = "david"
- authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.xml'))
+ authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.json'))
authorization = authorization_header["Authorization"].to_s.split
assert_equal "Basic", authorization[0]
@@ -108,7 +108,7 @@ class AuthorizationTest < Test::Unit::TestCase
def test_authorization_header_explicitly_setting_password_but_no_username
@conn = ActiveResource::Connection.new("http://@localhost")
@conn.password = "test123"
- authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.xml'))
+ authorization_header = @conn.__send__(:authorization_header, :get, URI.parse('/people/2.json'))
authorization = authorization_header["Authorization"].to_s.split
assert_equal "Basic", authorization[0]
@@ -117,7 +117,7 @@ class AuthorizationTest < Test::Unit::TestCase
def test_authorization_header_if_credentials_supplied_and_auth_type_is_basic
@authenticated_conn.auth_type = :basic
- authorization_header = @authenticated_conn.__send__(:authorization_header, :get, URI.parse('/people/2.xml'))
+ authorization_header = @authenticated_conn.__send__(:authorization_header, :get, URI.parse('/people/2.json'))
assert_equal @basic_authorization_request_header['Authorization'], authorization_header['Authorization']
authorization = authorization_header["Authorization"].to_s.split
@@ -127,96 +127,96 @@ class AuthorizationTest < Test::Unit::TestCase
def test_authorization_header_if_credentials_supplied_and_auth_type_is_digest
@authenticated_conn.auth_type = :digest
- authorization_header = @authenticated_conn.__send__(:authorization_header, :get, URI.parse('/people/2.xml'))
- assert_equal blank_digest_auth_header("/people/2.xml", "a10c9bd131c9d4d7755b8f4706fd04af"), authorization_header['Authorization']
+ authorization_header = @authenticated_conn.__send__(:authorization_header, :get, URI.parse('/people/2.json'))
+ assert_equal blank_digest_auth_header("/people/2.json", "fad396f6a34aeba28e28b9b96ddbb671"), authorization_header['Authorization']
end
def test_get
- david = decode(@authenticated_conn.get("/people/2.xml"))
+ david = decode(@authenticated_conn.get("/people/2.json"))
assert_equal "David", david["name"]
end
def test_post
- response = @authenticated_conn.post("/people/2/addresses.xml")
+ response = @authenticated_conn.post("/people/2/addresses.json")
assert_equal "/people/1/addresses/5", response["Location"]
end
def test_put
- response = @authenticated_conn.put("/people/2.xml")
+ response = @authenticated_conn.put("/people/2.json")
assert_equal 204, response.code
end
def test_delete
- response = @authenticated_conn.delete("/people/2.xml")
+ response = @authenticated_conn.delete("/people/2.json")
assert_equal 200, response.code
end
def test_head
- response = @authenticated_conn.head("/people/2.xml")
+ response = @authenticated_conn.head("/people/2.json")
assert_equal 200, response.code
end
def test_get_with_digest_auth_handles_initial_401_response_and_retries
@authenticated_conn.auth_type = :digest
- response = @authenticated_conn.get("/people/2.xml")
+ response = @authenticated_conn.get("/people/2.json")
assert_equal "David", decode(response)["name"]
end
def test_post_with_digest_auth_handles_initial_401_response_and_retries
@authenticated_conn.auth_type = :digest
- response = @authenticated_conn.post("/people/2/addresses.xml")
+ response = @authenticated_conn.post("/people/2/addresses.json")
assert_equal "/people/1/addresses/5", response["Location"]
assert_equal 201, response.code
end
def test_put_with_digest_auth_handles_initial_401_response_and_retries
@authenticated_conn.auth_type = :digest
- response = @authenticated_conn.put("/people/2.xml")
+ response = @authenticated_conn.put("/people/2.json")
assert_equal 204, response.code
end
def test_delete_with_digest_auth_handles_initial_401_response_and_retries
@authenticated_conn.auth_type = :digest
- response = @authenticated_conn.delete("/people/2.xml")
+ response = @authenticated_conn.delete("/people/2.json")
assert_equal 200, response.code
end
def test_head_with_digest_auth_handles_initial_401_response_and_retries
@authenticated_conn.auth_type = :digest
- response = @authenticated_conn.head("/people/2.xml")
+ response = @authenticated_conn.head("/people/2.json")
assert_equal 200, response.code
end
def test_get_with_digest_auth_caches_nonce
@authenticated_conn.auth_type = :digest
- response = @authenticated_conn.get("/people/2.xml")
+ response = @authenticated_conn.get("/people/2.json")
assert_equal "David", decode(response)["name"]
# There is no mock for this request with a non-cached nonce.
- response = @authenticated_conn.get("/people/1.xml")
+ response = @authenticated_conn.get("/people/1.json")
assert_equal "Matz", decode(response)["name"]
end
def test_retry_on_401_only_happens_with_digest_auth
- assert_raise(ActiveResource::UnauthorizedAccess) { @authenticated_conn.get("/people/1.xml") }
+ assert_raise(ActiveResource::UnauthorizedAccess) { @authenticated_conn.get("/people/1.json") }
assert_equal "", @authenticated_conn.send(:response_auth_header)
end
def test_raises_invalid_request_on_unauthorized_requests
- assert_raise(ActiveResource::InvalidRequestError) { @conn.get("/people/2.xml") }
- assert_raise(ActiveResource::InvalidRequestError) { @conn.post("/people/2/addresses.xml") }
- assert_raise(ActiveResource::InvalidRequestError) { @conn.put("/people/2.xml") }
- assert_raise(ActiveResource::InvalidRequestError) { @conn.delete("/people/2.xml") }
- assert_raise(ActiveResource::InvalidRequestError) { @conn.head("/people/2.xml") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.get("/people/2.json") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.post("/people/2/addresses.json") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.put("/people/2.json") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.delete("/people/2.json") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.head("/people/2.json") }
end
def test_raises_invalid_request_on_unauthorized_requests_with_digest_auth
@conn.auth_type = :digest
- assert_raise(ActiveResource::InvalidRequestError) { @conn.get("/people/2.xml") }
- assert_raise(ActiveResource::InvalidRequestError) { @conn.post("/people/2/addresses.xml") }
- assert_raise(ActiveResource::InvalidRequestError) { @conn.put("/people/2.xml") }
- assert_raise(ActiveResource::InvalidRequestError) { @conn.delete("/people/2.xml") }
- assert_raise(ActiveResource::InvalidRequestError) { @conn.head("/people/2.xml") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.get("/people/2.json") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.post("/people/2/addresses.json") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.put("/people/2.json") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.delete("/people/2.json") }
+ assert_raise(ActiveResource::InvalidRequestError) { @conn.head("/people/2.json") }
end
def test_client_nonce_is_not_nil
diff --git a/activeresource/test/cases/base/custom_methods_test.rb b/activeresource/test/cases/base/custom_methods_test.rb
index 0fbf94bc0e..3eaa9b1c5b 100644
--- a/activeresource/test/cases/base/custom_methods_test.rb
+++ b/activeresource/test/cases/base/custom_methods_test.rb
@@ -5,32 +5,32 @@ require 'active_support/core_ext/hash/conversions'
class CustomMethodsTest < Test::Unit::TestCase
def setup
- @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
- @matz_deep = { :id => 1, :name => 'Matz', :other => 'other' }.to_xml(:root => 'person')
- @matz_array = [{ :id => 1, :name => 'Matz' }].to_xml(:root => 'people')
- @ryan = { :name => 'Ryan' }.to_xml(:root => 'person')
- @addy = { :id => 1, :street => '12345 Street' }.to_xml(:root => 'address')
- @addy_deep = { :id => 1, :street => '12345 Street', :zip => "27519" }.to_xml(:root => 'address')
+ @matz = { :person => { :id => 1, :name => 'Matz' } }.to_json
+ @matz_deep = { :person => { :id => 1, :name => 'Matz', :other => 'other' } }.to_json
+ @matz_array = { :people => [{ :person => { :id => 1, :name => 'Matz' } }] }.to_json
+ @ryan = { :person => { :name => 'Ryan' } }.to_json
+ @addy = { :address => { :id => 1, :street => '12345 Street' } }.to_json
+ @addy_deep = { :address => { :id => 1, :street => '12345 Street', :zip => "27519" } }.to_json
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1.xml", {}, @matz
- mock.get "/people/1/shallow.xml", {}, @matz
- mock.get "/people/1/deep.xml", {}, @matz_deep
- mock.get "/people/retrieve.xml?name=Matz", {}, @matz_array
- mock.get "/people/managers.xml", {}, @matz_array
- mock.post "/people/hire.xml?name=Matz", {}, nil, 201
- mock.put "/people/1/promote.xml?position=Manager", {}, nil, 204
- mock.put "/people/promote.xml?name=Matz", {}, nil, 204, {}
- mock.put "/people/sort.xml?by=name", {}, nil, 204
- mock.delete "/people/deactivate.xml?name=Matz", {}, nil, 200
- mock.delete "/people/1/deactivate.xml", {}, nil, 200
- mock.post "/people/new/register.xml", {}, @ryan, 201, 'Location' => '/people/5.xml'
- mock.post "/people/1/register.xml", {}, @matz, 201
- mock.get "/people/1/addresses/1.xml", {}, @addy
- mock.get "/people/1/addresses/1/deep.xml", {}, @addy_deep
- mock.put "/people/1/addresses/1/normalize_phone.xml?locale=US", {}, nil, 204
- mock.put "/people/1/addresses/sort.xml?by=name", {}, nil, 204
- mock.post "/people/1/addresses/new/link.xml", {}, { :street => '12345 Street' }.to_xml(:root => 'address'), 201, 'Location' => '/people/1/addresses/2.xml'
+ mock.get "/people/1.json", {}, @matz
+ mock.get "/people/1/shallow.json", {}, @matz
+ mock.get "/people/1/deep.json", {}, @matz_deep
+ mock.get "/people/retrieve.json?name=Matz", {}, @matz_array
+ mock.get "/people/managers.json", {}, @matz_array
+ mock.post "/people/hire.json?name=Matz", {}, nil, 201
+ mock.put "/people/1/promote.json?position=Manager", {}, nil, 204
+ mock.put "/people/promote.json?name=Matz", {}, nil, 204, {}
+ mock.put "/people/sort.json?by=name", {}, nil, 204
+ mock.delete "/people/deactivate.json?name=Matz", {}, nil, 200
+ mock.delete "/people/1/deactivate.json", {}, nil, 200
+ mock.post "/people/new/register.json", {}, @ryan, 201, 'Location' => '/people/5.json'
+ mock.post "/people/1/register.json", {}, @matz, 201
+ mock.get "/people/1/addresses/1.json", {}, @addy
+ mock.get "/people/1/addresses/1/deep.json", {}, @addy_deep
+ mock.put "/people/1/addresses/1/normalize_phone.json?locale=US", {}, nil, 204
+ mock.put "/people/1/addresses/sort.json?by=name", {}, nil, 204
+ mock.post "/people/1/addresses/new/link.json", {}, { :address => { :street => '12345 Street' } }.to_json, 201, 'Location' => '/people/1/addresses/2.json'
end
Person.user = nil
@@ -81,14 +81,14 @@ class CustomMethodsTest < Test::Unit::TestCase
def test_custom_new_element_method
# Test POST against a new element URL
ryan = Person.new(:name => 'Ryan')
- assert_equal ActiveResource::Response.new(@ryan, 201, {'Location' => '/people/5.xml'}), ryan.post(:register)
- expected_request = ActiveResource::Request.new(:post, '/people/new/register.xml', @ryan)
+ assert_equal ActiveResource::Response.new(@ryan, 201, { 'Location' => '/people/5.json' }), ryan.post(:register)
+ expected_request = ActiveResource::Request.new(:post, '/people/new/register.json', @ryan)
assert_equal expected_request.body, ActiveResource::HttpMock.requests.first.body
# Test POST against a nested collection URL
addy = StreetAddress.new(:street => '123 Test Dr.', :person_id => 1)
- assert_equal ActiveResource::Response.new({ :street => '12345 Street' }.to_xml(:root => 'address'),
- 201, {'Location' => '/people/1/addresses/2.xml'}),
+ assert_equal ActiveResource::Response.new({ :address => { :street => '12345 Street' } }.to_json,
+ 201, { 'Location' => '/people/1/addresses/2.json' }),
addy.post(:link)
matz = Person.find(1)
diff --git a/activeresource/test/cases/base/load_test.rb b/activeresource/test/cases/base/load_test.rb
index 228dc36d9b..d6b04cfaa8 100644
--- a/activeresource/test/cases/base/load_test.rb
+++ b/activeresource/test/cases/base/load_test.rb
@@ -36,10 +36,10 @@ class BaseLoadTest < Test::Unit::TestCase
def setup
@matz = { :id => 1, :name => 'Matz' }
- @first_address = { :id => 1, :street => '12345 Street' }
- @addresses = [@first_address, { :id => 2, :street => '67890 Street' }]
- @addresses_from_xml = { :street_addresses => @addresses }
- @addresses_from_xml_single = { :street_addresses => [ @first_address ] }
+ @first_address = { :address => { :id => 1, :street => '12345 Street' } }
+ @addresses = [@first_address, { :address => { :id => 2, :street => '67890 Street' } }]
+ @addresses_from_json = { :street_addresses => @addresses }
+ @addresses_from_json_single = { :street_addresses => [ @first_address ] }
@deep = { :id => 1, :street => {
:id => 1, :state => { :id => 1, :name => 'Oregon',
@@ -72,28 +72,29 @@ class BaseLoadTest < Test::Unit::TestCase
def test_after_load_attributes_are_accessible_via_indifferent_access
assert_equal Hash.new, @person.attributes
+ matz_attributes = @matz.values.first
assert_equal @matz.stringify_keys, @person.load(@matz).attributes
assert_equal @matz[:name], @person.attributes['name']
assert_equal @matz[:name], @person.attributes[:name]
end
def test_load_one_with_existing_resource
- address = @person.load(:street_address => @first_address).street_address
+ address = @person.load(:street_address => @first_address.values.first).street_address
assert_kind_of StreetAddress, address
- assert_equal @first_address.stringify_keys, address.attributes
+ assert_equal @first_address.values.first.stringify_keys, address.attributes
end
def test_load_one_with_unknown_resource
- address = silence_warnings { @person.load(:address => @first_address).address }
+ address = silence_warnings { @person.load(@first_address).address }
assert_kind_of Person::Address, address
- assert_equal @first_address.stringify_keys, address.attributes
+ assert_equal @first_address.values.first.stringify_keys, address.attributes
end
def test_load_collection_with_existing_resource
- addresses = @person.load(@addresses_from_xml).street_addresses
+ addresses = @person.load(@addresses_from_json).street_addresses
assert_kind_of Array, addresses
addresses.each { |address| assert_kind_of StreetAddress, address }
- assert_equal @addresses.map(&:stringify_keys), addresses.map(&:attributes)
+ assert_equal @addresses.map { |a| a[:address].stringify_keys }, addresses.map(&:attributes)
end
def test_load_collection_with_unknown_resource
@@ -102,14 +103,14 @@ class BaseLoadTest < Test::Unit::TestCase
addresses = silence_warnings { @person.load(:addresses => @addresses).addresses }
assert Person.const_defined?(:Address), "Address should have been autocreated"
addresses.each { |address| assert_kind_of Person::Address, address }
- assert_equal @addresses.map(&:stringify_keys), addresses.map(&:attributes)
+ assert_equal @addresses.map { |a| a[:address].stringify_keys }, addresses.map(&:attributes)
end
def test_load_collection_with_single_existing_resource
- addresses = @person.load(@addresses_from_xml_single).street_addresses
+ addresses = @person.load(@addresses_from_json_single).street_addresses
assert_kind_of Array, addresses
addresses.each { |address| assert_kind_of StreetAddress, address }
- assert_equal [ @first_address ].map(&:stringify_keys), addresses.map(&:attributes)
+ assert_equal [ @first_address.values.first ].map(&:stringify_keys), addresses.map(&:attributes)
end
def test_load_collection_with_single_unknown_resource
@@ -118,7 +119,7 @@ class BaseLoadTest < Test::Unit::TestCase
addresses = silence_warnings { @person.load(:addresses => [ @first_address ]).addresses }
assert Person.const_defined?(:Address), "Address should have been autocreated"
addresses.each { |address| assert_kind_of Person::Address, address }
- assert_equal [ @first_address ].map(&:stringify_keys), addresses.map(&:attributes)
+ assert_equal [ @first_address.values.first ].map(&:stringify_keys), addresses.map(&:attributes)
end
def test_recursively_loaded_collections
@@ -164,7 +165,7 @@ class BaseLoadTest < Test::Unit::TestCase
end
def test_nested_collections_within_the_same_namespace
- n = Highrise::Note.new(:comments => [{ :name => "1" }])
+ n = Highrise::Note.new(:comments => [{ :comment => { :name => "1" } }])
assert_kind_of Highrise::Comment, n.comments.first
end
diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
index 37f30e4353..48fdeb13df 100644
--- a/activeresource/test/cases/base/schema_test.rb
+++ b/activeresource/test/cases/base/schema_test.rb
@@ -118,7 +118,7 @@ class SchemaTest < ActiveModel::TestCase
test "with two instances, default schema should match the attributes of the individual instances - even if they differ" do
matz = Person.find(1)
- rick = Person.find(5)
+ rick = Person.find(6)
m_attrs = matz.attributes.keys.sort
r_attrs = rick.attributes.keys.sort
@@ -376,7 +376,7 @@ class SchemaTest < ActiveModel::TestCase
test "with two instances, known attributes should match the attributes of the individual instances - even if they differ" do
matz = Person.find(1)
- rick = Person.find(5)
+ rick = Person.find(6)
m_attrs = matz.attributes.keys.sort
r_attrs = rick.attributes.keys.sort
diff --git a/activeresource/test/cases/base_test.rb b/activeresource/test/cases/base_test.rb
index 48dacbdf67..f45652d988 100644
--- a/activeresource/test/cases/base_test.rb
+++ b/activeresource/test/cases/base_test.rb
@@ -448,31 +448,31 @@ class BaseTest < Test::Unit::TestCase
end
def test_collection_path
- assert_equal '/people.xml', Person.collection_path
+ assert_equal '/people.json', Person.collection_path
end
def test_collection_path_with_parameters
- assert_equal '/people.xml?gender=male', Person.collection_path(:gender => 'male')
- assert_equal '/people.xml?gender=false', Person.collection_path(:gender => false)
- assert_equal '/people.xml?gender=', Person.collection_path(:gender => nil)
+ assert_equal '/people.json?gender=male', Person.collection_path(:gender => 'male')
+ assert_equal '/people.json?gender=false', Person.collection_path(:gender => false)
+ assert_equal '/people.json?gender=', Person.collection_path(:gender => nil)
- assert_equal '/people.xml?gender=male', Person.collection_path('gender' => 'male')
+ assert_equal '/people.json?gender=male', Person.collection_path('gender' => 'male')
# Use includes? because ordering of param hash is not guaranteed
- assert Person.collection_path(:gender => 'male', :student => true).include?('/people.xml?')
+ assert Person.collection_path(:gender => 'male', :student => true).include?('/people.json?')
assert Person.collection_path(:gender => 'male', :student => true).include?('gender=male')
assert Person.collection_path(:gender => 'male', :student => true).include?('student=true')
- assert_equal '/people.xml?name%5B%5D=bob&name%5B%5D=your+uncle%2Bme&name%5B%5D=&name%5B%5D=false', Person.collection_path(:name => ['bob', 'your uncle+me', nil, false])
+ assert_equal '/people.json?name%5B%5D=bob&name%5B%5D=your+uncle%2Bme&name%5B%5D=&name%5B%5D=false', Person.collection_path(:name => ['bob', 'your uncle+me', nil, false])
- assert_equal '/people.xml?struct%5Ba%5D%5B%5D=2&struct%5Ba%5D%5B%5D=1&struct%5Bb%5D=fred', Person.collection_path(:struct => ActiveSupport::OrderedHash[:a, [2,1], 'b', 'fred'])
+ assert_equal '/people.json?struct%5Ba%5D%5B%5D=2&struct%5Ba%5D%5B%5D=1&struct%5Bb%5D=fred', Person.collection_path(:struct => ActiveSupport::OrderedHash[:a, [2,1], 'b', 'fred'])
end
def test_custom_element_path
- assert_equal '/people/1/addresses/1.xml', StreetAddress.element_path(1, :person_id => 1)
- assert_equal '/people/1/addresses/1.xml', StreetAddress.element_path(1, 'person_id' => 1)
- assert_equal '/people/Greg/addresses/1.xml', StreetAddress.element_path(1, 'person_id' => 'Greg')
- assert_equal '/people/ann%20mary/addresses/ann%20mary.xml', StreetAddress.element_path(:'ann mary', 'person_id' => 'ann mary')
+ assert_equal '/people/1/addresses/1.json', StreetAddress.element_path(1, :person_id => 1)
+ assert_equal '/people/1/addresses/1.json', StreetAddress.element_path(1, 'person_id' => 1)
+ assert_equal '/people/Greg/addresses/1.json', StreetAddress.element_path(1, 'person_id' => 'Greg')
+ assert_equal '/people/ann%20mary/addresses/ann%20mary.json', StreetAddress.element_path(:'ann mary', 'person_id' => 'ann mary')
end
def test_custom_element_path_without_required_prefix_param
@@ -482,7 +482,7 @@ class BaseTest < Test::Unit::TestCase
end
def test_module_element_path
- assert_equal '/sounds/1.xml', Asset::Sound.element_path(1)
+ assert_equal '/sounds/1.json', Asset::Sound.element_path(1)
end
def test_custom_element_path_with_redefined_to_param
@@ -494,10 +494,10 @@ class BaseTest < Test::Unit::TestCase
end
# Class method.
- assert_equal '/people/Greg.xml', Person.element_path('Greg')
+ assert_equal '/people/Greg.json', Person.element_path('Greg')
# Protected Instance method.
- assert_equal '/people/Greg.xml', Person.find('Greg').send(:element_path)
+ assert_equal '/people/Greg.json', Person.find('Greg').send(:element_path)
ensure
# revert back to original
@@ -509,14 +509,14 @@ class BaseTest < Test::Unit::TestCase
end
def test_custom_element_path_with_parameters
- assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, :person_id => 1, :type => 'work')
- assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, 'person_id' => 1, :type => 'work')
- assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, :type => 'work', :person_id => 1)
- assert_equal '/people/1/addresses/1.xml?type%5B%5D=work&type%5B%5D=play+time', StreetAddress.element_path(1, :person_id => 1, :type => ['work', 'play time'])
+ assert_equal '/people/1/addresses/1.json?type=work', StreetAddress.element_path(1, :person_id => 1, :type => 'work')
+ assert_equal '/people/1/addresses/1.json?type=work', StreetAddress.element_path(1, 'person_id' => 1, :type => 'work')
+ assert_equal '/people/1/addresses/1.json?type=work', StreetAddress.element_path(1, :type => 'work', :person_id => 1)
+ assert_equal '/people/1/addresses/1.json?type%5B%5D=work&type%5B%5D=play+time', StreetAddress.element_path(1, :person_id => 1, :type => ['work', 'play time'])
end
def test_custom_element_path_with_prefix_and_parameters
- assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, {:person_id => 1}, {:type => 'work'})
+ assert_equal '/people/1/addresses/1.json?type=work', StreetAddress.element_path(1, {:person_id => 1}, {:type => 'work'})
end
def test_custom_collection_path_without_required_prefix_param
@@ -526,17 +526,17 @@ class BaseTest < Test::Unit::TestCase
end
def test_custom_collection_path
- assert_equal '/people/1/addresses.xml', StreetAddress.collection_path(:person_id => 1)
- assert_equal '/people/1/addresses.xml', StreetAddress.collection_path('person_id' => 1)
+ assert_equal '/people/1/addresses.json', StreetAddress.collection_path(:person_id => 1)
+ assert_equal '/people/1/addresses.json', StreetAddress.collection_path('person_id' => 1)
end
def test_custom_collection_path_with_parameters
- assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path(:person_id => 1, :type => 'work')
- assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path('person_id' => 1, :type => 'work')
+ assert_equal '/people/1/addresses.json?type=work', StreetAddress.collection_path(:person_id => 1, :type => 'work')
+ assert_equal '/people/1/addresses.json?type=work', StreetAddress.collection_path('person_id' => 1, :type => 'work')
end
def test_custom_collection_path_with_prefix_and_parameters
- assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path({:person_id => 1}, {:type => 'work'})
+ assert_equal '/people/1/addresses.json?type=work', StreetAddress.collection_path({:person_id => 1}, {:type => 'work'})
end
def test_custom_element_name
@@ -626,7 +626,7 @@ class BaseTest < Test::Unit::TestCase
resp = {'Location' => '/foo/bar/1'}
assert_equal '1', p.__send__(:id_from_response, resp)
- resp['Location'] << '.xml'
+ resp['Location'] << '.json'
assert_equal '1', p.__send__(:id_from_response, resp)
end
@@ -698,14 +698,14 @@ class BaseTest < Test::Unit::TestCase
# Test that save exceptions get bubbled up too
ActiveResource::HttpMock.respond_to do |mock|
- mock.post "/people.xml", {}, nil, 409
+ mock.post "/people.json", {}, nil, 409
end
assert_raise(ActiveResource::ResourceConflict) { Person.create(:name => 'Rick') }
end
def test_create_without_location
ActiveResource::HttpMock.respond_to do |mock|
- mock.post "/people.xml", {}, nil, 201
+ mock.post "/people.json", {}, nil, 201
end
person = Person.create(:name => 'Rick')
assert_nil person.id
@@ -772,8 +772,8 @@ class BaseTest < Test::Unit::TestCase
def test_update_conflict
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/2.xml", {}, @david
- mock.put "/people/2.xml", @default_request_headers, nil, 409
+ mock.get "/people/2.json", {}, @david
+ mock.put "/people/2.json", @default_request_headers, nil, 409
end
assert_raise(ActiveResource::ResourceConflict) { Person.find(2).save }
end
@@ -830,7 +830,7 @@ class BaseTest < Test::Unit::TestCase
def test_destroy
assert Person.find(1).destroy
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1.xml", {}, nil, 404
+ mock.get "/people/1.json", {}, nil, 404
end
assert_raise(ActiveResource::ResourceNotFound) { Person.find(1).destroy }
end
@@ -838,7 +838,7 @@ class BaseTest < Test::Unit::TestCase
def test_destroy_with_custom_prefix
assert StreetAddress.find(1, :params => { :person_id => 1 }).destroy
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1/addresses/1.xml", {}, nil, 404
+ mock.get "/people/1/addresses/1.json", {}, nil, 404
end
assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
end
@@ -846,7 +846,7 @@ class BaseTest < Test::Unit::TestCase
def test_destroy_with_410_gone
assert Person.find(1).destroy
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1.xml", {}, nil, 410
+ mock.get "/people/1.json", {}, nil, 410
end
assert_raise(ActiveResource::ResourceGone) { Person.find(1).destroy }
end
@@ -854,7 +854,7 @@ class BaseTest < Test::Unit::TestCase
def test_delete
assert Person.delete(1)
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1.xml", {}, nil, 404
+ mock.get "/people/1.json", {}, nil, 404
end
assert_raise(ActiveResource::ResourceNotFound) { Person.find(1) }
end
@@ -862,7 +862,7 @@ class BaseTest < Test::Unit::TestCase
def test_delete_with_custom_prefix
assert StreetAddress.delete(1, :person_id => 1)
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1/addresses/1.xml", {}, nil, 404
+ mock.get "/people/1/addresses/1.json", {}, nil, 404
end
assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
end
@@ -870,7 +870,7 @@ class BaseTest < Test::Unit::TestCase
def test_delete_with_410_gone
assert Person.delete(1)
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1.xml", {}, nil, 410
+ mock.get "/people/1.json", {}, nil, 410
end
assert_raise(ActiveResource::ResourceGone) { Person.find(1) }
end
@@ -939,13 +939,14 @@ class BaseTest < Test::Unit::TestCase
def test_exists_with_410_gone
ActiveResource::HttpMock.respond_to do |mock|
- mock.head "/people/1.xml", {}, nil, 410
+ mock.head "/people/1.json", {}, nil, 410
end
assert !Person.exists?(1)
end
def test_to_xml
+ Person.format = :xml
matz = Person.find(1)
encode = matz.encode
xml = matz.to_xml
@@ -954,9 +955,12 @@ class BaseTest < Test::Unit::TestCase
assert xml.include?('<?xml version="1.0" encoding="UTF-8"?>')
assert xml.include?('<name>Matz</name>')
assert xml.include?('<id type="integer">1</id>')
+ ensure
+ Person.format = :json
end
def test_to_xml_with_element_name
+ Person.format = :xml
old_elem_name = Person.element_name
matz = Person.find(1)
Person.element_name = 'ruby_creator'
@@ -970,45 +974,45 @@ class BaseTest < Test::Unit::TestCase
assert xml.include?('<id type="integer">1</id>')
assert xml.include?('</ruby-creator>')
ensure
+ Person.format = :json
Person.element_name = old_elem_name
end
def test_to_xml_with_private_method_name_as_attribute
+ Person.format = :xml
assert_nothing_raised(ArgumentError) {
Customer.new(:test => true).to_xml
}
+ ensure
+ Person.format = :json
end
def test_to_json
Person.include_root_in_json = true
- Person.format = :json
joe = Person.find(6)
encode = joe.encode
json = joe.to_json
- Person.format = :xml
assert_equal encode, json
- assert_match %r{^\{"person":\{"person":\{}, json
+ assert_match %r{^\{"person":\{}, json
assert_match %r{"id":6}, json
assert_match %r{"name":"Joe"}, json
- assert_match %r{\}\}\}$}, json
+ assert_match %r{\}\}$}, json
end
def test_to_json_with_element_name
old_elem_name = Person.element_name
Person.include_root_in_json = true
- Person.format = :json
joe = Person.find(6)
Person.element_name = 'ruby_creator'
encode = joe.encode
json = joe.to_json
- Person.format = :xml
assert_equal encode, json
- assert_match %r{^\{"ruby_creator":\{"person":\{}, json
+ assert_match %r{^\{"ruby_creator":\{}, json
assert_match %r{"id":6}, json
assert_match %r{"name":"Joe"}, json
- assert_match %r{\}\}\}$}, json
+ assert_match %r{\}\}$}, json
ensure
Person.element_name = old_elem_name
end
@@ -1043,19 +1047,22 @@ class BaseTest < Test::Unit::TestCase
def test_load_yaml_array
assert_nothing_raised do
+ Person.format = :xml
marty = Person.find(5)
assert_equal 3, marty.colors.size
marty.colors.each do |color|
assert_kind_of String, color
end
end
+ ensure
+ Person.format = :json
end
def test_with_custom_formatter
- @addresses = [{:id => "1", :street => "1 Infinite Loop", :city => "Cupertino", :state => "CA"}].to_xml(:root => 'addresses')
+ addresses = [{ :id => "1", :street => "1 Infinite Loop", :city => "Cupertino", :state => "CA" }].to_xml(:root => :addresses)
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/addresses.xml", {}, @addresses, 200
+ mock.get "/addresses.xml", {}, addresses, 200
end
# late bind the site
@@ -1066,10 +1073,10 @@ class BaseTest < Test::Unit::TestCase
end
def test_create_with_custom_primary_key
- silver_plan = {:code => "silver", :price => 5.00}.to_xml(:root => "plan")
+ silver_plan = { :plan => { :code => "silver", :price => 5.00 } }.to_json
ActiveResource::HttpMock.respond_to do |mock|
- mock.post "/plans.xml", {}, silver_plan, 201, 'Location' => '/plans/silver.xml'
+ mock.post "/plans.json", {}, silver_plan, 201, 'Location' => '/plans/silver.json'
end
plan = SubscriptionPlan.new(:code => "silver", :price => 5.00)
@@ -1080,12 +1087,12 @@ class BaseTest < Test::Unit::TestCase
end
def test_update_with_custom_primary_key
- silver_plan = {:code => "silver", :price => 5.00}.to_xml(:root => "plan")
- silver_plan_updated = {:code => "silver", :price => 10.00}.to_xml(:root => "plan")
+ silver_plan = { :plan => { :code => "silver", :price => 5.00 } }.to_json
+ silver_plan_updated = { :plan => { :code => "silver", :price => 10.00 } }.to_json
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/plans/silver.xml", {}, silver_plan
- mock.put "/plans/silver.xml", {}, silver_plan_updated, 201, 'Location' => '/plans/silver.xml'
+ mock.get "/plans/silver.json", {}, silver_plan
+ mock.put "/plans/silver.json", {}, silver_plan_updated, 201, 'Location' => '/plans/silver.json'
end
plan = SubscriptionPlan.find("silver")
@@ -1097,7 +1104,7 @@ class BaseTest < Test::Unit::TestCase
plan.save!
assert_equal 10.00, plan.price
end
-
+
def test_namespacing
sound = Asset::Sound.find(1)
assert_equal "Asset::Sound::Author", sound.author.class.to_s
diff --git a/activeresource/test/connection_test.rb b/activeresource/test/cases/connection_test.rb
index 7c36393cf2..09df0fb678 100644
--- a/activeresource/test/connection_test.rb
+++ b/activeresource/test/cases/connection_test.rb
@@ -5,29 +5,29 @@ class ConnectionTest < Test::Unit::TestCase
def setup
@conn = ActiveResource::Connection.new('http://localhost')
- @matz = { :id => 1, :name => 'Matz' }
- @david = { :id => 2, :name => 'David' }
- @people = [ @matz, @david ].to_xml(:root => 'people')
- @people_single = [ @matz ].to_xml(:root => 'people-single-elements')
- @people_empty = [ ].to_xml(:root => 'people-empty-elements')
- @matz = @matz.to_xml(:root => 'person')
- @david = @david.to_xml(:root => 'person')
- @header = {'key' => 'value'}.freeze
-
- @default_request_headers = { 'Content-Type' => 'application/xml' }
+ matz = { :person => { :id => 1, :name => 'Matz' } }
+ david = { :person => { :id => 2, :name => 'David' } }
+ @people = { :people => [ matz, david ] }.to_json
+ @people_single = { 'people-single-elements' => [ matz ] }.to_json
+ @people_empty = { 'people-empty-elements' => [ ] }.to_json
+ @matz = matz.to_json
+ @david = david.to_json
+ @header = { 'key' => 'value' }.freeze
+
+ @default_request_headers = { 'Content-Type' => 'application/json' }
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/2.xml", @header, @david
- mock.get "/people.xml", {}, @people
- mock.get "/people_single_elements.xml", {}, @people_single
- mock.get "/people_empty_elements.xml", {}, @people_empty
- mock.get "/people/1.xml", {}, @matz
- mock.put "/people/1.xml", {}, nil, 204
- mock.put "/people/2.xml", {}, @header, 204
- mock.delete "/people/1.xml", {}, nil, 200
- mock.delete "/people/2.xml", @header, nil, 200
- mock.post "/people.xml", {}, nil, 201, 'Location' => '/people/5.xml'
- mock.post "/members.xml", {}, @header, 201, 'Location' => '/people/6.xml'
- mock.head "/people/1.xml", {}, nil, 200
+ mock.get "/people/2.json", @header, @david
+ mock.get "/people.json", {}, @people
+ mock.get "/people_single_elements.json", {}, @people_single
+ mock.get "/people_empty_elements.json", {}, @people_empty
+ mock.get "/people/1.json", {}, @matz
+ mock.put "/people/1.json", {}, nil, 204
+ mock.put "/people/2.json", {}, @header, 204
+ mock.delete "/people/1.json", {}, nil, 200
+ mock.delete "/people/2.json", @header, nil, 200
+ mock.post "/people.json", {}, nil, 201, 'Location' => '/people/5.json'
+ mock.post "/members.json", {}, @header, 201, 'Location' => '/people/6.json'
+ mock.head "/people/1.json", {}, nil, 200
end
end
@@ -120,64 +120,64 @@ class ConnectionTest < Test::Unit::TestCase
end
def test_get
- matz = decode(@conn.get("/people/1.xml"))
+ matz = decode(@conn.get("/people/1.json"))
assert_equal "Matz", matz["name"]
end
def test_head
- response = @conn.head("/people/1.xml")
+ response = @conn.head("/people/1.json")
assert response.body.blank?
assert_equal 200, response.code
end
def test_get_with_header
- david = decode(@conn.get("/people/2.xml", @header))
+ david = decode(@conn.get("/people/2.json", @header))
assert_equal "David", david["name"]
end
def test_get_collection
- people = decode(@conn.get("/people.xml"))
- assert_equal "Matz", people[0]["name"]
- assert_equal "David", people[1]["name"]
+ people = decode(@conn.get("/people.json"))
+ assert_equal "Matz", people[0]["person"]["name"]
+ assert_equal "David", people[1]["person"]["name"]
end
def test_get_collection_single
- people = decode(@conn.get("/people_single_elements.xml"))
- assert_equal "Matz", people[0]["name"]
+ people = decode(@conn.get("/people_single_elements.json"))
+ assert_equal "Matz", people[0]["person"]["name"]
end
def test_get_collection_empty
- people = decode(@conn.get("/people_empty_elements.xml"))
+ people = decode(@conn.get("/people_empty_elements.json"))
assert_equal [], people
end
def test_post
- response = @conn.post("/people.xml")
- assert_equal "/people/5.xml", response["Location"]
+ response = @conn.post("/people.json")
+ assert_equal "/people/5.json", response["Location"]
end
def test_post_with_header
- response = @conn.post("/members.xml", @header)
- assert_equal "/people/6.xml", response["Location"]
+ response = @conn.post("/members.json", @header)
+ assert_equal "/people/6.json", response["Location"]
end
def test_put
- response = @conn.put("/people/1.xml")
+ response = @conn.put("/people/1.json")
assert_equal 204, response.code
end
def test_put_with_header
- response = @conn.put("/people/2.xml", @header)
+ response = @conn.put("/people/2.json", @header)
assert_equal 204, response.code
end
def test_delete
- response = @conn.delete("/people/1.xml")
+ response = @conn.delete("/people/1.json")
assert_equal 200, response.code
end
def test_delete_with_header
- response = @conn.delete("/people/2.xml", @header)
+ response = @conn.delete("/people/2.json", @header)
assert_equal 200, response.code
end
@@ -185,7 +185,7 @@ class ConnectionTest < Test::Unit::TestCase
@http = mock('new Net::HTTP')
@conn.expects(:http).returns(@http)
@http.expects(:get).raises(Timeout::Error, 'execution expired')
- assert_raise(ActiveResource::TimeoutError) { @conn.get('/people_timeout.xml') }
+ assert_raise(ActiveResource::TimeoutError) { @conn.get('/people_timeout.json') }
end
def test_setting_timeout
@@ -203,8 +203,8 @@ class ConnectionTest < Test::Unit::TestCase
@http = mock('new Net::HTTP')
@conn.expects(:http).returns(@http)
path = '/people/1.xml'
- @http.expects(:get).with(path, {'Accept' => 'application/xhtml+xml'}).returns(ActiveResource::Response.new(@matz, 200, {'Content-Type' => 'text/xhtml'}))
- assert_nothing_raised(Mocha::ExpectationError) { @conn.get(path, {'Accept' => 'application/xhtml+xml'}) }
+ @http.expects(:get).with(path, { 'Accept' => 'application/xhtml+xml' }).returns(ActiveResource::Response.new(@matz, 200, { 'Content-Type' => 'text/xhtml' }))
+ assert_nothing_raised(Mocha::ExpectationError) { @conn.get(path, { 'Accept' => 'application/xhtml+xml' }) }
end
def test_ssl_options_get_applied_to_http
@@ -222,7 +222,7 @@ class ConnectionTest < Test::Unit::TestCase
http = Net::HTTP.new('')
@conn.expects(:http).returns(http)
http.expects(:get).raises(OpenSSL::SSL::SSLError, 'Expired certificate')
- assert_raise(ActiveResource::SSLError) { @conn.get('/people/1.xml') }
+ assert_raise(ActiveResource::SSLError) { @conn.get('/people/1.json') }
end
def test_auth_type_can_be_string
diff --git a/activeresource/test/cases/finder_test.rb b/activeresource/test/cases/finder_test.rb
index ebb783996d..9c51f2a390 100644
--- a/activeresource/test/cases/finder_test.rb
+++ b/activeresource/test/cases/finder_test.rb
@@ -100,23 +100,23 @@ class FinderTest < Test::Unit::TestCase
end
def test_find_all_by_from
- ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david }
+ ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.json", {}, @people_david }
- people = Person.find(:all, :from => "/companies/1/people.xml")
+ people = Person.find(:all, :from => "/companies/1/people.json")
assert_equal 1, people.size
assert_equal "David", people.first.name
end
def test_find_all_by_from_with_options
- ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david }
+ ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.json", {}, @people_david }
- people = Person.find(:all, :from => "/companies/1/people.xml")
+ people = Person.find(:all, :from => "/companies/1/people.json")
assert_equal 1, people.size
assert_equal "David", people.first.name
end
def test_find_all_by_symbol_from
- ActiveResource::HttpMock.respond_to { |m| m.get "/people/managers.xml", {}, @people_david }
+ ActiveResource::HttpMock.respond_to { |m| m.get "/people/managers.json", {}, @people_david }
people = Person.find(:all, :from => :managers)
assert_equal 1, people.size
@@ -124,14 +124,14 @@ class FinderTest < Test::Unit::TestCase
end
def test_find_single_by_from
- ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/manager.xml", {}, @david }
+ ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/manager.json", {}, @david }
- david = Person.find(:one, :from => "/companies/1/manager.xml")
+ david = Person.find(:one, :from => "/companies/1/manager.json")
assert_equal "David", david.name
end
def test_find_single_by_symbol_from
- ActiveResource::HttpMock.respond_to { |m| m.get "/people/leader.xml", {}, @david }
+ ActiveResource::HttpMock.respond_to { |m| m.get "/people/leader.json", {}, @david }
david = Person.find(:one, :from => :leader)
assert_equal "David", david.name
diff --git a/activeresource/test/cases/format_test.rb b/activeresource/test/cases/format_test.rb
index f8d33f99fa..174142ec52 100644
--- a/activeresource/test/cases/format_test.rb
+++ b/activeresource/test/cases/format_test.rb
@@ -51,28 +51,30 @@ class FormatTest < Test::Unit::TestCase
end
def test_formats_on_custom_element_method
- for format in [ :json, :xml ]
+ [:json, :xml].each do |format|
using_format(Person, format) do
+ david = (format == :json ? { :person => @david } : @david)
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/2.#{format}", {'Accept' => ActiveResource::Formats[format].mime_type}, ActiveResource::Formats[format].encode(@david)
- mock.get "/people/2/shallow.#{format}", {'Accept' => ActiveResource::Formats[format].mime_type}, ActiveResource::Formats[format].encode(@david)
+ mock.get "/people/2.#{format}", { 'Accept' => ActiveResource::Formats[format].mime_type }, ActiveResource::Formats[format].encode(david)
+ mock.get "/people/2/shallow.#{format}", { 'Accept' => ActiveResource::Formats[format].mime_type }, ActiveResource::Formats[format].encode(david)
end
+
remote_programmer = Person.find(2).get(:shallow)
assert_equal @david[:id], remote_programmer['id']
assert_equal @david[:name], remote_programmer['name']
end
- end
- for format in [ :json, :xml ]
- ryan = ActiveResource::Formats[format].encode({ :name => 'Ryan' })
+ ryan_hash = { :name => 'Ryan' }
+ ryan_hash = (format == :json ? { :person => ryan_hash } : ryan_hash)
+ ryan = ActiveResource::Formats[format].encode(ryan_hash)
using_format(Person, format) do
remote_ryan = Person.new(:name => 'Ryan')
- ActiveResource::HttpMock.respond_to.post "/people.#{format}", {'Content-Type' => ActiveResource::Formats[format].mime_type}, ryan, 201, {'Location' => "/people/5.#{format}"}
+ ActiveResource::HttpMock.respond_to.post "/people.#{format}", { 'Content-Type' => ActiveResource::Formats[format].mime_type}, ryan, 201, { 'Location' => "/people/5.#{format}" }
remote_ryan.save
remote_ryan = Person.new(:name => 'Ryan')
- ActiveResource::HttpMock.respond_to.post "/people/new/register.#{format}", {'Content-Type' => ActiveResource::Formats[format].mime_type}, ryan, 201, {'Location' => "/people/5.#{format}"}
- assert_equal ActiveResource::Response.new(ryan, 201, {'Location' => "/people/5.#{format}"}), remote_ryan.post(:register)
+ ActiveResource::HttpMock.respond_to.post "/people/new/register.#{format}", { 'Content-Type' => ActiveResource::Formats[format].mime_type}, ryan, 201, { 'Location' => "/people/5.#{format}" }
+ assert_equal ActiveResource::Response.new(ryan, 201, { 'Location' => "/people/5.#{format}" }), remote_ryan.post(:register)
end
end
end
diff --git a/activeresource/test/cases/http_mock_test.rb b/activeresource/test/cases/http_mock_test.rb
index cd5155924a..d2fd911314 100644
--- a/activeresource/test/cases/http_mock_test.rb
+++ b/activeresource/test/cases/http_mock_test.rb
@@ -11,10 +11,10 @@ class HttpMockTest < ActiveSupport::TestCase
[:post, :put, :get, :delete, :head].each do |method|
test "responds to simple #{method} request" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(method, "/people/1", {FORMAT_HEADER[method] => "application/xml"}, "Response")
+ mock.send(method, "/people/1", { FORMAT_HEADER[method] => "application/json" }, "Response")
end
- assert_equal "Response", request(method, "/people/1", FORMAT_HEADER[method] => "application/xml").body
+ assert_equal "Response", request(method, "/people/1", FORMAT_HEADER[method] => "application/json").body
end
test "adds format header by default to #{method} request" do
@@ -22,7 +22,7 @@ class HttpMockTest < ActiveSupport::TestCase
mock.send(method, "/people/1", {}, "Response")
end
- assert_equal "Response", request(method, "/people/1", FORMAT_HEADER[method] => "application/xml").body
+ assert_equal "Response", request(method, "/people/1", FORMAT_HEADER[method] => "application/json").body
end
test "respond only when headers match header by default to #{method} request" do
@@ -53,8 +53,8 @@ class HttpMockTest < ActiveSupport::TestCase
test "responds correctly when format header is given to #{method} request" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(method, "/people/1", {FORMAT_HEADER[method] => "application/xml"}, "XML")
- mock.send(method, "/people/1", {FORMAT_HEADER[method] => "application/json"}, "Json")
+ mock.send(method, "/people/1", { FORMAT_HEADER[method] => "application/xml" }, "XML")
+ mock.send(method, "/people/1", { FORMAT_HEADER[method] => "application/json" }, "Json")
end
assert_equal "XML", request(method, "/people/1", FORMAT_HEADER[method] => "application/xml").body
@@ -63,22 +63,22 @@ class HttpMockTest < ActiveSupport::TestCase
test "raises InvalidRequestError if no response found for the #{method} request" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(method, "/people/1", {FORMAT_HEADER[method] => "application/xml"}, "XML")
+ mock.send(method, "/people/1", { FORMAT_HEADER[method] => "application/json" }, "json")
end
assert_raise(::ActiveResource::InvalidRequestError) do
- request(method, "/people/1", FORMAT_HEADER[method] => "application/json")
+ request(method, "/people/1", FORMAT_HEADER[method] => "application/xml")
end
end
end
test "allows you to send in pairs directly to the respond_to method" do
- matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
+ matz = { :person => { :id => 1, :name => "Matz" } }.to_json
- create_matz = ActiveResource::Request.new(:post, '/people.xml', matz, {})
- created_response = ActiveResource::Response.new("", 201, {"Location" => "/people/1.xml"})
- get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil)
+ create_matz = ActiveResource::Request.new(:post, '/people.json', matz, {})
+ created_response = ActiveResource::Response.new("", 201, { "Location" => "/people/1.json" })
+ get_matz = ActiveResource::Request.new(:get, '/people/1.json', nil)
ok_response = ActiveResource::Response.new(matz, 200, {})
pairs = {create_matz => created_response, get_matz => ok_response}
@@ -91,24 +91,24 @@ class HttpMockTest < ActiveSupport::TestCase
test "resets all mocked responses on each call to respond_to with a block by default" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(:get, "/people/1", {}, "XML1")
+ mock.send(:get, "/people/1", {}, "JSON1")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(:get, "/people/2", {}, "XML2")
+ mock.send(:get, "/people/2", {}, "JSON2")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
end
test "resets all mocked responses on each call to respond_to by passing pairs by default" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(:get, "/people/1", {}, "XML1")
+ mock.send(:get, "/people/1", {}, "JSON1")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
- matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
- get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil)
+ matz = { :person => { :id => 1, :name => "Matz" } }.to_json
+ get_matz = ActiveResource::Request.new(:get, '/people/1.json', nil)
ok_response = ActiveResource::Response.new(matz, 200, {})
ActiveResource::HttpMock.respond_to({get_matz => ok_response})
@@ -117,24 +117,24 @@ class HttpMockTest < ActiveSupport::TestCase
test "allows you to add new responses to the existing responses by calling a block" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(:get, "/people/1", {}, "XML1")
+ mock.send(:get, "/people/1", {}, "JSON1")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
ActiveResource::HttpMock.respond_to(false) do |mock|
- mock.send(:get, "/people/2", {}, "XML2")
+ mock.send(:get, "/people/2", {}, "JSON2")
end
assert_equal 2, ActiveResource::HttpMock.responses.length
end
test "allows you to add new responses to the existing responses by passing pairs" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(:get, "/people/1", {}, "XML1")
+ mock.send(:get, "/people/1", {}, "JSON1")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
- matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
- get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil)
+ matz = { :person => { :id => 1, :name => "Matz" } }.to_json
+ get_matz = ActiveResource::Request.new(:get, '/people/1.json', nil)
ok_response = ActiveResource::Response.new(matz, 200, {})
ActiveResource::HttpMock.respond_to({get_matz => ok_response}, false)
@@ -143,23 +143,23 @@ class HttpMockTest < ActiveSupport::TestCase
test "allows you to replace the existing reponse with the same request by calling a block" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(:get, "/people/1", {}, "XML1")
+ mock.send(:get, "/people/1", {}, "JSON1")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
ActiveResource::HttpMock.respond_to(false) do |mock|
- mock.send(:get, "/people/1", {}, "XML2")
+ mock.send(:get, "/people/1", {}, "JSON2")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
end
test "allows you to replace the existing reponse with the same request by passing pairs" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(:get, "/people/1", {}, "XML1")
+ mock.send(:get, "/people/1", {}, "JSON1")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
- matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
+ matz = { :person => { :id => 1, :name => "Matz" } }.to_json
get_matz = ActiveResource::Request.new(:get, '/people/1', nil)
ok_response = ActiveResource::Response.new(matz, 200, {})
@@ -169,19 +169,19 @@ class HttpMockTest < ActiveSupport::TestCase
test "do not replace the response with the same path but different method by calling a block" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(:get, "/people/1", {}, "XML1")
+ mock.send(:get, "/people/1", {}, "JSON1")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
ActiveResource::HttpMock.respond_to(false) do |mock|
- mock.send(:put, "/people/1", {}, "XML2")
+ mock.send(:put, "/people/1", {}, "JSON2")
end
assert_equal 2, ActiveResource::HttpMock.responses.length
end
test "do not replace the response with the same path but different method by passing pairs" do
ActiveResource::HttpMock.respond_to do |mock|
- mock.send(:get, "/people/1", {}, "XML1")
+ mock.send(:get, "/people/1", {}, "JSON1")
end
assert_equal 1, ActiveResource::HttpMock.responses.length
diff --git a/activeresource/test/cases/log_subscriber_test.rb b/activeresource/test/cases/log_subscriber_test.rb
index 3cd96007db..b9143f5b67 100644
--- a/activeresource/test/cases/log_subscriber_test.rb
+++ b/activeresource/test/cases/log_subscriber_test.rb
@@ -10,9 +10,9 @@ class LogSubscriberTest < ActiveSupport::TestCase
def setup
super
- @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
+ @matz = { :person => { :id => 1, :name => 'Matz' } }.to_json
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1.xml", {}, @matz
+ mock.get "/people/1.json", {}, @matz
end
ActiveResource::LogSubscriber.attach_to :active_resource
@@ -26,7 +26,7 @@ class LogSubscriberTest < ActiveSupport::TestCase
matz = Person.find(1)
wait
assert_equal 2, @logger.logged(:info).size
- assert_equal "GET http://37s.sunrise.i:3000/people/1.xml", @logger.logged(:info)[0]
- assert_match(/\-\-\> 200 200 106/, @logger.logged(:info)[1])
+ assert_equal "GET http://37s.sunrise.i:3000/people/1.json", @logger.logged(:info)[0]
+ assert_match(/\-\-\> 200 200 33/, @logger.logged(:info)[1])
end
end
diff --git a/activeresource/test/cases/observing_test.rb b/activeresource/test/cases/observing_test.rb
index 925ec7a84a..ca3ab5d03d 100644
--- a/activeresource/test/cases/observing_test.rb
+++ b/activeresource/test/cases/observing_test.rb
@@ -20,13 +20,13 @@ class ObservingTest < Test::Unit::TestCase
end
def setup
- @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
+ @matz = { 'person' => { :id => 1, :name => 'Matz' } }.to_json
ActiveResource::HttpMock.respond_to do |mock|
- mock.get "/people/1.xml", {}, @matz
- mock.post "/people.xml", {}, @matz, 201, 'Location' => '/people/1.xml'
- mock.put "/people/1.xml", {}, nil, 204
- mock.delete "/people/1.xml", {}, nil, 200
+ mock.get "/people/1.json", {}, @matz
+ mock.post "/people.json", {}, @matz, 201, 'Location' => '/people/1.json'
+ mock.put "/people/1.json", {}, nil, 204
+ mock.delete "/people/1.json", {}, nil, 200
end
PersonObserver.instance
diff --git a/activeresource/test/cases/validations_test.rb b/activeresource/test/cases/validations_test.rb
index 3b1caecb04..c6c6e1d786 100644
--- a/activeresource/test/cases/validations_test.rb
+++ b/activeresource/test/cases/validations_test.rb
@@ -8,9 +8,9 @@ require 'active_support/core_ext/hash/conversions'
class ValidationsTest < ActiveModel::TestCase
VALID_PROJECT_HASH = { :name => "My Project", :description => "A project" }
def setup
- @my_proj = VALID_PROJECT_HASH.to_xml(:root => "person")
+ @my_proj = { "person" => VALID_PROJECT_HASH }.to_json
ActiveResource::HttpMock.respond_to do |mock|
- mock.post "/projects.xml", {}, @my_proj, 201, 'Location' => '/projects/5.xml'
+ mock.post "/projects.json", {}, @my_proj, 201, 'Location' => '/projects/5.json'
end
end
diff --git a/activeresource/test/setter_trap.rb b/activeresource/test/setter_trap.rb
index 437fbdad32..7cfd9ca111 100644
--- a/activeresource/test/setter_trap.rb
+++ b/activeresource/test/setter_trap.rb
@@ -1,5 +1,3 @@
-require 'abstract_unit'
-
class SetterTrap < ActiveSupport::BasicObject
class << self
def rollback_sets(obj)
diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb
index a14f008be5..b937d4c50d 100644
--- a/activesupport/lib/active_support/buffered_logger.rb
+++ b/activesupport/lib/active_support/buffered_logger.rb
@@ -48,14 +48,17 @@ module ActiveSupport
if log.respond_to?(:write)
@log = log
elsif File.exist?(log)
- @log = open(log, (File::WRONLY | File::APPEND))
- @log.binmode
- @log.sync = true
+ @log = open_log(log, (File::WRONLY | File::APPEND))
else
FileUtils.mkdir_p(File.dirname(log))
- @log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
- @log.binmode
- @log.sync = true
+ @log = open_log(log, (File::WRONLY | File::APPEND | File::CREAT))
+ end
+ end
+
+ def open_log(log, mode)
+ open(log, mode).tap do |log|
+ log.set_encoding(Encoding::BINARY) if log.respond_to?(:set_encoding)
+ log.sync = true
end
end
diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
index ca3db2349e..ec475134ef 100644
--- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
@@ -130,7 +130,6 @@ class Class # :nodoc:
end
def write_inheritable_attribute(key, value)
- ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
@inheritable_attributes = {}
end
@@ -148,7 +147,6 @@ class Class # :nodoc:
end
def read_inheritable_attribute(key)
- ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
inheritable_attributes[key]
end
diff --git a/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb b/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb
index e3259a0a84..984f6fb957 100644
--- a/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb
+++ b/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb
@@ -19,6 +19,7 @@ class Module
# attr_accessor_with_default(:element_name) { name.underscore }
#
def attr_accessor_with_default(sym, default = Proc.new)
+ ActiveSupport::Deprecation.warn "attr_accessor_with_default is deprecated. Use Ruby instead!"
define_method(sym, block_given? ? default : Proc.new { default })
module_eval(<<-EVAL, __FILE__, __LINE__ + 1)
def #{sym}=(value) # def age=(value)
diff --git a/activesupport/lib/active_support/core_ext/numeric/time.rb b/activesupport/lib/active_support/core_ext/numeric/time.rb
index e73915ffcf..58a03d508e 100644
--- a/activesupport/lib/active_support/core_ext/numeric/time.rb
+++ b/activesupport/lib/active_support/core_ext/numeric/time.rb
@@ -1,4 +1,6 @@
require 'active_support/duration'
+require 'active_support/core_ext/time/calculations'
+require 'active_support/core_ext/time/acts_like'
class Numeric
# Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index dcac17536a..00fda2b370 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -1,4 +1,5 @@
require 'active_support/duration'
+require 'active_support/core_ext/time/zones'
class Time
COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index 8ec4f6e09a..39ebc1ec82 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -10,6 +10,10 @@ module ActiveSupport
true
end
+ def with_indifferent_access
+ self
+ end
+
def initialize(constructor = {})
if constructor.is_a?(Hash)
super()
@@ -58,8 +62,12 @@ module ActiveSupport
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
#
def update(other_hash)
- other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
- self
+ if other_hash.is_a? HashWithIndifferentAccess
+ super(other_hash)
+ else
+ other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
+ self
+ end
end
alias_method :merge!, :update
diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb
index 7cd9bfa947..02c19448fd 100644
--- a/activesupport/lib/active_support/testing/performance.rb
+++ b/activesupport/lib/active_support/testing/performance.rb
@@ -1,470 +1,317 @@
-begin
- require 'ruby-prof'
-
- require 'fileutils'
- require 'rails/version'
- require 'active_support/concern'
- require 'active_support/core_ext/class/delegating_attributes'
- require 'active_support/core_ext/string/inflections'
-
- module ActiveSupport
- module Testing
- module Performance
- extend ActiveSupport::Concern
-
- included do
- superclass_delegating_accessor :profile_options
- self.profile_options = DEFAULTS
-
- if defined?(MiniTest::Assertions) && TestCase < MiniTest::Assertions
- include ForMiniTest
- else
- include ForClassicTestUnit
- end
+require 'fileutils'
+require 'rails/version'
+require 'active_support/concern'
+require 'active_support/core_ext/class/delegating_attributes'
+require 'active_support/core_ext/string/inflections'
+require 'action_view/helpers/number_helper'
+
+module ActiveSupport
+ module Testing
+ module Performance
+ extend ActiveSupport::Concern
+
+ included do
+ superclass_delegating_accessor :profile_options
+ self.profile_options = {}
+
+ if defined?(MiniTest::Assertions) && TestCase < MiniTest::Assertions
+ include ForMiniTest
+ else
+ include ForClassicTestUnit
end
+ end
+
+ # each implementation should define metrics and freeze the defaults
+ DEFAULTS =
+ if ARGV.include?('--benchmark') # HAX for rake test
+ { :runs => 4,
+ :output => 'tmp/performance',
+ :benchmark => true }
+ else
+ { :runs => 1,
+ :output => 'tmp/performance',
+ :benchmark => false }
+ end
+
+ def full_profile_options
+ DEFAULTS.merge(profile_options)
+ end
- module ForMiniTest
- def run(runner)
- @runner = runner
-
- run_warmup
- if profile_options && metrics = profile_options[:metrics]
- metrics.each do |metric_name|
- if klass = Metrics[metric_name.to_sym]
- run_profile(klass.new)
- end
+ def full_test_name
+ "#{self.class.name}##{method_name}"
+ end
+
+ module ForMiniTest
+ def run(runner)
+ @runner = runner
+
+ run_warmup
+ if full_profile_options && metrics = full_profile_options[:metrics]
+ metrics.each do |metric_name|
+ if klass = Metrics[metric_name.to_sym]
+ run_profile(klass.new)
end
end
end
+
+ return
+ end
- def run_test(metric, mode)
- result = '.'
+ def run_test(metric, mode)
+ result = '.'
+ begin
+ run_callbacks :setup
+ setup
+ metric.send(mode) { __send__ method_name }
+ rescue Exception => e
+ result = @runner.puke(self.class, method_name, e)
+ ensure
begin
- run_callbacks :setup
- setup
- metric.send(mode) { __send__ method_name }
+ teardown
+ run_callbacks :teardown, :enumerator => :reverse_each
rescue Exception => e
result = @runner.puke(self.class, method_name, e)
- ensure
- begin
- teardown
- run_callbacks :teardown, :enumerator => :reverse_each
- rescue Exception => e
- result = @runner.puke(self.class, method_name, e)
- end
end
- result
end
+ result
end
+ end
- module ForClassicTestUnit
- def run(result)
- return if method_name =~ /^default_test$/
+ module ForClassicTestUnit
+ def run(result)
+ return if method_name =~ /^default_test$/
- yield(self.class::STARTED, name)
- @_result = result
+ yield(self.class::STARTED, name)
+ @_result = result
- run_warmup
- if profile_options && metrics = profile_options[:metrics]
- metrics.each do |metric_name|
- if klass = Metrics[metric_name.to_sym]
- run_profile(klass.new)
- result.add_run
- end
+ run_warmup
+ if full_profile_options && metrics = full_profile_options[:metrics]
+ metrics.each do |metric_name|
+ if klass = Metrics[metric_name.to_sym]
+ run_profile(klass.new)
+ result.add_run
+ else
+ puts '%20s: unsupported' % metric_name
end
end
-
- yield(self.class::FINISHED, name)
end
- def run_test(metric, mode)
- run_callbacks :setup
- setup
- metric.send(mode) { __send__ @method_name }
+ yield(self.class::FINISHED, name)
+ end
+
+ def run_test(metric, mode)
+ run_callbacks :setup
+ setup
+ metric.send(mode) { __send__ @method_name }
+ rescue ::Test::Unit::AssertionFailedError => e
+ add_failure(e.message, e.backtrace)
+ rescue StandardError, ScriptError => e
+ add_error(e)
+ ensure
+ begin
+ teardown
+ run_callbacks :teardown, :enumerator => :reverse_each
rescue ::Test::Unit::AssertionFailedError => e
- add_failure(e.message, e.backtrace)
+ add_failure(e.message, e.backtrace)
rescue StandardError, ScriptError => e
add_error(e)
- ensure
- begin
- teardown
- run_callbacks :teardown, :enumerator => :reverse_each
- rescue ::Test::Unit::AssertionFailedError => e
- add_failure(e.message, e.backtrace)
- rescue StandardError, ScriptError => e
- add_error(e)
- end
end
end
+ end
- DEFAULTS =
- if benchmark = ARGV.include?('--benchmark') # HAX for rake test
- { :benchmark => true,
- :runs => 4,
- :metrics => [:wall_time, :memory, :objects, :gc_runs, :gc_time],
- :output => 'tmp/performance' }
- else
- { :benchmark => false,
- :runs => 1,
- :min_percent => 0.01,
- :metrics => [:process_time, :memory, :objects],
- :formats => [:flat, :graph_html, :call_tree],
- :output => 'tmp/performance' }
- end.freeze
-
- def full_test_name
- "#{self.class.name}##{method_name}"
- end
-
- protected
- def run_warmup
- GC.start
-
- time = Metrics::Time.new
- run_test(time, :benchmark)
- puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
+ protected
+ # overridden by each implementation
+ def run_gc; end
+
+ def run_warmup
+ run_gc
- GC.start
- end
+ time = Metrics::Time.new
+ run_test(time, :benchmark)
+ puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
- def run_profile(metric)
- klass = profile_options[:benchmark] ? Benchmarker : Profiler
- performer = klass.new(self, metric)
-
- performer.run
- puts performer.report
- performer.record
- end
+ run_gc
+ end
+
+ def run_profile(metric)
+ klass = full_profile_options[:benchmark] ? Benchmarker : Profiler
+ performer = klass.new(self, metric)
+
+ performer.run
+ puts performer.report
+ performer.record
+ end
- class Performer
- delegate :run_test, :profile_options, :full_test_name, :to => :@harness
+ class Performer
+ delegate :run_test, :full_profile_options, :full_test_name, :to => :@harness
- def initialize(harness, metric)
- @harness, @metric = harness, metric
- end
+ def initialize(harness, metric)
+ @harness, @metric, @supported = harness, metric, false
+ end
- def report
- rate = @total / profile_options[:runs]
+ def report
+ if @supported
+ rate = @total / full_profile_options[:runs]
'%20s: %s' % [@metric.name, @metric.format(rate)]
+ else
+ '%20s: unsupported' % @metric.name
end
-
- protected
- def output_filename
- "#{profile_options[:output]}/#{full_test_name}_#{@metric.name}"
- end
end
- class Benchmarker < Performer
- def run
- profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
- @total = @metric.total
- end
-
- def record
- avg = @metric.total / profile_options[:runs].to_i
- now = Time.now.utc.xmlschema
- with_output_file do |file|
- file.puts "#{avg},#{now},#{environment}"
- end
- end
-
- def environment
- unless defined? @env
- app = "#{$1}.#{$2}" if File.directory?('.git') && `git branch -v` =~ /^\* (\S+)\s+(\S+)/
-
- rails = Rails::VERSION::STRING
- if File.directory?('vendor/rails/.git')
- Dir.chdir('vendor/rails') do
- rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
- end
- end
-
- ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
- ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
-
- @env = [app, rails, ruby, RUBY_PLATFORM] * ','
- end
-
- @env
+ protected
+ def output_filename
+ "#{full_profile_options[:output]}/#{full_test_name}_#{@metric.name}"
end
-
- protected
- HEADER = 'measurement,created_at,app,rails,ruby,platform'
-
- def with_output_file
- fname = output_filename
-
- if new = !File.exist?(fname)
- FileUtils.mkdir_p(File.dirname(fname))
- end
-
- File.open(fname, 'ab') do |file|
- file.puts(HEADER) if new
- yield file
- end
- end
-
- def output_filename
- "#{super}.csv"
- end
+ end
+
+ # overridden by each implementation
+ class Profiler < Performer
+ def time_with_block
+ before = Time.now
+ yield
+ Time.now - before
end
+
+ def run; end
+ def record; end
+ end
- class Profiler < Performer
- def initialize(*args)
- super
- @supported = @metric.measure_mode rescue false
- end
-
- def run
- return unless @supported
-
- RubyProf.measure_mode = @metric.measure_mode
- RubyProf.start
- RubyProf.pause
- profile_options[:runs].to_i.times { run_test(@metric, :profile) }
- @data = RubyProf.stop
- @total = @data.threads.values.sum(0) { |method_infos| method_infos.max.total_time }
- end
+ class Benchmarker < Performer
+ def initialize(*args)
+ super
+ @supported = @metric.respond_to?('measure')
+ end
+
+ def run
+ return unless @supported
+
+ full_profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
+ @total = @metric.total
+ end
- def report
- if @supported
- super
- else
- '%20s: unsupported' % @metric.name
- end
+ def record
+ avg = @metric.total / full_profile_options[:runs].to_i
+ now = Time.now.utc.xmlschema
+ with_output_file do |file|
+ file.puts "#{avg},#{now},#{environment}"
end
+ end
- def record
- return unless @supported
-
- klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
+ def environment
+ unless defined? @env
+ app = "#{$1}.#{$2}" if File.directory?('.git') && `git branch -v` =~ /^\* (\S+)\s+(\S+)/
- klasses.each do |klass|
- fname = output_filename(klass)
- FileUtils.mkdir_p(File.dirname(fname))
- File.open(fname, 'wb') do |file|
- klass.new(@data).print(file, profile_options.slice(:min_percent))
+ rails = Rails::VERSION::STRING
+ if File.directory?('vendor/rails/.git')
+ Dir.chdir('vendor/rails') do
+ rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
end
end
- end
- protected
- def output_filename(printer_class)
- suffix =
- case printer_class.name.demodulize
- when 'FlatPrinter'; 'flat.txt'
- when 'FlatPrinterWithLineNumbers'; 'flat_line_numbers.txt'
- when 'GraphPrinter'; 'graph.txt'
- when 'GraphHtmlPrinter'; 'graph.html'
- when 'GraphYamlPrinter'; 'graph.yml'
- when 'CallTreePrinter'; 'tree.txt'
- when 'CallStackPrinter'; 'stack.html'
- when 'DotPrinter'; 'graph.dot'
- else printer_class.name.sub(/Printer$/, '').underscore
- end
-
- "#{super()}_#{suffix}"
- end
- end
+ ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
+ ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
- module Metrics
- def self.[](name)
- const_get(name.to_s.camelize)
- rescue NameError
- nil
+ @env = [app, rails, ruby, RUBY_PLATFORM] * ','
end
- class Base
- attr_reader :total
-
- def initialize
- @total = 0
- end
+ @env
+ end
- def name
- @name ||= self.class.name.demodulize.underscore
- end
+ protected
+ HEADER = 'measurement,created_at,app,rails,ruby,platform'
- def measure_mode
- self.class::Mode
- end
+ def with_output_file
+ fname = output_filename
- def measure
- 0
- end
-
- def benchmark
- with_gc_stats do
- before = measure
- yield
- @total += (measure - before)
- end
+ if new = !File.exist?(fname)
+ FileUtils.mkdir_p(File.dirname(fname))
end
- def profile
- RubyProf.resume
- yield
- ensure
- RubyProf.pause
+ File.open(fname, 'ab') do |file|
+ file.puts(HEADER) if new
+ yield file
end
-
- protected
- # Ruby 1.9 with GC::Profiler
- if defined?(GC::Profiler)
- def with_gc_stats
- GC::Profiler.enable
- GC.start
- yield
- ensure
- GC::Profiler.disable
- end
-
- # Ruby 1.8 + ruby-prof wrapper (enable/disable stats for Benchmarker)
- elsif GC.respond_to?(:enable_stats)
- def with_gc_stats
- GC.enable_stats
- yield
- ensure
- GC.disable_stats
- end
-
- else
- def with_gc_stats
- yield
- end
- end
end
- class Time < Base
- def measure
- ::Time.now.to_f
- end
-
- def format(measurement)
- if measurement < 1
- '%d ms' % (measurement * 1000)
- else
- '%.2f sec' % measurement
- end
- end
+ def output_filename
+ "#{super}.csv"
end
+ end
+
+ module Metrics
+ def self.[](name)
+ const_get(name.to_s.camelize)
+ rescue NameError
+ nil
+ end
- class ProcessTime < Time
- Mode = RubyProf::PROCESS_TIME
+ class Base
+ include ActionView::Helpers::NumberHelper
+
+ attr_reader :total
- def measure
- RubyProf.measure_process_time
- end
+ def initialize
+ @total = 0
end
- class WallTime < Time
- Mode = RubyProf::WALL_TIME
-
- def measure
- RubyProf.measure_wall_time
- end
+ def name
+ @name ||= self.class.name.demodulize.underscore
end
- class CpuTime < Time
- Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME)
-
- def initialize(*args)
- # FIXME: yeah my CPU is 2.33 GHz
- RubyProf.cpu_frequency = 2.33e9 unless RubyProf.cpu_frequency > 0
- super
- end
-
- def measure
- RubyProf.measure_cpu_time
+ def benchmark
+ with_gc_stats do
+ before = measure
+ yield
+ @total += (measure - before)
end
end
-
- class Memory < Base
- Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY)
-
- # Ruby 1.9 + GCdata patch
- if GC.respond_to?(:malloc_allocated_size)
- def measure
- GC.malloc_allocated_size / 1024.0
- end
-
- # Ruby 1.8 + ruby-prof wrapper
- elsif RubyProf.respond_to?(:measure_memory)
- def measure
- RubyProf.measure_memory / 1024.0
- end
- end
-
- def format(measurement)
- '%.2f KB' % measurement
- end
+
+ # overridden by each implementation
+ def profile; end
+
+ protected
+ # overridden by each implementation
+ def with_gc_stats; end
+ end
+
+ class Time < Base
+ def measure
+ ::Time.now.to_f
end
- class Objects < Base
- Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS)
-
- # Ruby 1.9 + GCdata patch
- if GC.respond_to?(:malloc_allocations)
- def measure
- GC.malloc_allocations
- end
-
- # Ruby 1.8 + ruby-prof wrapper
- elsif RubyProf.respond_to?(:measure_allocations)
- def measure
- RubyProf.measure_allocations
- end
- end
-
- def format(measurement)
- measurement.to_i.to_s
+ def format(measurement)
+ if measurement < 1
+ '%d ms' % (measurement * 1000)
+ else
+ '%.2f sec' % measurement
end
end
-
- class GcRuns < Base
- Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS)
-
- # Ruby 1.9
- if GC.respond_to?(:count)
- def measure
- GC.count
- end
-
- # Ruby 1.8 + ruby-prof wrapper
- elsif RubyProf.respond_to?(:measure_gc_runs)
- def measure
- RubyProf.measure_gc_runs
- end
- end
-
- def format(measurement)
- measurement.to_i.to_s
- end
+ end
+
+ class Amount < Base
+ def format(measurement)
+ number_with_delimiter(measurement.floor)
end
-
- class GcTime < Base
- Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME)
-
- # Ruby 1.9 with GC::Profiler
- if defined?(GC::Profiler) && GC::Profiler.respond_to?(:total_time)
- def measure
- GC::Profiler.total_time
- end
-
- # Ruby 1.8 + ruby-prof wrapper
- elsif RubyProf.respond_to?(:measure_gc_time)
- def measure
- RubyProf.measure_gc_time / 1000
- end
- end
-
- def format(measurement)
- '%.2f ms' % measurement
- end
+ end
+
+ class DigitalInformationUnit < Base
+ def format(measurement)
+ number_to_human_size(measurement, :precision => 2)
end
end
+
+ # each implementation provides its own metrics like ProcessTime, Memory or GcRuns
end
end
end
-rescue LoadError
+end
+
+RUBY_ENGINE = 'ruby' unless defined?(RUBY_ENGINE) # mri 1.8
+case RUBY_ENGINE
+ when 'ruby' then require 'active_support/testing/performance/ruby'
+ when 'rbx' then require 'active_support/testing/performance/rubinius'
+ when 'jruby' then require 'active_support/testing/performance/jruby'
+ else
+ $stderr.puts 'Your ruby interpreter is not supported for benchmarking.'
+ exit
end
diff --git a/activesupport/lib/active_support/testing/performance/jruby.rb b/activesupport/lib/active_support/testing/performance/jruby.rb
new file mode 100644
index 0000000000..6b27959840
--- /dev/null
+++ b/activesupport/lib/active_support/testing/performance/jruby.rb
@@ -0,0 +1,115 @@
+require 'jruby/profiler'
+require 'java'
+import java.lang.management.ManagementFactory
+
+module ActiveSupport
+ module Testing
+ module Performance
+ DEFAULTS.merge!(
+ if ARGV.include?('--benchmark')
+ {:metrics => [:wall_time, :user_time, :memory, :gc_runs, :gc_time]}
+ else
+ { :metrics => [:wall_time],
+ :formats => [:flat, :graph] }
+ end).freeze
+
+ protected
+ def run_gc
+ ManagementFactory.memory_mx_bean.gc
+ end
+
+ class Profiler < Performer
+ def initialize(*args)
+ super
+ @supported = @metric.is_a?(Metrics::WallTime)
+ end
+
+ def run
+ return unless @supported
+
+ @total = time_with_block do
+ @data = JRuby::Profiler.profile do
+ full_profile_options[:runs].to_i.times { run_test(@metric, :profile) }
+ end
+ end
+ end
+
+ def record
+ return unless @supported
+
+ klasses = full_profile_options[:formats].map { |f| JRuby::Profiler.const_get("#{f.to_s.camelize}ProfilePrinter") }.compact
+
+ klasses.each do |klass|
+ fname = output_filename(klass)
+ FileUtils.mkdir_p(File.dirname(fname))
+ file = File.open(fname, 'wb') do |file|
+ klass.new(@data).printProfile(file)
+ end
+ end
+ end
+
+ protected
+ def output_filename(printer_class)
+ suffix =
+ case printer_class.name.demodulize
+ when 'FlatProfilePrinter'; 'flat.txt'
+ when 'GraphProfilePrinter'; 'graph.txt'
+ else printer_class.name.sub(/ProfilePrinter$/, '').underscore
+ end
+
+ "#{super()}_#{suffix}"
+ end
+ end
+
+ module Metrics
+ class Base
+ def profile
+ yield
+ end
+
+ protected
+ def with_gc_stats
+ ManagementFactory.memory_mx_bean.gc
+ yield
+ end
+ end
+
+ class WallTime < Time
+ def measure
+ super
+ end
+ end
+
+ class CpuTime < Time
+ def measure
+ ManagementFactory.thread_mx_bean.get_current_thread_cpu_time / 1000 / 1000 / 1000.0 # seconds
+ end
+ end
+
+ class UserTime < Time
+ def measure
+ ManagementFactory.thread_mx_bean.get_current_thread_user_time / 1000 / 1000 / 1000.0 # seconds
+ end
+ end
+
+ class Memory < DigitalInformationUnit
+ def measure
+ ManagementFactory.memory_mx_bean.non_heap_memory_usage.used + ManagementFactory.memory_mx_bean.heap_memory_usage.used
+ end
+ end
+
+ class GcRuns < Amount
+ def measure
+ ManagementFactory.garbage_collector_mx_beans.inject(0) { |total_runs, current_gc| total_runs += current_gc.collection_count }
+ end
+ end
+
+ class GcTime < Time
+ def measure
+ ManagementFactory.garbage_collector_mx_beans.inject(0) { |total_time, current_gc| total_time += current_gc.collection_time } / 1000.0 # seconds
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/testing/performance/rubinius.rb b/activesupport/lib/active_support/testing/performance/rubinius.rb
new file mode 100644
index 0000000000..198d235548
--- /dev/null
+++ b/activesupport/lib/active_support/testing/performance/rubinius.rb
@@ -0,0 +1,113 @@
+require 'rubinius/agent'
+
+module ActiveSupport
+ module Testing
+ module Performance
+ DEFAULTS.merge!(
+ if ARGV.include?('--benchmark')
+ {:metrics => [:wall_time, :memory, :objects, :gc_runs, :gc_time]}
+ else
+ { :metrics => [:wall_time],
+ :formats => [:flat, :graph] }
+ end).freeze
+
+ protected
+ def run_gc
+ GC.run(true)
+ end
+
+ class Performer; end
+
+ class Profiler < Performer
+ def initialize(*args)
+ super
+ @supported = @metric.is_a?(Metrics::WallTime)
+ end
+
+ def run
+ return unless @supported
+
+ @profiler = Rubinius::Profiler::Instrumenter.new
+
+ @total = time_with_block do
+ @profiler.profile(false) do
+ full_profile_options[:runs].to_i.times { run_test(@metric, :profile) }
+ end
+ end
+ end
+
+ def record
+ return unless @supported
+
+ if(full_profile_options[:formats].include?(:flat))
+ create_path_and_open_file(:flat) do |file|
+ @profiler.show(file)
+ end
+ end
+
+ if(full_profile_options[:formats].include?(:graph))
+ create_path_and_open_file(:graph) do |file|
+ @profiler.show(file)
+ end
+ end
+ end
+
+ protected
+ def create_path_and_open_file(printer_name)
+ fname = "#{output_filename}_#{printer_name}.txt"
+ FileUtils.mkdir_p(File.dirname(fname))
+ File.open(fname, 'wb') do |file|
+ yield(file)
+ end
+ end
+ end
+
+ module Metrics
+ class Base
+ attr_reader :loopback
+
+ def profile
+ yield
+ end
+
+ protected
+ def with_gc_stats
+ @loopback = Rubinius::Agent.loopback
+ GC.run(true)
+ yield
+ end
+ end
+
+ class WallTime < Time
+ def measure
+ super
+ end
+ end
+
+ class Memory < DigitalInformationUnit
+ def measure
+ loopback.get("system.memory.counter.bytes").last
+ end
+ end
+
+ class Objects < Amount
+ def measure
+ loopback.get("system.memory.counter.objects").last
+ end
+ end
+
+ class GcRuns < Amount
+ def measure
+ loopback.get("system.gc.full.count").last + loopback.get("system.gc.young.count").last
+ end
+ end
+
+ class GcTime < Time
+ def measure
+ (loopback.get("system.gc.full.wallclock").last + loopback.get("system.gc.young.wallclock").last) / 1000.0
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/testing/performance/ruby.rb b/activesupport/lib/active_support/testing/performance/ruby.rb
new file mode 100644
index 0000000000..b29ec6719c
--- /dev/null
+++ b/activesupport/lib/active_support/testing/performance/ruby.rb
@@ -0,0 +1,152 @@
+begin
+ require 'ruby-prof'
+rescue LoadError
+ $stderr.puts 'Specify ruby-prof as application\'s dependency in Gemfile to run benchmarks.'
+ exit
+end
+
+module ActiveSupport
+ module Testing
+ module Performance
+ DEFAULTS.merge!(
+ if ARGV.include?('--benchmark')
+ { :metrics => [:wall_time, :memory, :objects, :gc_runs, :gc_time] }
+ else
+ { :min_percent => 0.01,
+ :metrics => [:process_time, :memory, :objects],
+ :formats => [:flat, :graph_html, :call_tree, :call_stack] }
+ end).freeze
+
+ protected
+ def run_gc
+ GC.start
+ end
+
+ class Profiler < Performer
+ def initialize(*args)
+ super
+ @supported = @metric.measure_mode rescue false
+ end
+
+ def run
+ return unless @supported
+
+ RubyProf.measure_mode = @metric.measure_mode
+ RubyProf.start
+ RubyProf.pause
+ full_profile_options[:runs].to_i.times { run_test(@metric, :profile) }
+ @data = RubyProf.stop
+ @total = @data.threads.values.sum(0) { |method_infos| method_infos.max.total_time }
+ end
+
+ def record
+ return unless @supported
+
+ klasses = full_profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
+
+ klasses.each do |klass|
+ fname = output_filename(klass)
+ FileUtils.mkdir_p(File.dirname(fname))
+ File.open(fname, 'wb') do |file|
+ klass.new(@data).print(file, full_profile_options.slice(:min_percent))
+ end
+ end
+ end
+
+ protected
+ def output_filename(printer_class)
+ suffix =
+ case printer_class.name.demodulize
+ when 'FlatPrinter'; 'flat.txt'
+ when 'FlatPrinterWithLineNumbers'; 'flat_line_numbers.txt'
+ when 'GraphPrinter'; 'graph.txt'
+ when 'GraphHtmlPrinter'; 'graph.html'
+ when 'GraphYamlPrinter'; 'graph.yml'
+ when 'CallTreePrinter'; 'tree.txt'
+ when 'CallStackPrinter'; 'stack.html'
+ when 'DotPrinter'; 'graph.dot'
+ else printer_class.name.sub(/Printer$/, '').underscore
+ end
+
+ "#{super()}_#{suffix}"
+ end
+ end
+
+ module Metrics
+ class Base
+ def measure_mode
+ self.class::Mode
+ end
+
+ def profile
+ RubyProf.resume
+ yield
+ ensure
+ RubyProf.pause
+ end
+
+ protected
+ # overridden by each implementation
+ def with_gc_stats
+ yield
+ end
+ end
+
+ class ProcessTime < Time
+ Mode = RubyProf::PROCESS_TIME if RubyProf.const_defined?(:PROCESS_TIME)
+
+ def measure
+ RubyProf.measure_process_time
+ end
+ end
+
+ class WallTime < Time
+ Mode = RubyProf::WALL_TIME if RubyProf.const_defined?(:WALL_TIME)
+
+ def measure
+ RubyProf.measure_wall_time
+ end
+ end
+
+ class CpuTime < Time
+ Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME)
+
+ def initialize(*args)
+ # FIXME: yeah my CPU is 2.33 GHz
+ RubyProf.cpu_frequency = 2.33e9 unless RubyProf.cpu_frequency > 0
+ super
+ end
+
+ def measure
+ RubyProf.measure_cpu_time
+ end
+ end
+
+ class Memory < DigitalInformationUnit
+ Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY)
+ end
+
+ class Objects < Amount
+ Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS)
+ end
+
+ class GcRuns < Amount
+ Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS)
+ end
+
+ class GcTime < Time
+ Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME)
+ end
+ end
+ end
+ end
+end
+
+if RUBY_VERSION.between?('1.9.2', '2.0')
+ require 'active_support/testing/performance/ruby/yarv'
+elsif RUBY_VERSION.between?('1.8.6', '1.9')
+ require 'active_support/testing/performance/ruby/mri'
+else
+ $stderr.puts 'Update your ruby interpreter to be able to run benchmarks.'
+ exit
+end
diff --git a/activesupport/lib/active_support/testing/performance/ruby/mri.rb b/activesupport/lib/active_support/testing/performance/ruby/mri.rb
new file mode 100644
index 0000000000..86e650050b
--- /dev/null
+++ b/activesupport/lib/active_support/testing/performance/ruby/mri.rb
@@ -0,0 +1,59 @@
+module ActiveSupport
+ module Testing
+ module Performance
+ module Metrics
+ class Base
+ protected
+ # Ruby 1.8 + ruby-prof wrapper (enable/disable stats for Benchmarker)
+ if GC.respond_to?(:enable_stats)
+ def with_gc_stats
+ GC.enable_stats
+ GC.start
+ yield
+ ensure
+ GC.disable_stats
+ end
+ end
+ end
+
+ class Memory < DigitalInformationUnit
+ # Ruby 1.8 + ruby-prof wrapper
+ if RubyProf.respond_to?(:measure_memory)
+ def measure
+ RubyProf.measure_memory
+ end
+ end
+ end
+
+ class Objects < Amount
+ # Ruby 1.8 + ruby-prof wrapper
+ if RubyProf.respond_to?(:measure_allocations)
+ def measure
+ RubyProf.measure_allocations
+ end
+ end
+ end
+
+ class GcRuns < Amount
+ # Ruby 1.8 + ruby-prof wrapper
+ if RubyProf.respond_to?(:measure_gc_runs)
+ def measure
+ RubyProf.measure_gc_runs
+ end
+ end
+ end
+
+ class GcTime < Time
+ # Ruby 1.8 + ruby-prof wrapper
+ if RubyProf.respond_to?(:measure_gc_time)
+ def measure
+ RubyProf.measure_gc_time / 1000.0 / 1000.0
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+
diff --git a/activesupport/lib/active_support/testing/performance/ruby/yarv.rb b/activesupport/lib/active_support/testing/performance/ruby/yarv.rb
new file mode 100644
index 0000000000..62095a8fe4
--- /dev/null
+++ b/activesupport/lib/active_support/testing/performance/ruby/yarv.rb
@@ -0,0 +1,57 @@
+module ActiveSupport
+ module Testing
+ module Performance
+ module Metrics
+ class Base
+ protected
+ # Ruby 1.9 with GC::Profiler
+ if defined?(GC::Profiler)
+ def with_gc_stats
+ GC::Profiler.enable
+ GC.start
+ yield
+ ensure
+ GC::Profiler.disable
+ end
+ end
+ end
+
+ class Memory < DigitalInformationUnit
+ # Ruby 1.9 + GCdata patch
+ if GC.respond_to?(:malloc_allocated_size)
+ def measure
+ GC.malloc_allocated_size
+ end
+ end
+ end
+
+ class Objects < Amount
+ # Ruby 1.9 + GCdata patch
+ if GC.respond_to?(:malloc_allocations)
+ def measure
+ GC.malloc_allocations
+ end
+ end
+ end
+
+ class GcRuns < Amount
+ # Ruby 1.9
+ if GC.respond_to?(:count)
+ def measure
+ GC.count
+ end
+ end
+ end
+
+ class GcTime < Time
+ # Ruby 1.9 with GC::Profiler
+ if defined?(GC::Profiler) && GC::Profiler.respond_to?(:total_time)
+ def measure
+ GC::Profiler.total_time
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index 4557a10688..b2c85f15cb 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -971,6 +971,11 @@ class HashToXmlTest < Test::Unit::TestCase
assert_nil hash_wia.default
end
+ def test_should_return_self_for_with_indifferent_access
+ hash_wia = HashWithIndifferentAccess.new
+ assert_equal hash_wia, hash_wia.with_indifferent_access
+ end
+
def test_should_copy_the_default_value_when_converting_to_hash_with_indifferent_access
hash = Hash.new(3)
hash_wia = hash.with_indifferent_access
diff --git a/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb b/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb
index b9b60c4d6d..0ecd16b051 100644
--- a/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb
+++ b/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb
@@ -1,7 +1,7 @@
require 'abstract_unit'
require 'active_support/core_ext/module/attr_accessor_with_default'
-class AttrAccessorWithDefaultTest < Test::Unit::TestCase
+class AttrAccessorWithDefaultTest < ActiveSupport::TestCase
def setup
@target = Class.new do
def helper
@@ -12,20 +12,28 @@ class AttrAccessorWithDefaultTest < Test::Unit::TestCase
end
def test_default_arg
- @target.attr_accessor_with_default :foo, :bar
+ assert_deprecated do
+ @target.attr_accessor_with_default :foo, :bar
+ end
assert_equal(:bar, @instance.foo)
@instance.foo = nil
assert_nil(@instance.foo)
end
def test_default_proc
- @target.attr_accessor_with_default(:foo) {helper.upcase}
+ assert_deprecated do
+ @target.attr_accessor_with_default(:foo) {helper.upcase}
+ end
assert_equal('HELPER', @instance.foo)
@instance.foo = nil
assert_nil(@instance.foo)
end
def test_invalid_args
- assert_raise(ArgumentError) {@target.attr_accessor_with_default :foo}
+ assert_raise(ArgumentError) do
+ assert_deprecated do
+ @target.attr_accessor_with_default :foo
+ end
+ end
end
end
diff --git a/activesupport/test/option_merger_test.rb b/activesupport/test/option_merger_test.rb
index 5b2e16a212..2bdd3034e5 100644
--- a/activesupport/test/option_merger_test.rb
+++ b/activesupport/test/option_merger_test.rb
@@ -66,11 +66,11 @@ class OptionMergerTest < Test::Unit::TestCase
end
end
- def test_nested_method_with_options_using_lamdba
- local_lamdba = lambda { { :lambda => true } }
+ def test_nested_method_with_options_using_lambda
+ local_lambda = lambda { { :lambda => true } }
with_options(@options) do |o|
- assert_equal @options.merge(local_lamdba.call),
- o.method_with_options(local_lamdba).call
+ assert_equal @options.merge(local_lambda.call),
+ o.method_with_options(local_lambda).call
end
end
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index 2958d1b053..fbe3d46367 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -60,7 +60,7 @@ config.asset_path = proc { |path| "/blog/public#{path}" }
* +config.autoload_once_paths+ accepts an array of paths from which Rails will autoload constants that won't be wiped per request. Relevant if +config.cache_classes+ is false, which is the case in development mode by default. Otherwise, all autoloading happens only once. All elements of this array must also be in +autoload_paths+. Default is an empty array.
-* +config.autoload_paths+ accepts an array of paths from which Rails will autoload constants. By default that's the abolute paths of +app/mailers+, +app/assets+, +app/controllers+, +app/models+, and +app/helpers+. Please use <tt>+=</tt> to extend the default list.
+* +config.autoload_paths+ accepts an array of paths from which Rails will autoload constants. Default is all directories under +app+.
* +config.cache_classes+ controls whether or not application classes and modules should be reloaded on each request. Defaults to true in development mode, and false in test and production modes. Can also be enabled with +threadsafe!+.
@@ -68,51 +68,43 @@ config.asset_path = proc { |path| "/blog/public#{path}" }
* +config.cache_store+ configures which cache store to use for Rails caching. Options include one of the symbols +:memory_store+, +:file_store+, +:mem_cache_store+, or an object that implements the cache API. Defaults to +:file_store+ if the directory +tmp/cache+ exists, and to +:memory_store+ otherwise.
-* +config.colorize_logging+ specifies whether or not to use ANSI color codes when logging information. Defaults to _true_.
+* +config.colorize_logging+ specifies whether or not to use ANSI color codes when logging information. Defaults to true.
-* +config.consider_all_requests_local+ is generally set to +true+ during development and +false+ during production; if it is set to +true+, then any error will cause detailed debugging information to be dumped in the HTTP response. For finer-grained control, set this to +false+ and implement +local_request?+ in controllers to specify which requests should provide debugging information on errors.
+* +config.consider_all_requests_local+ is a flag. If true then any error will cause detailed debugging information to be dumped in the HTTP response, and the +Rails::Info+ controller will show the application runtime context in +/rails/info/properties+. True by default in development and test environments, and false in production mode. For finer-grained control, set this to false and implement +local_request?+ in controllers to specify which requests should provide debugging information on errors.
-* +config.controller_paths+ configures where Rails can find controllers for this application.
+* +config.dependency_loading+ is a flag that allows you to disable constant autoloading setting it to false. It only has effect if +config.cache_classes+ is true, which it is by default in production mode. This flag is set to false by +config.threadsafe!+.
-* +config.dependency_loading+ enables or disables dependency loading during the request cycle. Setting dependency_loading to _true_ will allow new classes to be loaded during a request and setting it to _false_ will disable this behavior. Can also be enabled with +threadsafe!+.
-
-* +config.eager_load_paths+ accepts an array of paths from which Rails will eager load on boot if cache classes is enabled. Defaults to every folder in the +app+ directory of the application. All elements of this array must also be in +load_paths+.
+* +config.eager_load_paths+ accepts an array of paths from which Rails will eager load on boot if cache classes is enabled. Defaults to every folder in the +app+ directory of the application.
* +config.encoding+ sets up the application-wide encoding. Defaults to UTF-8.
* +config.filter_parameters+ used for filtering out the parameters that you don't want shown in the logs, such as passwords or credit card numbers.
-* +config.force_ssl+ forcing all requests to be under HTTPS protocol by using +Rack::SSL+ middleware. This will secure your application from a session hijack attempt.
-
-* +config.helper_paths+ configures where Rails can find helpers for this application.
-
-* +config.log_level+ defines the verbosity of the Rails logger. In production mode, this defaults to +:info+. In development mode, it defaults to +:debug+.
+* +config.force_ssl+ forces all requests to be under HTTPS protocol by using +Rack::SSL+ middleware.
-* +config.log_path+ overrides the path to the log file to use. Defaults to +log/#{environment}.log+ (e.g. log/development.log or log/production.log).
+* +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.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Controller. Set to nil to disable logging.
+* +config.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ +Logger+ class. Defaults to an instance of +ActiveSupport::BufferedLogger+, with auto flushing off in production mode.
-* +config.middleware+ allows you to configure the application's middleware. This is covered in depth in the "Configuring Middleware" section below.
+* +config.middleware+ allows you to configure the application's middleware. This is covered in depth in the "Configuring Middleware":configuring-middleware section below.
-* +config.plugins+ accepts the list of plugins to load. If this is set to nil, all plugins will be loaded. If this is set to [], no plugins will be loaded. Otherwise, plugins will be loaded in the order specified.
+* +config.plugins+ accepts the list of plugins to load. If this is set to +nil+, default, all plugins will be loaded. If this is set to +[]+, no plugins will be loaded. Otherwise, plugins will be loaded in the order specified. This option let's you enforce some particular loading order, useful when dependencies between plugins require it. For that use case, put first the plugins you want to be loaded in a certain order, and then the special symbol +:all+ to have the rest loaded without the need to specify them.
-* +config.preload_frameworks+ enables or disables preloading all frameworks at startup. Can also be enabled with +threadsafe!+. Defaults to +nil+, so is disabled.
+* +config.preload_frameworks+ enables or disables preloading all frameworks at startup. Enabled by +config.threadsafe!+. Defaults to +nil+, so is disabled.
-* +config.reload_plugins+ enables or disables plugin reloading.
+* +config.reload_plugins+ enables or disables plugin reloading. Defaults to false.
-* +config.root+ configures the root path of the application.
+* +config.secret_token+ used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get +config.secret_token+ initialized to a random key in +config/initializers/secret_token.rb+.
-* +config.secret_token+ used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering.
+* +config.serve_static_assets+ configures Rails to serve static assets. Defaults to true, but in the production environment is turned off. The server software used to run the application should be used to serve the assets instead.
-* +config.serve_static_assets+ configures Rails to serve static assets. Defaults to _true_, but in the production environment is turned off. The server software used to run the application should be used to serve the assets instead.
-
-* +config.session_store+ is usually set up in +config/initializers/session_store.rb+ and specifies what class to use to store the session. Custom session stores can be specified like so:
+* +config.session_store+ is usually set up in +config/initializers/session_store.rb+ and specifies what class to use to store the session. Possible values are +:cookie_store+, default, +:mem_cache_store+, and +:disabled+. The last one tells Rails not to deal with sessions. Custom session stores can also be specified like so:
<ruby>
- config.session_store = :my_custom_store
+config.session_store :my_custom_store
</ruby>
-This custom store must be defined as +ActionDispatch::Session::MyCustomStore+.
+This custom store must be defined as +ActionDispatch::Session::MyCustomStore+. In addition to symbols, they can also be objects implementing a certain API, like +ActiveRecord::SessionStore+, in which case no special namespace is required.
* +config.threadsafe!+ enables +allow_concurrency+, +cache_classes+, +dependency_loading+ and +preload_frameworks+ to make the application threadsafe.
@@ -120,7 +112,9 @@ WARNING: Threadsafe operation is incompatible with the normal workings of develo
* +config.time_zone+ sets the default time zone for the application and enables time zone awareness for Active Record.
-* +config.whiny_nils+ enables or disables warnings when any methods of nil are invoked. Defaults to _true_ in development and test environments.
+* +config.whiny_nils+ enables or disables warnings when a certain set of methods are invoked on +nil+ and it does not respond to them. Defaults to true in development and test environments.
+
+* +config.assets.enabled+ a flag that controls whether the asset pipeline is enabled. It is explicitly initialized in +config/application.rb+.
h4. Configuring Generators
diff --git a/railties/guides/source/performance_testing.textile b/railties/guides/source/performance_testing.textile
index 5679bae531..2b79237c59 100644
--- a/railties/guides/source/performance_testing.textile
+++ b/railties/guides/source/performance_testing.textile
@@ -4,7 +4,7 @@ This guide covers the various ways of performance testing a Ruby on Rails applic
* Understand the various types of benchmarking and profiling metrics
* Generate performance and benchmarking tests
-* Use a GC-patched Ruby binary to measure memory usage and object allocation
+* Install and use a GC-patched Ruby binary to measure memory usage and object allocation
* Understand the benchmarking information provided by Rails inside the log files
* Learn about various tools facilitating benchmarking and profiling
@@ -23,7 +23,7 @@ require 'test_helper'
require 'rails/performance_test_help'
# Profiling results for each test method are written to tmp/performance.
-class BrowsingTest < ActionController::PerformanceTest
+class BrowsingTest < ActionDispatch::PerformanceTest
def test_homepage
get '/'
end
@@ -34,10 +34,10 @@ This example is a simple performance test case for profiling a GET request to th
h4. Generating Performance Tests
-Rails provides a generator called +test_unit:performance+ for creating new performance tests:
+Rails provides a generator called +performance_test+ for creating new performance tests:
<shell>
-$ rails generate test_unit:performance homepage
+$ rails generate performance_test homepage
</shell>
This generates +homepage_test.rb+ in the +test/performance+ directory:
@@ -46,7 +46,7 @@ This generates +homepage_test.rb+ in the +test/performance+ directory:
require 'test_helper'
require 'rails/performance_test_help'
-class HomepageTest < ActionController::PerformanceTest
+class HomepageTest < ActionDispatch::PerformanceTest
# Replace this with your real tests.
def test_homepage
get '/'
@@ -105,7 +105,7 @@ Here's the performance test for +HomeController#dashboard+ and +PostsController#
require 'test_helper'
require 'rails/performance_test_help'
-class PostPerformanceTest < ActionController::PerformanceTest
+class PostPerformanceTest < ActionDispatch::PerformanceTest
def setup
# Application requires logged-in user
login_as(:lifo)
@@ -133,7 +133,7 @@ Performance test for +Post+ model:
require 'test_helper'
require 'rails/performance_test_help'
-class PostModelTest < ActionController::PerformanceTest
+class PostModelTest < ActionDispatch::PerformanceTest
def test_creation
Post.create :body => 'still fooling you', :cost => '100'
end
@@ -151,7 +151,7 @@ Performance tests can be run in two modes: Benchmarking and Profiling.
h5. Benchmarking
-Benchmarking helps find out how fast each performance test runs. Each test case is run +4 times+ in benchmarking mode.
+Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run +4 times+ in benchmarking mode.
To run performance tests in benchmarking mode:
@@ -161,7 +161,7 @@ $ rake test:benchmark
h5. Profiling
-Profiling helps you see the details of a performance test and provide an in-depth picture of the slow and memory hungry parts. Each test case is run +1 time+ in profiling mode.
+Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run +1 time+ in profiling mode.
To run performance tests in profiling mode:
@@ -171,43 +171,59 @@ $ rake test:profile
h4. Metrics
-Benchmarking and profiling run performance tests in various modes described below.
+Benchmarking and profiling run performance tests and give you multiple metrics. The availability of each metric is determined by the interpreter being used—none of them support all metrics—and by the mode in use. A brief description of each metric and their availability across interpreters/modes is given below.
h5. Wall Time
Wall time measures the real world time elapsed during the test run. It is affected by any other processes concurrently running on the system.
-Mode: Benchmarking
-
h5. Process Time
Process time measures the time taken by the process. It is unaffected by any other processes running concurrently on the same system. Hence, process time is likely to be constant for any given performance test, irrespective of the machine load.
-Mode: Profiling
+h5. CPU Time
+
+Similar to process time, but leverages the more accurate CPU clock counter available on the Pentium and PowerPC platforms.
+
+h5. User Time
+
+User time measures the amount of time the CPU spent in user-mode, i.e. within the process. This is not affected by other processes and by the time it possibly spends blocked.
h5. Memory
Memory measures the amount of memory used for the performance test case.
-Mode: Benchmarking, Profiling "Requires GC Patched Ruby":#installing-gc-patched-ruby
-
h5. Objects
Objects measures the number of objects allocated for the performance test case.
-Mode: Benchmarking, Profiling "Requires GC Patched Ruby":#installing-gc-patched-ruby
-
h5. GC Runs
GC Runs measures the number of times GC was invoked for the performance test case.
-Mode: Benchmarking "Requires GC Patched Ruby":#installing-gc-patched-ruby
-
h5. GC Time
GC Time measures the amount of time spent in GC for the performance test case.
-Mode: Benchmarking "Requires GC Patched Ruby":#installing-gc-patched-ruby
+h5. Metric Availability
+
+h6. Benchmarking
+
+|_.Interpreter|_.Wall Time|_.Process Time|_.CPU Time|_.User Time|_.Memory|_.Objects|_.GC Runs|_.GC Time|
+|_.MRI | yes | yes | yes | no | yes | yes | yes | yes |
+|_.REE | yes | yes | yes | no | yes | yes | yes | yes |
+|_.Rubinius | yes | no | no | no | yes | yes | yes | yes |
+|_.JRuby | yes | no | no | yes | yes | yes | yes | yes |
+
+h6. Profiling
+
+|_.Interpreter|_.Wall Time|_.Process Time|_.CPU Time|_.User Time|_.Memory|_.Objects|_.GC Runs|_.GC Time|
+|_.MRI | yes | yes | no | no | yes | yes | yes | yes |
+|_.REE | yes | yes | no | no | yes | yes | yes | yes |
+|_.Rubinius | yes | no | no | no | no | no | no | no |
+|_.JRuby | yes | no | no | no | no | no | no | no |
+
+NOTE: To profile under JRuby you'll need to run +export JRUBY_OPTS="-Xlaunch.inproc=false --profile.api"+ *before* the performance tests.
h4. Understanding the Output
@@ -215,7 +231,7 @@ Performance tests generate different outputs inside +tmp/performance+ directory
h5(#output-benchmarking). Benchmarking
-In benchmarking mode, performance tests generate two types of outputs:
+In benchmarking mode, performance tests generate two types of outputs.
h6(#output-command-line). Command Line
@@ -225,7 +241,7 @@ This is the primary form of output in benchmarking mode. Example:
BrowsingTest#test_homepage (31 ms warmup)
wall_time: 6 ms
memory: 437.27 KB
- objects: 5514
+ objects: 5,514
gc_runs: 0
gc_time: 19 ms
</shell>
@@ -260,7 +276,7 @@ measurement,created_at,app,rails,ruby,platform
h5(#output-profiling). Profiling
-In profiling mode, you can choose from four types of output.
+In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is dependant on the interpreter in use. A brief description of each type and their availability across interpreters is given below.
h6. Command Line
@@ -270,26 +286,67 @@ This is a very basic form of output in profiling mode:
BrowsingTest#test_homepage (58 ms warmup)
process_time: 63 ms
memory: 832.13 KB
- objects: 7882
+ objects: 7,882
</shell>
h6. Flat
-Flat output shows the total amount of time spent in each method. "Check ruby prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/flat_txt.html.
+Flat output shows the metric—time, memory, etc—measure in each method. "Check Ruby-Prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/flat_txt.html.
h6. Graph
-Graph output shows how long each method takes to run, which methods call it and which methods it calls. "Check ruby prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/graph_txt.html.
+Graph output shows the metric measure in each method, which methods call it and which methods it calls. "Check Ruby-Prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/graph_txt.html.
h6. Tree
Tree output is profiling information in calltree format for use by "kcachegrind":http://kcachegrind.sourceforge.net/html/Home.html and similar tools.
+h6. Output Availability
+
+|_. |_.Flat|_.Graph|_.Tree|
+|_.MRI | yes | yes | yes |
+|_.REE | yes | yes | yes |
+|_.Rubinius | yes | yes | no |
+|_.JRuby | yes | yes | no |
+
h4. Tuning Test Runs
-By default, each performance test is run +4 times+ in benchmarking mode and +1 time+ in profiling. However, test runs can easily be configured.
+Test runs can be tuned by setting the +profile_options+ class variable on your test class.
-WARNING: Performance test configurability is not yet enabled in Rails. But it will be soon.
+<ruby>
+require 'test_helper'
+require 'rails/performance_test_help'
+
+# Profiling results for each test method are written to tmp/performance.
+class BrowsingTest < ActionDispatch::PerformanceTest
+ self.profile_options = { :runs => 5,
+ :metrics => [:wall_time, :memory] }
+
+ def test_homepage
+ get '/'
+ end
+end
+</ruby>
+
+In this example, the test would run 5 times and measure wall time and memory. There are a few configurable options:
+
+|_.Option |_.Description|_.Default|_.Mode|
+|+:runs+ |Number of runs.|Benchmarking: 4, Profiling: 1|Both|
+|+:output+ |Directory to use when writing the results.|+tmp/performance+|Both|
+|+:metrics+ |Metrics to use.|See below.|Both|
+|+:formats+ |Formats to output to.|See below.|Profiling|
+
+Metrics and formats have different defaults depending on the interpreter in use.
+
+|_.Interpreter|_.Mode|_.Default metrics|_.Default formats|
+|/2.MRI/REE |Benchmarking|+[:wall_time, :memory, :objects, :gc_runs, :gc_time]+|N/A|
+|Profiling |+[:process_time, :memory, :objects]+|+[:flat, :graph_html, :call_tree, :call_stack]+|
+|/2.Rubinius|Benchmarking|+[:wall_time, :memory, :objects, :gc_runs, :gc_time]+|N/A|
+|Profiling |+[:wall_time]+|+[:flat, :graph]+|
+|/2.JRuby |Benchmarking|+[:wall_time, :user_time, :memory, :gc_runs, :gc_time]+|N/A|
+|Profiling |+[:wall_time]+|+[:flat, :graph]+|
+
+As you've probably noticed by now, metrics and formats are specified using a symbol array with each name "underscored.":http://api.rubyonrails.org/classes/String.html#method-i-underscore
h4. Performance Test Environment
@@ -303,41 +360,71 @@ Rails.logger.level = ActiveSupport::BufferedLogger::INFO
As +ActionController::Base.perform_caching+ is set to +true+, performance tests will behave much as they do in the +production+ environment.
-h4. Installing GC-Patched Ruby
+h4. Installing GC-Patched MRI
+
+To get the best from Rails' performance tests under MRI, you'll need to build a special Ruby binary with some super powers.
-To get the best from Rails performance tests, you need to build a special Ruby binary with some super powers - "GC patch":http://rubyforge.org/tracker/download.php/1814/7062/17676/3291/ruby186gc.patch for measuring GC Runs/Time and memory/object allocation.
+The recommended patches for each MRI version are:
-The process is fairly straightforward. If you've never compiled a Ruby binary before, follow these steps to build a ruby binary inside your home directory:
+|_.Version|_.Patch|
+|1.8.6|ruby186gc|
+|1.8.7|ruby187gc|
+|1.9.2 and above|gcdata|
-h5. Installation
+All of these can be found on "RVM's _patches_ directory":https://github.com/wayneeseguin/rvm/tree/master/patches/ruby under each specific interpreter version.
-Compile Ruby and apply this "GC Patch":http://rubyforge.org/tracker/download.php/1814/7062/17676/3291/ruby186gc.patch.
+Concerning the installation itself, you can either do this easily by using "RVM":http://rvm.beginrescueend.com or you can build everything from source, which is a little bit harder.
-h5. Download and Extract
+h5. Install Using RVM
+
+The process of installing a patched Ruby interpreter is very easy if you let RVM do the hard work. All of the following RVM commands will provide you with a patched Ruby interpreter:
+
+<shell>
+$ rvm install 1.9.2-p180 --patch gcdata
+$ rvm install 1.8.7 --patch ruby187gc
+$ rvm install 1.9.2-p180 --patch ~/Downloads/downloaded_gcdata_patch.patch
+</shell>
+
+You can even keep your regular interpreter by assigning a name to the patched one:
+
+<shell>
+$ rvm install 1.9.2-p180 --patch gcdata --name gcdata
+$ rvm use 1.9.2-p180 # your regular ruby
+$ rvm use 1.9.2-p180-gcdata # your patched ruby
+</shell>
+
+And it's done! You have installed a patched Ruby interpreter.
+
+h5. Install From Source
+
+This process is a bit more complicated, but straightforward nonetheless. If you've never compiled a Ruby binary before, follow these steps to build a Ruby binary inside your home directory.
+
+h6. Download and Extract
<shell>
$ mkdir rubygc
-$ wget <download the latest stable ruby from ftp://ftp.ruby-lang.org/pub/ruby>
+$ wget <the version you want from ftp://ftp.ruby-lang.org/pub/ruby>
$ tar -xzvf <ruby-version.tar.gz>
$ cd <ruby-version>
</shell>
-h5. Apply the Patch
+h6. Apply the Patch
<shell>
-$ curl http://rubyforge.org/tracker/download.php/1814/7062/17676/3291/ruby186gc.patch | patch -p0
+$ curl http://github.com/wayneeseguin/rvm/raw/master/patches/ruby/1.9.2/p180/gcdata.patch | patch -p0 # if you're on 1.9.2!
+$ curl http://github.com/wayneeseguin/rvm/raw/master/patches/ruby/1.8.7/ruby187gc.patch | patch -p0 # if you're on 1.8.7!
</shell>
-h5. Configure and Install
+h6. Configure and Install
-The following will install ruby in your home directory's +/rubygc+ directory. Make sure to replace +&lt;homedir&gt;+ with a full patch to your actual home directory.
+The following will install Ruby in your home directory's +/rubygc+ directory. Make sure to replace +&lt;homedir&gt;+ with a full patch to your actual home directory.
<shell>
$ ./configure --prefix=/<homedir>/rubygc
$ make && make install
</shell>
-h5. Prepare Aliases
+h6. Prepare Aliases
For convenience, add the following lines in your +~/.profile+:
@@ -349,26 +436,21 @@ alias gcirb='~/rubygc/bin/irb'
alias gcrails='~/rubygc/bin/rails'
</shell>
-h5. Install Rubygems and Dependency Gems
+Don't forget to use your aliases from now on.
-Download "Rubygems":http://rubyforge.org/projects/rubygems and install it from source. Rubygem's README file should have necessary installation instructions.
+h6. Install Rubygems (1.8 only!)
-Additionally, install the following gems:
+Download "Rubygems":http://rubyforge.org/projects/rubygems and install it from source. Rubygem's README file should have necessary installation instructions. Please note that this step isn't necessary if you've installed Ruby 1.9 and above.
-* +rake+
-* +rails+
-* +ruby-prof+
-* +rack+
-* +mysql+
+h4. Using Ruby-Prof on MRI and REE
-If installing +mysql+ fails, you can try to install it manually:
+Add Ruby-Prof to your applications' Gemfile if you want to benchmark/profile under MRI or REE:
-<shell>
-$ gcruby extconf.rb --with-mysql-config
-$ make && make install
-</shell>
+<ruby>
+gem 'ruby-prof', :path => 'git://github.com/wycats/ruby-prof.git'
+</ruby>
-And you're ready to go. Don't forget to use +gcruby+ and +gcrake+ aliases when running the performance tests.
+Now run +bundle install+ and you're ready to go.
h3. Command Line Tools
@@ -376,55 +458,47 @@ Writing performance test cases could be an overkill when you are looking for one
h4. +benchmarker+
-+benchmarker+ is a wrapper around Ruby's "Benchmark":http://ruby-doc.org/core/classes/Benchmark.html standard library.
-
Usage:
<shell>
-$ rails benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ...
-</shell>
-
-Examples:
-
-<shell>
-$ rails benchmarker 10 'Item.all' 'CouchItem.all'
+Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]
+ -r, --runs N Number of runs.
+ Default: 4
+ -o, --output PATH Directory to use when writing the results.
+ Default: tmp/performance
+ -m, --metrics a,b,c Metrics to use.
+ Default: wall_time,memory,objects,gc_runs,gc_time
</shell>
-If the +[times]+ argument is omitted, supplied methods are run just once:
+Example:
<shell>
-$ rails benchmarker 'Item.first' 'Item.last'
+$ rails benchmarker 'Item.all' 'CouchItem.all' --runs 3 --metrics wall_time,memory
</shell>
h4. +profiler+
-+profiler+ is a wrapper around the "ruby-prof":http://ruby-prof.rubyforge.org gem.
-
Usage:
<shell>
-$ rails profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]
+Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]
+ -r, --runs N Number of runs.
+ Default: 1
+ -o, --output PATH Directory to use when writing the results.
+ Default: tmp/performance
+ --metrics a,b,c Metrics to use.
+ Default: process_time,memory,objects
+ -m, --formats x,y,z Formats to output to.
+ Default: flat,graph_html,call_tree
</shell>
-Examples:
+Example:
<shell>
-$ rails profiler 'Item.all'
+$ rails profiler 'Item.all' 'CouchItem.all' --runs 2 --metrics process_time --formats flat
</shell>
-This will profile +Item.all+ in +RubyProf::WALL_TIME+ measure mode. By default, it prints flat output to the shell.
-
-<shell>
-$ rails profiler 'Item.all' 10 graph
-</shell>
-
-This will profile +10.times { Item.all }+ with +RubyProf::WALL_TIME+ measure mode and print graph output to the shell.
-
-If you want to store the output in a file:
-
-<shell>
-$ rails profiler 'Item.all' 10 graph 2> graph.txt
-</shell>
+NOTE: Metrics and formats vary from interpreter to interpreter. Pass +--help+ to each tool to see the defaults for your interpreter.
h3. Helper Methods
@@ -517,12 +591,13 @@ h4. Tutorials and Documentation
h3. Commercial Products
-Rails has been lucky to have two startups dedicated to Rails specific performance tools:
+Rails has been lucky to have a few companies dedicated to Rails-specific performance tools. A couple of those are:
* "New Relic":http://www.newrelic.com
* "Scout":http://scoutapp.com
h3. Changelog
+* March 30, 2011: Documented the recent improvements (multiple interpreters, options, etc) and necessary adjustments. Other minor improvements. "Gonçalo Silva":http://goncalossilva.com.
* January 9, 2009: Complete rewrite by "Pratik":credits.html#lifo
* September 6, 2008: Initial version by Matthew Bergman
diff --git a/railties/lib/rails/commands/benchmarker.rb b/railties/lib/rails/commands/benchmarker.rb
index f230f405c0..b06c915ac3 100644
--- a/railties/lib/rails/commands/benchmarker.rb
+++ b/railties/lib/rails/commands/benchmarker.rb
@@ -1,25 +1,34 @@
-require 'active_support/core_ext/object/inclusion'
+require 'optparse'
+require 'rails/test_help'
+require 'rails/performance_test_help'
-if ARGV.first.in?([nil, "-h", "--help"])
- puts "Usage: rails benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ..."
- exit 1
-end
+ARGV.push('--benchmark') # HAX
+require 'active_support/testing/performance'
+ARGV.pop
-begin
- N = Integer(ARGV.first)
- ARGV.shift
-rescue ArgumentError
- N = 1
+def options
+ options = {}
+ defaults = ActiveSupport::Testing::Performance::DEFAULTS
+
+ OptionParser.new do |opt|
+ opt.banner = "Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]"
+ opt.on('-r', '--runs N', Numeric, 'Number of runs.', "Default: #{defaults[:runs]}") { |r| options[:runs] = r }
+ opt.on('-o', '--output PATH', String, 'Directory to use when writing the results.', "Default: #{defaults[:output]}") { |o| options[:output] = o }
+ opt.on('-m', '--metrics a,b,c', Array, 'Metrics to use.', "Default: #{defaults[:metrics].join(",")}") { |m| options[:metrics] = m.map(&:to_sym) }
+ opt.parse!(ARGV)
+ end
+
+ options
end
-require 'benchmark'
-include Benchmark
-
-# Don't include compilation in the benchmark
-ARGV.each { |expression| eval(expression) }
-
-bm(6) do |x|
- ARGV.each_with_index do |expression, idx|
- x.report("##{idx + 1}") { N.times { eval(expression) } }
+class BenchmarkerTest < ActionDispatch::PerformanceTest
+ self.profile_options = options
+
+ ARGV.each do |expression|
+ eval <<-RUBY
+ def test_#{expression.parameterize('_')}
+ #{expression}
+ end
+ RUBY
end
end
diff --git a/railties/lib/rails/commands/profiler.rb b/railties/lib/rails/commands/profiler.rb
index 7959d8a981..94cf32d32d 100644
--- a/railties/lib/rails/commands/profiler.rb
+++ b/railties/lib/rails/commands/profiler.rb
@@ -1,48 +1,32 @@
-require 'active_support/core_ext/object/inclusion'
+require 'optparse'
+require 'rails/test_help'
+require 'rails/performance_test_help'
+require 'active_support/testing/performance'
-if ARGV.first.in?([nil, "-h", "--help"])
- $stderr.puts "Usage: rails profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]"
- exit(1)
-end
-
-# Define a method to profile.
-if ARGV[1] and ARGV[1].to_i > 1
- eval "def profile_me() #{ARGV[1]}.times { #{ARGV[0]} } end"
-else
- eval "def profile_me() #{ARGV[0]} end"
+def options
+ options = {}
+ defaults = ActiveSupport::Testing::Performance::DEFAULTS
+
+ OptionParser.new do |opt|
+ opt.banner = "Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]"
+ opt.on('-r', '--runs N', Numeric, 'Number of runs.', "Default: #{defaults[:runs]}") { |r| options[:runs] = r }
+ opt.on('-o', '--output PATH', String, 'Directory to use when writing the results.', "Default: #{defaults[:output]}") { |o| options[:output] = o }
+ opt.on('-m', '--metrics a,b,c', Array, 'Metrics to use.', "Default: #{defaults[:metrics].join(",")}") { |m| options[:metrics] = m.map(&:to_sym) }
+ opt.on('-f', '--formats x,y,z', Array, 'Formats to output to.', "Default: #{defaults[:formats].join(",")}") { |m| options[:formats] = m.map(&:to_sym) }
+ opt.parse!(ARGV)
+ end
+
+ options
end
-# Use the ruby-prof extension if available. Fall back to stdlib profiler.
-begin
- begin
- require "ruby-prof"
- $stderr.puts 'Using the ruby-prof extension.'
- RubyProf.measure_mode = RubyProf::WALL_TIME
- RubyProf.start
- profile_me
- results = RubyProf.stop
- if ARGV[2]
- printer_class = RubyProf.const_get((ARGV[2] + "_printer").classify)
- else
- printer_class = RubyProf::FlatPrinter
- end
- printer = printer_class.new(results)
- printer.print($stderr)
- rescue LoadError
- require "prof"
- $stderr.puts 'Using the old ruby-prof extension.'
- Prof.clock_mode = Prof::GETTIMEOFDAY
- Prof.start
- profile_me
- results = Prof.stop
- require 'rubyprof_ext'
- Prof.print_profile(results, $stderr)
+class ProfilerTest < ActionDispatch::PerformanceTest
+ self.profile_options = options
+
+ ARGV.each do |expression|
+ eval <<-RUBY
+ def test_#{expression.parameterize('_')}
+ #{expression}
+ end
+ RUBY
end
-rescue LoadError
- require 'profiler'
- $stderr.puts 'Using the standard Ruby profiler.'
- Profiler__.start_profile
- profile_me
- Profiler__.stop_profile
- Profiler__.print_profile($stderr)
end
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 6a125685d0..e26f73ed8d 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -522,9 +522,9 @@ module Rails
end
initializer :append_assets_path do |app|
- app.config.assets.paths.unshift *paths["vendor/assets"].existent
- app.config.assets.paths.unshift *paths["lib/assets"].existent
- app.config.assets.paths.unshift *paths["app/assets"].existent
+ app.config.assets.paths.unshift(*paths["vendor/assets"].existent)
+ app.config.assets.paths.unshift(*paths["lib/assets"].existent)
+ app.config.assets.paths.unshift(*paths["app/assets"].existent)
end
initializer :prepend_helpers_path do |app|
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index c323df3e95..d31a3262e3 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -278,7 +278,7 @@ module Rails
say args.first.to_s unless options.quiet?
else
args << (self.behavior == :invoke ? :green : :red)
- say_status *args
+ say_status(*args)
end
end
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index a5743762e5..8512b1ca4a 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -165,7 +165,7 @@ module Rails
end
def gem_for_ruby_debugger
- if RUBY_VERSION < "1.9.2"
+ if RUBY_VERSION < "1.9"
"gem 'ruby-debug'"
else
"gem 'ruby-debug19', :require => 'ruby-debug'"
@@ -173,7 +173,7 @@ module Rails
end
def gem_for_turn
- unless RUBY_VERSION < "1.9.2"
+ unless RUBY_VERSION < "1.9.2" || options[:skip_test_unit]
<<-GEMFILE.strip_heredoc
group :test do
# Pretty printed test output
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
index d12b2ff0e5..32546936e3 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
@@ -11,7 +11,7 @@
</div>
<%% end %>
-<% for attribute in attributes -%>
+<% attributes.each do |attribute| -%>
<div class="field">
<%%= f.label :<%= attribute.name %> %><br />
<%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
index a7393cfe18..7b1a2a1841 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
@@ -2,7 +2,7 @@
<table>
<tr>
-<% for attribute in attributes -%>
+<% attributes.each do |attribute| -%>
<th><%= attribute.human_name %></th>
<% end -%>
<th></th>
@@ -12,7 +12,7 @@
<%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
<tr>
-<% for attribute in attributes -%>
+<% attributes.each do |attribute| -%>
<td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>
<% end -%>
<td><%%= link_to 'Show', <%= singular_table_name %> %></td>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
index c0e5ccff1e..67f263efbb 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
@@ -1,6 +1,6 @@
<p id="notice"><%%= notice %></p>
-<% for attribute in attributes -%>
+<% attributes.each do |attribute| -%>
<p>
<b><%= attribute.human_name %>:</b>
<%%= @<%= singular_table_name %>.<%= attribute.name %> %>
diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb
index b26161f1d0..9450894b05 100644
--- a/railties/lib/rails/generators/generated_attribute.rb
+++ b/railties/lib/rails/generators/generated_attribute.rb
@@ -13,12 +13,13 @@ module Rails
def field_type
@field_type ||= case type
- when :integer, :float, :decimal then :text_field
- when :time then :time_select
- when :datetime, :timestamp then :datetime_select
- when :date then :date_select
- when :text then :text_area
- when :boolean then :check_box
+ when :integer then :number_field
+ when :float, :decimal then :text_field
+ when :time then :time_select
+ when :datetime, :timestamp then :datetime_select
+ when :date then :date_select
+ when :text then :text_area
+ when :boolean then :check_box
else
:text_field
end
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index cf317eb21f..7e7f8d2d08 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -13,6 +13,7 @@ module Rails
:desc => "Force using old style hash (:foo => 'bar') on Ruby >= 1.9"
def initialize(args, *options) #:nodoc:
+ @inside_template = nil
# Unfreeze name in case it's given as a frozen string
args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
super
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
index c0c3588be1..4807986333 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
@@ -2,7 +2,10 @@
#
# Get the bindings:
# gem install ruby-frontbase
-
+#
+# Configure Using Gemfile
+# gem 'ruby-frontbase'
+#
development:
adapter: frontbase
host: localhost
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
index df5ef33064..3d689a110a 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
@@ -28,6 +28,9 @@
# On Windows:
# Issue the command: gem install ibm_db
#
+# Configure Using Gemfile
+# gem 'ibm_db'
+#
# For more details on the installation and the connection parameters below,
# please refer to the latest documents at http://rubyforge.org/docman/?group_id=2361
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
index ca807c9f3f..6bf83e86a5 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
@@ -3,6 +3,9 @@
# Install the MySQL driver:
# gem install activerecord-jdbcmysql-adapter
#
+# Configure Using Gemfile
+# gem 'activerecord-jdbcmysql-adapter'
+#
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
index a228aca5d2..0c7f45322b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
@@ -8,6 +8,10 @@
# gem install pg
# Choose the win32 build.
# Install PostgreSQL and put its /bin directory on your path.
+#
+# Configure Using Gemfile
+# gem 'activerecord-jdbcpostgresql-adapter'
+
development:
adapter: jdbcpostgresql
encoding: unicode
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
index 30776b3b4e..6d241d57ae 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
@@ -1,6 +1,9 @@
# SQLite version 3.x
# gem 'activerecord-jdbcsqlite3-adapter'
-
+#
+# Configure Using Gemfile
+# gem 'activerecord-jdbcsqlite3-adapter'
+#
development:
adapter: jdbcsqlite3
database: db/development.sqlite3
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
index 5d28c7c312..cce166c7c3 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
@@ -1,8 +1,11 @@
# MySQL. Versions 4.1 and 5.0 are recommended.
-#
-# Install the MySQL driver:
+#
+# Install the MYSQL driver
# gem install mysql2
#
+# Ensure the MySQL gem is defined in your Gemfile
+# gem 'mysql2'
+#
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
index 4e6391e3d6..467dfc3956 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
@@ -8,6 +8,10 @@
# gem install pg
# Choose the win32 build.
# Install PostgreSQL and put its /bin directory on your path.
+#
+# Configure Using Gemfile
+# gem 'pg'
+#
development:
adapter: postgresql
encoding: unicode
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
index 90d87cc295..51a4dd459d 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
@@ -1,5 +1,8 @@
# SQLite version 3.x
# gem install sqlite3
+#
+# Ensure the SQLite 3 gem is defined in your Gemfile
+# gem 'sqlite3'
development:
adapter: sqlite3
database: db/development.sqlite3
diff --git a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt
index 9a2efa68a7..f75c5dd941 100644
--- a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt
@@ -4,4 +4,4 @@
# Examples:
#
# cities = City.create([{ <%= key_value :name, "'Chicago'" %> }, { <%= key_value :name, "'Copenhagen'" %> }])
-# Mayor.create(<%= key_value :name, "'Daley'" %>, <%= key_value :city, "cities.first" %>)
+# Mayor.create(<%= key_value :name, "'Emanuel'" %>, <%= key_value :city, "cities.first" %>)
diff --git a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb b/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
index 867fc8c985..5d1be041a5 100644
--- a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
+++ b/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
@@ -1,8 +1,11 @@
require 'test_helper'
require 'rails/performance_test_help'
-# Profiling results for each test method are written to tmp/performance.
class BrowsingTest < ActionDispatch::PerformanceTest
+ # Refer to the documentation for all available options
+ # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
+ # :output => 'tmp/performance', :formats => [:flat] }
+
def test_homepage
get '/'
end
diff --git a/railties/lib/rails/generators/rails/controller/templates/controller.rb b/railties/lib/rails/generators/rails/controller/templates/controller.rb
index c61ea4b510..8f5f78556f 100644
--- a/railties/lib/rails/generators/rails/controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/controller/templates/controller.rb
@@ -1,6 +1,6 @@
<% module_namespacing do -%>
class <%= class_name %>Controller < ApplicationController
-<% for action in actions -%>
+<% actions.each do |action| -%>
def <%= action %>
end
diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
index 939c0cd727..9ddb3cae33 100644
--- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
@@ -75,6 +75,7 @@ task :default => :test
def generate_test_dummy(force = false)
opts = (options || {}).slice(*PASSTHROUGH_OPTIONS)
opts[:force] = force
+ opts[:skip_bundle] = true
invoke Rails::Generators::AppGenerator,
[ File.expand_path(dummy_path, destination_root) ], opts
diff --git a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
index 0bc5fd8ca2..509bd60564 100644
--- a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
@@ -7,7 +7,7 @@ class <%= class_name %>ControllerTest < ActionController::TestCase
# assert true
# end
<% else -%>
-<% for action in actions -%>
+<% actions.each do |action| -%>
test "should get <%= action %>" do
get :<%= action %>
assert_response :success
diff --git a/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb
index c05102290c..7e204105a3 100644
--- a/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb
@@ -2,7 +2,7 @@ require 'test_helper'
<% module_namespacing do -%>
class <%= class_name %>Test < ActionMailer::TestCase
-<% for action in actions -%>
+<% actions.each do |action| -%>
test "<%= action %>" do
mail = <%= class_name %>.<%= action %>
assert_equal <%= action.to_s.humanize.inspect %>, mail.subject
diff --git a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml
index 6465a6a6e2..d4138ca2f5 100644
--- a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml
+++ b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml
@@ -2,12 +2,12 @@
<% unless attributes.empty? -%>
one:
-<% for attribute in attributes -%>
+<% attributes.each do |attribute| -%>
<%= attribute.name %>: <%= attribute.default %>
<% end -%>
two:
-<% for attribute in attributes -%>
+<% attributes.each do |attribute| -%>
<%= attribute.name %>: <%= attribute.default %>
<% end -%>
<% else -%>
@@ -20,4 +20,4 @@ one: {}
#
two: {}
# column: value
-<% end -%> \ No newline at end of file
+<% end -%>
diff --git a/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb b/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb
index e827aa918f..14a878328b 100644
--- a/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb
+++ b/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb
@@ -2,7 +2,10 @@ require 'test_helper'
require 'rails/performance_test_help'
class <%= class_name %>Test < ActionDispatch::PerformanceTest
- # Replace this with your real tests.
+ # Refer to the documentation for all available options
+ # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
+ # :output => 'tmp/performance', :formats => [:flat] }
+
def test_homepage
get '/'
end
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index b03dc3132b..98a702f134 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -11,6 +11,10 @@ module ApplicationTests
boot_rails
end
+ def app
+ @app ||= Rails.application
+ end
+
test "assets routes have higher priority" do
app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
@@ -20,8 +24,36 @@ module ApplicationTests
end
RUBY
+ require "#{app_path}/config/environment"
+
+ get "/assets/demo.js"
+ assert_match "alert()", last_response.body
+ end
+
+ test "does not stream session cookies back" do
+ app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
+
+ app_file "config/routes.rb", <<-RUBY
+ AppTemplate::Application.routes.draw do
+ match '/omg', :to => "omg#index"
+ end
+ RUBY
+
+ require "#{app_path}/config/environment"
+
+ class ::OmgController < ActionController::Base
+ def index
+ flash[:cool_story] = true
+ render :text => "ok"
+ end
+ end
+
+ get "/omg"
+ assert_equal 'ok', last_response.body
+
get "/assets/demo.js"
assert_match "alert()", last_response.body
+ assert_equal nil, last_response.headers["Set-Cookie"]
end
end
end
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 43876c0a72..0e27c9606d 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -452,7 +452,7 @@ module ApplicationTests
app_file 'app/models/post.rb', <<-RUBY
class Post
- def self.column_names
+ def self.attribute_names
%w(title)
end
end
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index 68d4c17623..597746c4aa 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -118,8 +118,8 @@ class ActionsTest < Rails::Generators::TestCase
end
assert_file 'config/application.rb' do |content|
- assert_match /# This will be added/, content
- assert_no_match /# This wont be added/, content
+ assert_match(/# This will be added/, content)
+ assert_no_match(/# This wont be added/, content)
end
end
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 9e1d47cd2f..42fe7a7fea 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -155,7 +155,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator [destination_root, "--skip-active-record"]
assert_no_file "config/database.yml"
assert_file "test/test_helper.rb" do |helper_content|
- assert_no_match /fixtures :all/, helper_content
+ assert_no_match(/fixtures :all/, helper_content)
end
assert_file "test/performance/browsing_test.rb"
end
@@ -178,7 +178,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_match %r{^//= require jquery_ujs}, contents
end
assert_file 'Gemfile' do |contents|
- assert_match /^gem 'jquery-rails'/, contents
+ assert_match(/^gem 'jquery-rails'/, contents)
end
end
@@ -190,7 +190,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_match %r{^//= require prototype_ujs}, contents
end
assert_file 'Gemfile' do |contents|
- assert_match /^gem 'prototype-rails'/, contents
+ assert_match(/^gem 'prototype-rails'/, contents)
end
end
@@ -202,9 +202,38 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_inclusion_of_turn_gem_in_gemfile
+ run_generator
+ assert_file "Gemfile" do |contents|
+ assert_match(/gem 'turn'/, contents) unless RUBY_VERSION < '1.9.2'
+ assert_no_match(/gem 'turn'/, contents) if RUBY_VERSION < '1.9.2'
+ end
+ end
+
+ def test_turn_gem_is_not_included_in_gemfile_if_skipping_test_unit
+ run_generator [destination_root, "--skip-test-unit"]
+ assert_file "Gemfile" do |contents|
+ assert_no_match(/gem 'turn'/, contents) unless RUBY_VERSION < '1.9.2'
+ end
+ end
+
+ def test_inclusion_of_ruby_debug
+ run_generator
+ assert_file "Gemfile" do |contents|
+ assert_match(/gem 'ruby-debug'/, contents) if RUBY_VERSION < '1.9'
+ end
+ end
+
+ def test_inclusion_of_ruby_debug19_if_ruby19
+ run_generator
+ assert_file "Gemfile" do |contents|
+ assert_match(/gem 'ruby-debug19', :require => 'ruby-debug'/, contents) unless RUBY_VERSION < '1.9'
+ end
+ end
+
def test_template_from_dir_pwd
FileUtils.cd(Rails.root)
- assert_match /It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"])
+ assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"]))
end
def test_usage_read_from_file
@@ -214,7 +243,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_default_usage
File.expects(:exist?).returns(false)
- assert_match /Create rails files for app generator/, Rails::Generators::AppGenerator.desc
+ assert_match(/Create rails files for app generator/, Rails::Generators::AppGenerator.desc)
end
def test_default_namespace
@@ -241,9 +270,9 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator [destination_root]
assert_file "config/initializers/session_store.rb" do |file|
if RUBY_VERSION < "1.9"
- assert_match /config.session_store :cookie_store, :key => '_.+_session'/, file
+ assert_match(/config.session_store :cookie_store, :key => '_.+_session'/, file)
else
- assert_match /config.session_store :cookie_store, key: '_.+_session'/, file
+ assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file)
end
end
end
@@ -251,7 +280,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_force_old_style_hash
run_generator [destination_root, "--old-style-hash"]
assert_file "config/initializers/session_store.rb" do |file|
- assert_match /config.session_store :cookie_store, :key => '_.+_session'/, file
+ assert_match(/config.session_store :cookie_store, :key => '_.+_session'/, file)
end
end
diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb
index 2dfc91c683..46533b70be 100644
--- a/railties/test/generators/controller_generator_test.rb
+++ b/railties/test/generators/controller_generator_test.rb
@@ -9,7 +9,7 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
def test_help_does_not_show_invoked_generators_options_if_they_already_exist
content = run_generator ["--help"]
- assert_no_match /Helper options\:/, content
+ assert_no_match(/Helper options\:/, content)
end
def test_controller_skeleton_is_created
@@ -20,7 +20,7 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
def test_check_class_collision
Object.send :const_set, :ObjectController, Class.new
content = capture(:stderr){ run_generator ["object"] }
- assert_match /The name 'ObjectController' is either already used in your application or reserved/, content
+ assert_match(/The name 'ObjectController' is either already used in your application or reserved/, content)
ensure
Object.send :remove_const, :ObjectController
end
diff --git a/railties/test/generators/generated_attribute_test.rb b/railties/test/generators/generated_attribute_test.rb
index 064546a3f3..0d2e624f44 100644
--- a/railties/test/generators/generated_attribute_test.rb
+++ b/railties/test/generators/generated_attribute_test.rb
@@ -4,8 +4,12 @@ require 'rails/generators/generated_attribute'
class GeneratedAttributeTest < Rails::Generators::TestCase
include GeneratorsTestHelper
+ def test_field_type_returns_number_field
+ assert_field_type :integer, :number_field
+ end
+
def test_field_type_returns_text_field
- %w(integer float decimal string).each do |attribute_type|
+ %w(float decimal string).each do |attribute_type|
assert_field_type attribute_type, :text_field
end
end
diff --git a/railties/test/generators/helper_generator_test.rb b/railties/test/generators/helper_generator_test.rb
index f0bfebd57f..8da3aa61a4 100644
--- a/railties/test/generators/helper_generator_test.rb
+++ b/railties/test/generators/helper_generator_test.rb
@@ -20,17 +20,17 @@ class HelperGeneratorTest < Rails::Generators::TestCase
def test_logs_if_the_test_framework_cannot_be_found
content = run_generator ["admin", "--test-framework=rspec"]
- assert_match /rspec \[not found\]/, content
+ assert_match(/rspec \[not found\]/, content)
end
def test_check_class_collision
content = capture(:stderr){ run_generator ["object"] }
- assert_match /The name 'ObjectHelper' is either already used in your application or reserved/, content
+ assert_match(/The name 'ObjectHelper' is either already used in your application or reserved/, content)
end
def test_check_class_collision_on_tests
content = capture(:stderr){ run_generator ["another_object"] }
- assert_match /The name 'AnotherObjectHelperTest' is either already used in your application or reserved/, content
+ assert_match(/The name 'AnotherObjectHelperTest' is either already used in your application or reserved/, content)
end
def test_namespaced_and_not_namespaced_helpers
diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb
index bf1cfe5305..139d6b1421 100644
--- a/railties/test/generators/mailer_generator_test.rb
+++ b/railties/test/generators/mailer_generator_test.rb
@@ -9,11 +9,11 @@ class MailerGeneratorTest < Rails::Generators::TestCase
def test_mailer_skeleton_is_created
run_generator
assert_file "app/mailers/notifier.rb" do |mailer|
- assert_match /class Notifier < ActionMailer::Base/, mailer
+ assert_match(/class Notifier < ActionMailer::Base/, mailer)
if RUBY_VERSION < "1.9"
- assert_match /default :from => "from@example.com"/, mailer
+ assert_match(/default :from => "from@example.com"/, mailer)
else
- assert_match /default from: "from@example.com"/, mailer
+ assert_match(/default from: "from@example.com"/, mailer)
end
end
end
@@ -21,35 +21,35 @@ class MailerGeneratorTest < Rails::Generators::TestCase
def test_mailer_with_i18n_helper
run_generator
assert_file "app/mailers/notifier.rb" do |mailer|
- assert_match /en\.notifier\.foo\.subject/, mailer
- assert_match /en\.notifier\.bar\.subject/, mailer
+ assert_match(/en\.notifier\.foo\.subject/, mailer)
+ assert_match(/en\.notifier\.bar\.subject/, mailer)
end
end
def test_check_class_collision
content = capture(:stderr){ run_generator ["object"] }
- assert_match /The name 'Object' is either already used in your application or reserved/, content
+ assert_match(/The name 'Object' is either already used in your application or reserved/, content)
end
def test_invokes_default_test_framework
run_generator
assert_file "test/functional/notifier_test.rb" do |test|
- assert_match /class NotifierTest < ActionMailer::TestCase/, test
- assert_match /test "foo"/, test
- assert_match /test "bar"/, test
+ assert_match(/class NotifierTest < ActionMailer::TestCase/, test)
+ assert_match(/test "foo"/, test)
+ assert_match(/test "bar"/, test)
end
end
def test_invokes_default_template_engine
run_generator
assert_file "app/views/notifier/foo.text.erb" do |view|
- assert_match %r(app/views/notifier/foo\.text\.erb), view
- assert_match /<%= @greeting %>/, view
+ assert_match(%r(app/views/notifier/foo\.text\.erb), view)
+ assert_match(/<%= @greeting %>/, view)
end
assert_file "app/views/notifier/bar.text.erb" do |view|
- assert_match %r(app/views/notifier/bar\.text\.erb), view
- assert_match /<%= @greeting %>/, view
+ assert_match(%r(app/views/notifier/bar\.text\.erb), view)
+ assert_match(/<%= @greeting %>/, view)
end
end
@@ -60,14 +60,14 @@ class MailerGeneratorTest < Rails::Generators::TestCase
def test_logs_if_the_template_engine_cannot_be_found
content = run_generator ["notifier", "foo", "bar", "--template-engine=haml"]
- assert_match /haml \[not found\]/, content
+ assert_match(/haml \[not found\]/, content)
end
def test_mailer_with_namedspaced_mailer
run_generator ["Farm::Animal", "moos"]
assert_file "app/mailers/farm/animal.rb" do |mailer|
- assert_match /class Farm::Animal < ActionMailer::Base/, mailer
- assert_match /en\.farm\.animal\.moos\.subject/, mailer
+ assert_match(/class Farm::Animal < ActionMailer::Base/, mailer)
+ assert_match(/en\.farm\.animal\.moos\.subject/, mailer)
end
assert_file "app/views/farm/animal/moos.text.erb"
end
@@ -78,20 +78,20 @@ class MailerGeneratorTest < Rails::Generators::TestCase
assert_file "app/mailers/notifier.rb" do |mailer|
assert_instance_method :foo, mailer do |foo|
if RUBY_VERSION < "1.9"
- assert_match /mail :to => "to@example.org"/, foo
+ assert_match(/mail :to => "to@example.org"/, foo)
else
- assert_match /mail to: "to@example.org"/, foo
+ assert_match(/mail to: "to@example.org"/, foo)
end
- assert_match /@greeting = "Hi"/, foo
+ assert_match(/@greeting = "Hi"/, foo)
end
assert_instance_method :bar, mailer do |bar|
if RUBY_VERSION < "1.9"
- assert_match /mail :to => "to@example.org"/, bar
+ assert_match(/mail :to => "to@example.org"/, bar)
else
- assert_match /mail to: "to@example.org"/, bar
+ assert_match(/mail to: "to@example.org"/, bar)
end
- assert_match /@greeting = "Hi"/, bar
+ assert_match(/@greeting = "Hi"/, bar)
end
end
end
@@ -99,10 +99,10 @@ class MailerGeneratorTest < Rails::Generators::TestCase
def test_force_old_style_hash
run_generator ["notifier", "foo", "--old-style-hash"]
assert_file "app/mailers/notifier.rb" do |mailer|
- assert_match /default :from => "from@example.com"/, mailer
+ assert_match(/default :from => "from@example.com"/, mailer)
assert_instance_method :foo, mailer do |foo|
- assert_match /mail :to => "to@example.org"/, foo
+ assert_match(/mail :to => "to@example.org"/, foo)
end
end
end
diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb
index 6eecfc8e2e..337257df7d 100644
--- a/railties/test/generators/migration_generator_test.rb
+++ b/railties/test/generators/migration_generator_test.rb
@@ -35,8 +35,8 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
assert_migration "db/migrate/#{migration}.rb" do |content|
assert_method :change, content do |up|
- assert_match /add_column :posts, :title, :string/, up
- assert_match /add_column :posts, :body, :text/, up
+ assert_match(/add_column :posts, :title, :string/, up)
+ assert_match(/add_column :posts, :body, :text/, up)
end
end
end
@@ -47,13 +47,13 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
assert_migration "db/migrate/#{migration}.rb" do |content|
assert_method :up, content do |up|
- assert_match /remove_column :posts, :title/, up
- assert_match /remove_column :posts, :body/, up
+ assert_match(/remove_column :posts, :title/, up)
+ assert_match(/remove_column :posts, :body/, up)
end
assert_method :down, content do |down|
- assert_match /add_column :posts, :title, :string/, down
- assert_match /add_column :posts, :body, :text/, down
+ assert_match(/add_column :posts, :title, :string/, down)
+ assert_match(/add_column :posts, :body, :text/, down)
end
end
end
@@ -64,11 +64,11 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
assert_migration "db/migrate/#{migration}.rb" do |content|
assert_method :up, content do |up|
- assert_match /^\s*$/, up
+ assert_match(/^\s*$/, up)
end
assert_method :down, content do |down|
- assert_match /^\s*$/, down
+ assert_match(/^\s*$/, down)
end
end
end
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index 3d773b4134..8c5ba9926b 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -7,14 +7,14 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_help_shows_invoked_generators_options
content = run_generator ["--help"]
- assert_match /ActiveRecord options:/, content
- assert_match /TestUnit options:/, content
+ assert_match(/ActiveRecord options:/, content)
+ assert_match(/TestUnit options:/, content)
end
def test_model_with_missing_attribute_type
content = capture(:stderr) { run_generator ["post", "title:string", "body"] }
- assert_match /Missing type for attribute 'body'/, content
- assert_match /Example: 'body:string' where string is the type/, content
+ assert_match(/Missing type for attribute 'body'/, content)
+ assert_match(/Example: 'body:string' where string is the type/, content)
end
def test_invokes_default_orm
@@ -100,9 +100,9 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_migration "db/migrate/create_products.rb" do |m|
assert_method :change, m do |up|
- assert_match /create_table :products/, up
- assert_match /t\.string :name/, up
- assert_match /t\.integer :supplier_id/, up
+ assert_match(/create_table :products/, up)
+ assert_match(/t\.string :name/, up)
+ assert_match(/t\.integer :supplier_id/, up)
end
end
end
@@ -138,7 +138,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_migration "db/migrate/create_accounts.rb" do |m|
assert_method :change, m do |up|
- assert_no_match /t.timestamps/, up
+ assert_no_match(/t.timestamps/, up)
end
end
end
@@ -164,7 +164,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_migration_error_is_not_shown_on_revoke
run_generator
error = capture(:stderr){ run_generator ["Account"], :behavior => :revoke }
- assert_no_match /Another migration is already named create_accounts/, error
+ assert_no_match(/Another migration is already named create_accounts/, error)
end
def test_migration_is_removed_on_revoke
@@ -177,7 +177,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
run_generator
old_migration = Dir["#{destination_root}/db/migrate/*_create_accounts.rb"].first
error = capture(:stderr) { run_generator ["Account", "--force"] }
- assert_no_match /Another migration is already named create_accounts/, error
+ assert_no_match(/Another migration is already named create_accounts/, error)
assert_no_file old_migration
assert_migration 'db/migrate/create_accounts.rb'
end
@@ -195,13 +195,13 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_fixture_is_skipped_if_fixture_replacement_is_given
content = run_generator ["account", "-r", "factory_girl"]
- assert_match /factory_girl \[not found\]/, content
+ assert_match(/factory_girl \[not found\]/, content)
assert_no_file "test/fixtures/accounts.yml"
end
def test_check_class_collision
content = capture(:stderr){ run_generator ["object"] }
- assert_match /The name 'Object' is either already used in your application or reserved/, content
+ assert_match(/The name 'Object' is either already used in your application or reserved/, content)
end
def test_index_is_added_for_belongs_to_association
@@ -209,7 +209,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_migration "db/migrate/create_accounts.rb" do |m|
assert_method :change, m do |up|
- assert_match /add_index/, up
+ assert_match(/add_index/, up)
end
end
end
@@ -219,7 +219,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_migration "db/migrate/create_accounts.rb" do |m|
assert_method :change, m do |up|
- assert_match /add_index/, up
+ assert_match(/add_index/, up)
end
end
end
@@ -229,7 +229,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_migration "db/migrate/create_accounts.rb" do |m|
assert_method :change, m do |up|
- assert_no_match /add_index/, up
+ assert_no_match(/add_index/, up)
end
end
end
@@ -239,9 +239,8 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_migration "db/migrate/create_accounts.rb" do |m|
assert_method :change, m do |up|
- assert_no_match /add_index/, up
+ assert_no_match(/add_index/, up)
end
end
end
-
end
diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb
index 38f024f061..6f8a9b4280 100644
--- a/railties/test/generators/namespaced_generators_test.rb
+++ b/railties/test/generators/namespaced_generators_test.rb
@@ -161,12 +161,12 @@ class NamespacedMailerGeneratorTest < NamespacedGeneratorTestCase
def test_mailer_skeleton_is_created
run_generator
assert_file "app/mailers/test_app/notifier.rb" do |mailer|
- assert_match /module TestApp/, mailer
- assert_match /class Notifier < ActionMailer::Base/, mailer
+ assert_match(/module TestApp/, mailer)
+ assert_match(/class Notifier < ActionMailer::Base/, mailer)
if RUBY_VERSION < "1.9"
- assert_match /default :from => "from@example.com"/, mailer
+ assert_match(/default :from => "from@example.com"/, mailer)
else
- assert_match /default from: "from@example.com"/, mailer
+ assert_match(/default from: "from@example.com"/, mailer)
end
end
end
@@ -174,31 +174,31 @@ class NamespacedMailerGeneratorTest < NamespacedGeneratorTestCase
def test_mailer_with_i18n_helper
run_generator
assert_file "app/mailers/test_app/notifier.rb" do |mailer|
- assert_match /en\.notifier\.foo\.subject/, mailer
- assert_match /en\.notifier\.bar\.subject/, mailer
+ assert_match(/en\.notifier\.foo\.subject/, mailer)
+ assert_match(/en\.notifier\.bar\.subject/, mailer)
end
end
def test_invokes_default_test_framework
run_generator
assert_file "test/functional/test_app/notifier_test.rb" do |test|
- assert_match /module TestApp/, test
- assert_match /class NotifierTest < ActionMailer::TestCase/, test
- assert_match /test "foo"/, test
- assert_match /test "bar"/, test
+ assert_match(/module TestApp/, test)
+ assert_match(/class NotifierTest < ActionMailer::TestCase/, test)
+ assert_match(/test "foo"/, test)
+ assert_match(/test "bar"/, test)
end
end
def test_invokes_default_template_engine
run_generator
assert_file "app/views/test_app/notifier/foo.text.erb" do |view|
- assert_match %r(app/views/test_app/notifier/foo\.text\.erb), view
- assert_match /<%= @greeting %>/, view
+ assert_match(%r(app/views/test_app/notifier/foo\.text\.erb), view)
+ assert_match(/<%= @greeting %>/, view)
end
assert_file "app/views/test_app/notifier/bar.text.erb" do |view|
- assert_match %r(app/views/test_app/notifier/bar\.text\.erb), view
- assert_match /<%= @greeting %>/, view
+ assert_match(%r(app/views/test_app/notifier/bar\.text\.erb), view)
+ assert_match(/<%= @greeting %>/, view)
end
end
diff --git a/railties/test/generators/observer_generator_test.rb b/railties/test/generators/observer_generator_test.rb
index 45fe8dfbd3..afcee0a2dc 100644
--- a/railties/test/generators/observer_generator_test.rb
+++ b/railties/test/generators/observer_generator_test.rb
@@ -22,6 +22,6 @@ class ObserverGeneratorTest < Rails::Generators::TestCase
def test_logs_if_the_test_framework_cannot_be_found
content = run_generator ["account", "--test-framework=rspec"]
- assert_match /rspec \[not found\]/, content
+ assert_match(/rspec \[not found\]/, content)
end
end
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index e6686a6af4..5c0774ddbd 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -32,7 +32,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
def test_check_class_collision
content = capture(:stderr){ run_generator ["object"] }
- assert_match /The name 'Object' is either already used in your application or reserved/, content
+ assert_match(/The name 'Object' is either already used in your application or reserved/, content)
end
def test_invokes_default_test_framework
@@ -44,7 +44,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
def test_logs_if_the_test_framework_cannot_be_found
content = nil
silence(:stderr) { content = run_generator ["plugin_fu", "--test-framework=rspec"] }
- assert_match /rspec \[not found\]/, content
+ assert_match(/rspec \[not found\]/, content)
end
def test_creates_tasks_if_required
@@ -66,6 +66,6 @@ class PluginGeneratorTest < Rails::Generators::TestCase
def test_deprecation
output = capture(:stderr) { run_generator }
- assert_match /Plugin generator is deprecated, please use 'rails plugin new' command to generate plugin structure./, output
+ assert_match(/Plugin generator is deprecated, please use 'rails plugin new' command to generate plugin structure./, output)
end
end
diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb
index 2af728e766..297ac5d238 100644
--- a/railties/test/generators/plugin_new_generator_test.rb
+++ b/railties/test/generators/plugin_new_generator_test.rb
@@ -95,6 +95,11 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
assert_file "test/dummy/config/database.yml", /postgres/
end
+ def test_generation_runs_bundle_install_with_full_and_mountable
+ result = run_generator [destination_root, "--mountable", "--full"]
+ assert_equal 1, result.scan("Your bundle is complete").size
+ end
+
def test_skipping_javascripts_without_mountable_option
run_generator
assert_no_file "app/assets/javascripts/application.js"
diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb
index 71b3619351..73804dae45 100644
--- a/railties/test/generators/resource_generator_test.rb
+++ b/railties/test/generators/resource_generator_test.rb
@@ -9,8 +9,8 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
def test_help_with_inherited_options
content = run_generator ["--help"]
- assert_match /ActiveRecord options:/, content
- assert_match /TestUnit options:/, content
+ assert_match(/ActiveRecord options:/, content)
+ assert_match(/TestUnit options:/, content)
end
def test_files_from_inherited_invocation
@@ -55,7 +55,7 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
run_generator
assert_file "config/routes.rb" do |route|
- assert_match /resources :accounts$/, route
+ assert_match(/resources :accounts$/, route)
end
end
@@ -63,19 +63,19 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
content = run_generator ["accounts".freeze]
assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
assert_file "test/unit/account_test.rb", /class AccountTest/
- assert_match /Plural version of the model detected, using singularized version. Override with --force-plural./, content
+ assert_match(/Plural version of the model detected, using singularized version. Override with --force-plural./, content)
end
def test_plural_names_can_be_forced
content = run_generator ["accounts", "--force-plural"]
assert_file "app/models/accounts.rb", /class Accounts < ActiveRecord::Base/
assert_file "test/unit/accounts_test.rb", /class AccountsTest/
- assert_no_match /Plural version of the model detected/, content
+ assert_no_match(/Plural version of the model detected/, content)
end
def test_mass_nouns_do_not_throw_warnings
content = run_generator ["sheep".freeze]
- assert_no_match /Plural version of the model detected/, content
+ assert_no_match(/Plural version of the model detected/, content)
end
def test_route_is_removed_on_revoke
@@ -83,7 +83,7 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
run_generator ["account"], :behavior => :revoke
assert_file "config/routes.rb" do |route|
- assert_no_match /resources :accounts$/, route
+ assert_no_match(/resources :accounts$/, route)
end
end
end
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index c7f45a807d..65b30b9fbd 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -14,39 +14,39 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
run_generator
assert_file "app/controllers/users_controller.rb" do |content|
- assert_match /class UsersController < ApplicationController/, content
+ assert_match(/class UsersController < ApplicationController/, content)
assert_instance_method :index, content do |m|
- assert_match /@users = User\.all/, m
+ assert_match(/@users = User\.all/, m)
end
assert_instance_method :show, content do |m|
- assert_match /@user = User\.find\(params\[:id\]\)/, m
+ assert_match(/@user = User\.find\(params\[:id\]\)/, m)
end
assert_instance_method :new, content do |m|
- assert_match /@user = User\.new/, m
+ assert_match(/@user = User\.new/, m)
end
assert_instance_method :edit, content do |m|
- assert_match /@user = User\.find\(params\[:id\]\)/, m
+ assert_match(/@user = User\.find\(params\[:id\]\)/, m)
end
assert_instance_method :create, content do |m|
- assert_match /@user = User\.new\(params\[:user\]\)/, m
- assert_match /@user\.save/, m
- assert_match /@user\.errors/, m
+ assert_match(/@user = User\.new\(params\[:user\]\)/, m)
+ assert_match(/@user\.save/, m)
+ assert_match(/@user\.errors/, m)
end
assert_instance_method :update, content do |m|
- assert_match /@user = User\.find\(params\[:id\]\)/, m
- assert_match /@user\.update_attributes\(params\[:user\]\)/, m
- assert_match /@user\.errors/, m
+ assert_match(/@user = User\.find\(params\[:id\]\)/, m)
+ assert_match(/@user\.update_attributes\(params\[:user\]\)/, m)
+ assert_match(/@user\.errors/, m)
end
assert_instance_method :destroy, content do |m|
- assert_match /@user = User\.find\(params\[:id\]\)/, m
- assert_match /@user\.destroy/, m
+ assert_match(/@user = User\.find\(params\[:id\]\)/, m)
+ assert_match(/@user\.destroy/, m)
end
end
end
@@ -73,8 +73,8 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
run_generator
assert_file "test/functional/users_controller_test.rb" do |content|
- assert_match /class UsersControllerTest < ActionController::TestCase/, content
- assert_match /test "should get index"/, content
+ assert_match(/class UsersControllerTest < ActionController::TestCase/, content)
+ assert_match(/test "should get index"/, content)
end
end
@@ -93,10 +93,10 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
run_generator ["User", "--orm=unknown"]
assert_file "app/controllers/users_controller.rb" do |content|
- assert_match /class UsersController < ApplicationController/, content
+ assert_match(/class UsersController < ApplicationController/, content)
assert_instance_method :index, content do |m|
- assert_match /@users = User\.all/, m
+ assert_match(/@users = User\.all/, m)
end
end
end
@@ -112,11 +112,11 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
run_generator ["User", "--orm=unknown"]
assert_file "app/controllers/users_controller.rb" do |content|
- assert_match /class UsersController < ApplicationController/, content
+ assert_match(/class UsersController < ApplicationController/, content)
assert_instance_method :index, content do |m|
- assert_match /@users = User\.find\(:all\)/, m
- assert_no_match /@users = User\.all/, m
+ assert_match(/@users = User\.find\(:all\)/, m)
+ assert_no_match(/@users = User\.all/, m)
end
end
ensure
@@ -127,9 +127,9 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
run_generator
assert_file "app/controllers/users_controller.rb" do |content|
if RUBY_VERSION < "1.9"
- assert_match /\{ render :action => "new" \}/, content
+ assert_match(/\{ render :action => "new" \}/, content)
else
- assert_match /\{ render action: "new" \}/, content
+ assert_match(/\{ render action: "new" \}/, content)
end
end
end
@@ -137,7 +137,7 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
def test_force_old_style_hash
run_generator ["User", "--old-style-hash"]
assert_file "app/controllers/users_controller.rb" do |content|
- assert_match /\{ render :action => "new" \}/, content
+ assert_match(/\{ render :action => "new" \}/, content)
end
end
end
diff --git a/railties/test/generators/session_migration_generator_test.rb b/railties/test/generators/session_migration_generator_test.rb
index 9fee948d7c..b590047ff0 100644
--- a/railties/test/generators/session_migration_generator_test.rb
+++ b/railties/test/generators/session_migration_generator_test.rb
@@ -18,8 +18,8 @@ class SessionMigrationGeneratorTest < Rails::Generators::TestCase
ActiveRecord::SessionStore::Session.table_name = "custom_table_name"
run_generator
assert_migration "db/migrate/add_sessions_table.rb" do |migration|
- assert_match /class AddSessionsTable < ActiveRecord::Migration/, migration
- assert_match /create_table :custom_table_name/, migration
+ assert_match(/class AddSessionsTable < ActiveRecord::Migration/, migration)
+ assert_match(/create_table :custom_table_name/, migration)
end
ensure
ActiveRecord::SessionStore::Session.table_name = "sessions"
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index 99c9d790eb..1264ac7764 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -28,7 +28,7 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_help_when_a_generator_with_required_arguments_is_invoked_without_arguments
output = capture(:stdout){ Rails::Generators.invoke :model, [] }
- assert_match /Description:/, output
+ assert_match(/Description:/, output)
end
def test_should_give_higher_preference_to_rails_generators
@@ -90,8 +90,8 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_find_by_namespace_show_warning_if_generator_cant_be_loaded
output = capture(:stderr) { Rails::Generators.find_by_namespace(:wrong) }
- assert_match /\[WARNING\] Could not load generator/, output
- assert_match /Rails 2\.x generator/, output
+ assert_match(/\[WARNING\] Could not load generator/, output)
+ assert_match(/Rails 2\.x generator/, output)
end
def test_invoke_with_nested_namespaces
@@ -104,38 +104,38 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_rails_generators_help_with_builtin_information
output = capture(:stdout){ Rails::Generators.help }
- assert_match /Rails:/, output
- assert_match /^ model$/, output
- assert_match /^ scaffold_controller$/, output
- assert_no_match /^ app$/, output
+ assert_match(/Rails:/, output)
+ assert_match(/^ model$/, output)
+ assert_match(/^ scaffold_controller$/, output)
+ assert_no_match(/^ app$/, output)
end
def test_rails_generators_help_does_not_include_app_nor_plugin_new
output = capture(:stdout){ Rails::Generators.help }
- assert_no_match /app/, output
- assert_no_match /plugin_new/, output
+ assert_no_match(/app/, output)
+ assert_no_match(/plugin_new/, output)
end
def test_rails_generators_with_others_information
output = capture(:stdout){ Rails::Generators.help }
- assert_match /Fixjour:/, output
- assert_match /^ fixjour$/, output
+ assert_match(/Fixjour:/, output)
+ assert_match(/^ fixjour$/, output)
end
def test_rails_generators_does_not_show_active_record_hooks
output = capture(:stdout){ Rails::Generators.help }
- assert_match /ActiveRecord:/, output
- assert_match /^ active_record:fixjour$/, output
+ assert_match(/ActiveRecord:/, output)
+ assert_match(/^ active_record:fixjour$/, output)
end
def test_default_banner_should_show_generator_namespace
klass = Rails::Generators.find_by_namespace(:foobar)
- assert_match /^rails generate foobar:foobar/, klass.banner
+ assert_match(/^rails generate foobar:foobar/, klass.banner)
end
def test_default_banner_should_not_show_rails_generator_namespace
klass = Rails::Generators.find_by_namespace(:model)
- assert_match /^rails generate model/, klass.banner
+ assert_match(/^rails generate model/, klass.banner)
end
def test_no_color_sets_proper_shell