aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2009-10-19 12:33:36 -0700
committerJeremy Kemper <jeremy@bitsweat.net>2009-10-19 12:33:36 -0700
commita49c3b03650b3193cc9440a3b219ab7f19326297 (patch)
treedd68d637a074bc08d1328d780aeb092b2a4c8874
parent028911ad00e7f7733064a80393a1548401bba7af (diff)
parent1ac5cf478825391071d34ec3d7f294fe28c0fceb (diff)
downloadrails-a49c3b03650b3193cc9440a3b219ab7f19326297.tar.gz
rails-a49c3b03650b3193cc9440a3b219ab7f19326297.tar.bz2
rails-a49c3b03650b3193cc9440a3b219ab7f19326297.zip
Merge branch 'master' of github.com:rails/rails
-rw-r--r--actionmailer/test/url_test.rb44
-rw-r--r--actionpack/test/controller/routing_test.rb293
-rw-r--r--actionpack/test/controller/url_rewriter_test.rb10
-rw-r--r--activerecord/lib/active_record.rb16
-rw-r--r--activerecord/lib/active_record/attribute_methods/before_type_cast.rb13
-rw-r--r--activerecord/lib/active_record/attribute_methods/query.rb20
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb49
-rw-r--r--activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb48
-rw-r--r--activerecord/lib/active_record/attribute_methods/write.rb9
-rw-r--r--activerecord/lib/active_record/attributes.rb37
-rw-r--r--activerecord/lib/active_record/attributes/aliasing.rb42
-rw-r--r--activerecord/lib/active_record/attributes/store.rb15
-rw-r--r--activerecord/lib/active_record/attributes/typecasting.rb117
-rwxr-xr-xactiverecord/lib/active_record/base.rb38
-rw-r--r--activerecord/lib/active_record/types.rb38
-rw-r--r--activerecord/lib/active_record/types/number.rb30
-rw-r--r--activerecord/lib/active_record/types/object.rb37
-rw-r--r--activerecord/lib/active_record/types/serialize.rb33
-rw-r--r--activerecord/lib/active_record/types/time_with_zone.rb20
-rw-r--r--activerecord/lib/active_record/types/unknown.rb37
-rw-r--r--activerecord/test/cases/attributes/aliasing_test.rb20
-rw-r--r--activerecord/test/cases/attributes/typecasting_test.rb120
-rw-r--r--activerecord/test/cases/types/number_test.rb30
-rw-r--r--activerecord/test/cases/types/object_test.rb24
-rw-r--r--activerecord/test/cases/types/serialize_test.rb20
-rw-r--r--activerecord/test/cases/types/time_with_zone_test.rb42
-rw-r--r--activerecord/test/cases/types/unknown_test.rb29
-rw-r--r--activerecord/test/cases/types_test.rb32
-rw-r--r--railties/lib/rails/application.rb81
-rw-r--r--railties/lib/rails/backtrace_cleaner.rb4
-rw-r--r--railties/lib/rails/configuration.rb21
-rw-r--r--railties/lib/rails/deprecation.rb10
-rw-r--r--railties/lib/rails/gem_builder.rb21
-rw-r--r--railties/lib/rails/gem_dependency.rb311
-rw-r--r--railties/lib/rails/generators.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile17
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/Rakefile2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb9
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/boot.rb152
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environment.rb6
-rw-r--r--railties/lib/rails/initializer.rb1
-rw-r--r--railties/lib/rails/plugin/locator.rb2
-rw-r--r--railties/lib/rails/tasks.rb1
-rw-r--r--railties/lib/rails/tasks/framework.rake5
-rw-r--r--railties/lib/rails/tasks/gems.rake78
-rw-r--r--railties/lib/rails/tasks/statistics.rake5
-rw-r--r--railties/lib/rails/vendor_gem_source_index.rb140
-rw-r--r--railties/test/application/configuration_test.rb1
-rw-r--r--railties/test/application/generators_test.rb1
-rw-r--r--railties/test/application/initializer_test.rb1
-rw-r--r--railties/test/application/notifications_test.rb2
-rw-r--r--railties/test/application/plugins_test.rb1
-rw-r--r--railties/test/backtrace_cleaner_test.rb8
-rw-r--r--railties/test/gem_dependency_test.rb220
-rw-r--r--railties/test/generators/actions_test.rb2
-rw-r--r--railties/test/generators/app_generator_test.rb4
-rw-r--r--railties/test/generators_test.rb9
-rw-r--r--railties/test/initializer/check_ruby_version_test.rb1
-rw-r--r--railties/test/initializer/initialize_i18n_test.rb1
-rw-r--r--railties/test/initializer/path_test.rb1
-rw-r--r--railties/test/isolation/abstract_unit.rb23
-rw-r--r--railties/test/rails_info_controller_test.rb12
63 files changed, 988 insertions, 1432 deletions
diff --git a/actionmailer/test/url_test.rb b/actionmailer/test/url_test.rb
index 71286bd1cf..2224f6321c 100644
--- a/actionmailer/test/url_test.rb
+++ b/actionmailer/test/url_test.rb
@@ -1,9 +1,9 @@
require 'abstract_unit'
class TestMailer < ActionMailer::Base
-
+
default_url_options[:host] = 'www.basecamphq.com'
-
+
def signed_up_with_url(recipient)
@recipients = recipient
@subject = "[Signed up] Welcome #{recipient}"
@@ -52,25 +52,27 @@ class ActionMailerUrlTest < Test::Unit::TestCase
end
def test_signed_up_with_url
- ActionController::Routing::Routes.draw do |map|
- map.connect ':controller/:action/:id'
- map.welcome 'welcome', :controller=>"foo", :action=>"bar"
- end
+ ActionController::Routing.use_controllers! ['welcome'] do
+ ActionController::Routing::Routes.draw do |map|
+ map.connect ':controller/:action/:id'
+ map.welcome 'welcome', :controller=>"foo", :action=>"bar"
+ end
- expected = new_mail
- expected.to = @recipient
- expected.subject = "[Signed up] Welcome #{@recipient}"
- expected.body = "Hello there, \n\nMr. #{@recipient}. Please see our greeting at http://example.com/welcome/greeting http://www.basecamphq.com/welcome\n\n<img alt=\"Somelogo\" src=\"/images/somelogo.png\" />"
- expected.from = "system@loudthinking.com"
- expected.date = Time.local(2004, 12, 12)
-
- created = nil
- assert_nothing_raised { created = TestMailer.create_signed_up_with_url(@recipient) }
- assert_not_nil created
- assert_equal expected.encoded, created.encoded
-
- assert_nothing_raised { TestMailer.deliver_signed_up_with_url(@recipient) }
- assert_not_nil ActionMailer::Base.deliveries.first
- assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded
+ expected = new_mail
+ expected.to = @recipient
+ expected.subject = "[Signed up] Welcome #{@recipient}"
+ expected.body = "Hello there, \n\nMr. #{@recipient}. Please see our greeting at http://example.com/welcome/greeting http://www.basecamphq.com/welcome\n\n<img alt=\"Somelogo\" src=\"/images/somelogo.png\" />"
+ expected.from = "system@loudthinking.com"
+ expected.date = Time.local(2004, 12, 12)
+
+ created = nil
+ assert_nothing_raised { created = TestMailer.create_signed_up_with_url(@recipient) }
+ assert_not_nil created
+ assert_equal expected.encoded, created.encoded
+
+ assert_nothing_raised { TestMailer.deliver_signed_up_with_url(@recipient) }
+ assert_not_nil ActionMailer::Base.deliveries.first
+ assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded
+ end
end
end
diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb
index 7c88520bac..cbbd7e6951 100644
--- a/actionpack/test/controller/routing_test.rb
+++ b/actionpack/test/controller/routing_test.rb
@@ -22,7 +22,6 @@ end
# See RFC 3986, section 3.3 for allowed path characters.
class UriReservedCharactersRoutingTest < Test::Unit::TestCase
def setup
- ActionController::Routing.use_controllers! ['controller']
@set = ActionController::Routing::RouteSet.new
@set.draw do |map|
map.connect ':controller/:action/:variable/*additional'
@@ -36,8 +35,9 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase
end
def test_route_generation_escapes_unsafe_path_characters
- assert_equal "/contr#{@segment}oller/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2",
- @set.generate(:controller => "contr#{@segment}oller",
+ @set.generate(:controller => "content", :action => "act#{@segment}ion", :variable => "variable", :additional => "foo")
+ assert_equal "/content/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2",
+ @set.generate(:controller => "content",
:action => "act#{@segment}ion",
:variable => "var#{@segment}iable",
:additional => ["add#{@segment}itional-1", "add#{@segment}itional-2"])
@@ -52,7 +52,7 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase
end
def test_route_generation_allows_passing_non_string_values_to_generated_helper
- assert_equal "/controller/action/variable/1/2", @set.generate(:controller => "controller",
+ assert_equal "/content/action/variable/1/2", @set.generate(:controller => "content",
:action => "action",
:variable => "variable",
:additional => [1, 2])
@@ -407,35 +407,7 @@ class LegacyRouteSetTests < Test::Unit::TestCase
rs.draw do |map|
map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
end
- exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") }
- assert_match /^post_url failed to generate/, exception.message
- from_match = exception.message.match(/from \{[^\}]+\}/).to_s
- assert_match /:bad_param=>"foo"/, from_match
- assert_match /:action=>"show"/, from_match
- assert_match /:controller=>"post"/, from_match
-
- expected_match = exception.message.match(/expected: \{[^\}]+\}/).to_s
- assert_no_match /:bad_param=>"foo"/, expected_match
- assert_match /:action=>"show"/, expected_match
- assert_match /:controller=>"post"/, expected_match
-
- diff_match = exception.message.match(/diff: \{[^\}]+\}/).to_s
- assert_match /:bad_param=>"foo"/, diff_match
- assert_no_match /:action=>"show"/, diff_match
- assert_no_match /:controller=>"post"/, diff_match
- end
-
- # this specifies the case where your formerly would get a very confusing error message with an empty diff
- def test_should_have_better_error_message_when_options_diff_is_empty
- rs.draw do |map|
- map.content '/content/:query', :controller => 'content', :action => 'show'
- end
-
- exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") }
- assert_match %r[:action=>"show"], exception.message
- assert_match %r[:controller=>"content"], exception.message
- assert_match %r[you may have ambiguous routes, or you may need to supply additional parameters for this route], exception.message
- assert_match %r[content_url has the following required parameters: \["content", :query\] - are they all satisfied?], exception.message
+ assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") }
end
def test_dynamic_path_allowed
@@ -503,17 +475,6 @@ class LegacyRouteSetTests < Test::Unit::TestCase
assert_equal '/content', rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'})
end
- def test_recognition_with_uppercase_controller_name
- @rs.draw {|m| m.connect ':controller/:action/:id' }
- assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/Content"))
- assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/ConTent/list"))
- assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/CONTENT/show/10"))
-
- # these used to work, before the routes rewrite, but support for this was pulled in the new version...
- #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/NewsFeed"))
- #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/News_Feed"))
- end
-
def test_requirement_should_prevent_optional_id
rs.draw do |map|
map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
@@ -760,12 +721,9 @@ class RouteSetTest < ActiveSupport::TestCase
def default_route_set
@default_route_set ||= begin
- set = nil
- ActionController::Routing.with_controllers(['accounts']) do
- set = ROUTING::RouteSet.new
- set.draw do |map|
- map.connect '/:controller/:action/:id/'
- end
+ set = ROUTING::RouteSet.new
+ set.draw do |map|
+ map.connect '/:controller/:action/:id/'
end
set
end
@@ -953,44 +911,38 @@ class RouteSetTest < ActiveSupport::TestCase
end
def test_draw_default_route
- ActionController::Routing.with_controllers(['users']) do
- set.draw do |map|
- map.connect '/:controller/:action/:id'
- end
+ set.draw do |map|
+ map.connect '/:controller/:action/:id'
+ end
- assert_equal 1, set.routes.size
+ assert_equal 1, set.routes.size
- assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10)
- assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10)
+ assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10)
+ assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10)
- assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10'))
- assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/'))
- end
+ assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10'))
+ assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/'))
end
def test_draw_default_route_with_default_controller
- ActionController::Routing.with_controllers(['users']) do
- set.draw do |map|
- map.connect '/:controller/:action/:id', :controller => 'users'
- end
- assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/'))
+ set.draw do |map|
+ map.connect '/:controller/:action/:id', :controller => 'users'
end
+ assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/'))
end
def test_route_with_parameter_shell
- ActionController::Routing.with_controllers(['users', 'pages']) do
- set.draw do |map|
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
- map.connect '/:controller/:action/:id'
- end
+ set.draw do |map|
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
+ map.connect '/:controller/:action/:id'
+ end
- assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages'))
- assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index'))
- assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list'))
+ assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages'))
+ assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index'))
+ assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list'))
- assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10'))
- assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
- end
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10'))
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
end
def test_route_requirements_with_anchor_chars_are_invalid
@@ -1019,14 +971,6 @@ class RouteSetTest < ActiveSupport::TestCase
map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\z/
end
end
- assert_nothing_raised do
- set.draw do |map|
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/, :name => /^(david|jamis)/
- end
- assert_raise ActionController::RoutingError do
- set.generate :controller => 'pages', :action => 'show', :id => 10
- end
- end
end
def test_route_requirements_with_invalid_http_method_is_invalid
@@ -1053,19 +997,6 @@ class RouteSetTest < ActiveSupport::TestCase
end
end
- def test_non_path_route_requirements_match_all
- set.draw do |map|
- map.connect 'page/37s', :controller => 'pages', :action => 'show', :name => /(jamis|david)/
- end
- assert_equal '/page/37s', set.generate(:controller => 'pages', :action => 'show', :name => 'jamis')
- assert_raise ActionController::RoutingError do
- set.generate(:controller => 'pages', :action => 'show', :name => 'not_jamis')
- end
- assert_raise ActionController::RoutingError do
- set.generate(:controller => 'pages', :action => 'show', :name => 'nor_jamis_and_david')
- end
- end
-
def test_recognize_with_encoded_id_and_regex
set.draw do |map|
map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /[a-zA-Z0-9\+]+/
@@ -1375,20 +1306,20 @@ class RouteSetTest < ActiveSupport::TestCase
set.draw do |map|
map.connect ':controller/:action/:id'
end
- assert_equal '/post', set.generate(
- {:controller => 'post', :action => 'index'},
- {:controller => 'post', :action => 'show', :id => '10'}
+ assert_equal '/books', set.generate(
+ {:controller => 'books', :action => 'index'},
+ {:controller => 'books', :action => 'show', :id => '10'}
)
end
def test_query_params_will_be_shown_when_recalled
set.draw do |map|
- map.connect 'show_post/:parameter', :controller => 'post', :action => 'show'
+ map.connect 'show_weblog/:parameter', :controller => 'weblog', :action => 'show'
map.connect ':controller/:action/:id'
end
- assert_equal '/post/edit?parameter=1', set.generate(
+ assert_equal '/weblog/edit?parameter=1', set.generate(
{:action => 'edit', :parameter => 1},
- {:controller => 'post', :action => 'show', :parameter => 1}
+ {:controller => 'weblog', :action => 'show', :parameter => 1}
)
end
@@ -1410,23 +1341,9 @@ class RouteSetTest < ActiveSupport::TestCase
def test_expiry_determination_should_consider_values_with_to_param
set.draw { |map| map.connect 'projects/:project_id/:controller/:action' }
- assert_equal '/projects/1/post/show', set.generate(
+ assert_equal '/projects/1/weblog/show', set.generate(
{:action => 'show', :project_id => 1},
- {:controller => 'post', :action => 'show', :project_id => '1'})
- end
-
- def test_generate_all
- set.draw do |map|
- map.connect 'show_post/:id', :controller => 'post', :action => 'show'
- map.connect ':controller/:action/:id'
- end
- all = set.generate(
- {:action => 'show', :id => 10, :generate_all => true},
- {:controller => 'post', :action => 'show'}
- )
- assert_equal 2, all.length
- assert_equal '/show_post/10', all.first
- assert_equal '/post/show/10', all.last
+ {:controller => 'weblog', :action => 'show', :project_id => '1'})
end
def test_named_route_in_nested_resource
@@ -1603,101 +1520,86 @@ class RouteSetTest < ActiveSupport::TestCase
assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/named'))
end
-
def test_interpolation_chunk_should_respect_raw
- ActionController::Routing.with_controllers(['hello']) do
- set.draw do |map|
- map.connect '/Hello World', :controller => 'hello'
- end
-
- assert_equal '/Hello%20World', set.generate(:controller => 'hello')
- assert_equal({:controller => "hello", :action => "index"}, set.recognize_path('/Hello World'))
- assert_raise(ActionController::RoutingError) { set.recognize_path('/Hello%20World') }
+ set.draw do |map|
+ map.connect '/Hello World', :controller => 'hello'
end
+
+ assert_equal '/Hello%20World', set.generate(:controller => 'hello')
+ assert_equal({:controller => "hello", :action => "index"}, set.recognize_path('/Hello World'))
+ assert_raise(ActionController::RoutingError) { set.recognize_path('/Hello%20World') }
end
def test_value_should_not_be_double_unescaped
- ActionController::Routing.with_controllers(['foo']) do
- set.draw do |map|
- map.connect '/Карта', :controller => 'foo'
- end
-
- assert_equal '/%D0%9A%D0%B0%D1%80%D1%82%D0%B0', set.generate(:controller => 'foo')
- assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/Карта'))
- assert_raise(ActionController::RoutingError) { set.recognize_path('/%D0%9A%D0%B0%D1%80%D1%82%D0%B0') }
+ set.draw do |map|
+ map.connect '/Карта', :controller => 'foo'
end
+
+ assert_equal '/%D0%9A%D0%B0%D1%80%D1%82%D0%B0', set.generate(:controller => 'foo')
+ assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/Карта'))
+ assert_raise(ActionController::RoutingError) { set.recognize_path('/%D0%9A%D0%B0%D1%80%D1%82%D0%B0') }
end
def test_regexp_chunk_should_escape_specials
- ActionController::Routing.with_controllers(['foo', 'bar']) do
- set.draw do |map|
- map.connect '/Hello*World', :controller => 'foo'
- map.connect '/HelloWorld', :controller => 'bar'
- end
+ set.draw do |map|
+ map.connect '/Hello*World', :controller => 'foo'
+ map.connect '/HelloWorld', :controller => 'bar'
+ end
- assert_equal '/Hello*World', set.generate(:controller => 'foo')
- assert_equal '/HelloWorld', set.generate(:controller => 'bar')
+ assert_equal '/Hello*World', set.generate(:controller => 'foo')
+ assert_equal '/HelloWorld', set.generate(:controller => 'bar')
- assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/Hello*World'))
- assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/HelloWorld'))
- end
+ assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/Hello*World'))
+ assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/HelloWorld'))
end
def test_regexp_chunk_should_add_question_mark_for_optionals
- ActionController::Routing.with_controllers(['foo', 'bar']) do
- set.draw do |map|
- map.connect '/', :controller => 'foo'
- map.connect '/hello', :controller => 'bar'
- end
+ set.draw do |map|
+ map.connect '/', :controller => 'foo'
+ map.connect '/hello', :controller => 'bar'
+ end
- assert_equal '/', set.generate(:controller => 'foo')
- assert_equal '/hello', set.generate(:controller => 'bar')
+ assert_equal '/', set.generate(:controller => 'foo')
+ assert_equal '/hello', set.generate(:controller => 'bar')
- assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/'))
- assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/hello'))
- end
+ assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/'))
+ assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/hello'))
end
def test_assign_route_options_with_anchor_chars
- ActionController::Routing.with_controllers(['cars']) do
- set.draw do |map|
- map.connect '/cars/:action/:person/:car/', :controller => 'cars'
- end
+ set.draw do |map|
+ map.connect '/cars/:action/:person/:car/', :controller => 'cars'
+ end
- assert_equal '/cars/buy/1/2', set.generate(:controller => 'cars', :action => 'buy', :person => '1', :car => '2')
+ assert_equal '/cars/buy/1/2', set.generate(:controller => 'cars', :action => 'buy', :person => '1', :car => '2')
- assert_equal({:controller => "cars", :action => "buy", :person => "1", :car => "2"}, set.recognize_path('/cars/buy/1/2'))
- end
+ assert_equal({:controller => "cars", :action => "buy", :person => "1", :car => "2"}, set.recognize_path('/cars/buy/1/2'))
end
def test_segmentation_of_dot_path
- ActionController::Routing.with_controllers(['books']) do
- set.draw do |map|
- map.connect '/books/:action.rss', :controller => 'books'
- end
+ set.draw do |map|
+ map.connect '/books/:action.rss', :controller => 'books'
+ end
- assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list')
+ assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list')
- assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list.rss'))
- end
+ assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list.rss'))
end
def test_segmentation_of_dynamic_dot_path
- ActionController::Routing.with_controllers(['books']) do
- set.draw do |map|
- map.connect '/books/:action.:format', :controller => 'books'
- end
+ set.draw do |map|
+ map.connect '/books/:action.:format', :controller => 'books'
+ end
- assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list', :format => 'rss')
- assert_equal '/books/list.xml', set.generate(:controller => 'books', :action => 'list', :format => 'xml')
- assert_equal '/books/list', set.generate(:controller => 'books', :action => 'list')
- assert_equal '/books', set.generate(:controller => 'books', :action => 'index')
+ assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list', :format => 'rss')
+ assert_equal '/books/list.xml', set.generate(:controller => 'books', :action => 'list', :format => 'xml')
+ assert_equal '/books/list', set.generate(:controller => 'books', :action => 'list')
+ assert_equal '/books', set.generate(:controller => 'books', :action => 'index')
- assert_equal({:controller => "books", :action => "list", :format => "rss"}, set.recognize_path('/books/list.rss'))
- assert_equal({:controller => "books", :action => "list", :format => "xml"}, set.recognize_path('/books/list.xml'))
- assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list'))
- assert_equal({:controller => "books", :action => "index"}, set.recognize_path('/books'))
- end
+ assert_equal({:controller => "books", :action => "list", :format => "rss"}, set.recognize_path('/books/list.rss'))
+ assert_equal({:controller => "books", :action => "list", :format => "xml"}, set.recognize_path('/books/list.xml'))
+ assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list'))
+ assert_equal({:controller => "books", :action => "index"}, set.recognize_path('/books'))
end
def test_slashes_are_implied
@@ -1782,32 +1684,43 @@ class RouteSetTest < ActiveSupport::TestCase
end
def test_build_empty_query_string
- assert_equal '/foo', default_route_set.generate({:controller => 'foo'})
+ assert_uri_equal '/foo', default_route_set.generate({:controller => 'foo'})
end
def test_build_query_string_with_nil_value
- assert_equal '/foo', default_route_set.generate({:controller => 'foo', :x => nil})
+ assert_uri_equal '/foo', default_route_set.generate({:controller => 'foo', :x => nil})
end
def test_simple_build_query_string
- assert_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => '1', :y => '2'})
+ assert_uri_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => '1', :y => '2'})
end
def test_convert_ints_build_query_string
- assert_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => 1, :y => 2})
+ assert_uri_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => 1, :y => 2})
end
def test_escape_spaces_build_query_string
- assert_equal '/foo?x=hello+world&y=goodbye+world', default_route_set.generate({:controller => 'foo', :x => 'hello world', :y => 'goodbye world'})
+ assert_uri_equal '/foo?x=hello+world&y=goodbye+world', default_route_set.generate({:controller => 'foo', :x => 'hello world', :y => 'goodbye world'})
end
def test_expand_array_build_query_string
- assert_equal '/foo?x%5B%5D=1&x%5B%5D=2', default_route_set.generate({:controller => 'foo', :x => [1, 2]})
+ assert_uri_equal '/foo?x%5B%5D=1&x%5B%5D=2', default_route_set.generate({:controller => 'foo', :x => [1, 2]})
end
def test_escape_spaces_build_query_string_selected_keys
- assert_equal '/foo?x=hello+world', default_route_set.generate({:controller => 'foo', :x => 'hello world'})
+ assert_uri_equal '/foo?x=hello+world', default_route_set.generate({:controller => 'foo', :x => 'hello world'})
end
+
+ private
+ def assert_uri_equal(expected, actual)
+ assert_equal(sort_query_string_params(expected), sort_query_string_params(actual))
+ end
+
+ def sort_query_string_params(uri)
+ path, qs = uri.split('?')
+ qs = qs.split('&').sort.join('&') if qs
+ qs ? "#{path}?#{qs}" : path
+ end
end
class RouteLoadingTest < Test::Unit::TestCase
diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb
index 4c4bf9ade4..d81ced96a8 100644
--- a/actionpack/test/controller/url_rewriter_test.rb
+++ b/actionpack/test/controller/url_rewriter_test.rb
@@ -321,8 +321,8 @@ class UrlWriterTests < ActionController::TestCase
params = extract_params(url)
assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query
assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query
- assert_equal params[2], { 'query[person][position][]' => 'prof' }.to_query
- assert_equal params[3], { 'query[person][position][]' => 'art director' }.to_query
+ assert_equal params[2], { 'query[person][position][]' => 'art director' }.to_query
+ assert_equal params[3], { 'query[person][position][]' => 'prof' }.to_query
end
def test_path_generation_for_symbol_parameter_keys
@@ -359,10 +359,10 @@ class UrlWriterTests < ActionController::TestCase
controller = kls.new
params = {:id => 1, :format => :xml}
assert_deprecated do
- assert_equal("/posts/1.xml", controller.send(:formatted_post_path, params))
+ assert_equal("/posts/1.xml", controller.send(:formatted_post_path, params))
end
assert_deprecated do
- assert_equal("/posts/1.xml", controller.send(:formatted_post_path, 1, :xml))
+ assert_equal("/posts/1.xml", controller.send(:formatted_post_path, 1, :xml))
end
end
end
@@ -382,6 +382,6 @@ class UrlWriterTests < ActionController::TestCase
private
def extract_params(url)
- url.split('?', 2).last.split('&')
+ url.split('?', 2).last.split('&').sort
end
end
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index 2d66fa9fcb..8f118a6057 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -51,6 +51,7 @@ module ActiveRecord
autoload :AssociationPreload, 'active_record/association_preload'
autoload :Associations, 'active_record/associations'
autoload :AttributeMethods, 'active_record/attribute_methods'
+ autoload :Attributes, 'active_record/attributes'
autoload :AutosaveAssociation, 'active_record/autosave_association'
autoload :Relation, 'active_record/relation'
autoload :Base, 'active_record/base'
@@ -74,6 +75,7 @@ module ActiveRecord
autoload :TestCase, 'active_record/test_case'
autoload :Timestamp, 'active_record/timestamp'
autoload :Transactions, 'active_record/transactions'
+ autoload :Types, 'active_record/types'
autoload :Validator, 'active_record/validator'
autoload :Validations, 'active_record/validations'
@@ -87,6 +89,20 @@ module ActiveRecord
autoload :Write, 'active_record/attribute_methods/write'
end
+ module Attributes
+ autoload :Aliasing, 'active_record/attributes/aliasing'
+ autoload :Store, 'active_record/attributes/store'
+ autoload :Typecasting, 'active_record/attributes/typecasting'
+ end
+
+ module Type
+ autoload :Number, 'active_record/types/number'
+ autoload :Object, 'active_record/types/object'
+ autoload :Serialize, 'active_record/types/serialize'
+ autoload :TimeWithZone, 'active_record/types/time_with_zone'
+ autoload :Unknown, 'active_record/types/unknown'
+ end
+
module Locking
autoload :Optimistic, 'active_record/locking/optimistic'
autoload :Pessimistic, 'active_record/locking/pessimistic'
diff --git a/activerecord/lib/active_record/attribute_methods/before_type_cast.rb b/activerecord/lib/active_record/attribute_methods/before_type_cast.rb
index a4e144f233..74921241f7 100644
--- a/activerecord/lib/active_record/attribute_methods/before_type_cast.rb
+++ b/activerecord/lib/active_record/attribute_methods/before_type_cast.rb
@@ -8,25 +8,18 @@ module ActiveRecord
end
def read_attribute_before_type_cast(attr_name)
- @attributes[attr_name]
+ _attributes.without_typecast[attr_name]
end
# Returns a hash of attributes before typecasting and deserialization.
def attributes_before_type_cast
- self.attribute_names.inject({}) do |attrs, name|
- attrs[name] = read_attribute_before_type_cast(name)
- attrs
- end
+ _attributes.without_typecast
end
private
# Handle *_before_type_cast for method_missing.
def attribute_before_type_cast(attribute_name)
- if attribute_name == 'id'
- read_attribute_before_type_cast(self.class.primary_key)
- else
- read_attribute_before_type_cast(attribute_name)
- end
+ read_attribute_before_type_cast(attribute_name)
end
end
end
diff --git a/activerecord/lib/active_record/attribute_methods/query.rb b/activerecord/lib/active_record/attribute_methods/query.rb
index a949d80120..0154ee35f8 100644
--- a/activerecord/lib/active_record/attribute_methods/query.rb
+++ b/activerecord/lib/active_record/attribute_methods/query.rb
@@ -8,23 +8,7 @@ module ActiveRecord
end
def query_attribute(attr_name)
- unless value = read_attribute(attr_name)
- false
- else
- column = self.class.columns_hash[attr_name]
- if column.nil?
- if Numeric === value || value !~ /[^0-9]/
- !value.to_i.zero?
- else
- return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
- !value.blank?
- end
- elsif column.number?
- !value.zero?
- else
- !value.blank?
- end
- end
+ _attributes.has?(attr_name)
end
private
@@ -35,3 +19,5 @@ module ActiveRecord
end
end
end
+
+
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 3da3d9d8cc..97caec7744 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -37,11 +37,7 @@ module ActiveRecord
protected
def define_method_attribute(attr_name)
- if self.serialized_attributes[attr_name]
- define_read_method_for_serialized_attribute(attr_name)
- else
- define_read_method(attr_name.to_sym, attr_name, columns_hash[attr_name])
- end
+ define_read_method(attr_name.to_sym, attr_name, columns_hash[attr_name])
if attr_name == primary_key && attr_name != "id"
define_read_method(:id, attr_name, columns_hash[attr_name])
@@ -49,18 +45,12 @@ module ActiveRecord
end
private
- # Define read method for serialized attribute.
- def define_read_method_for_serialized_attribute(attr_name)
- generated_attribute_methods.module_eval("def #{attr_name}; unserialize_attribute('#{attr_name}'); end", __FILE__, __LINE__)
- end
# Define an attribute reader method. Cope with nil column.
def define_read_method(symbol, attr_name, column)
- cast_code = column.type_cast_code('v') if column
- access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']"
-
+ access_code = "_attributes['#{attr_name}']"
unless attr_name.to_s == self.primary_key.to_s
- access_code = access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless @attributes.has_key?('#{attr_name}'); ")
+ access_code = access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless _attributes.key?('#{attr_name}'); ")
end
if cache_attribute?(attr_name)
@@ -73,38 +63,7 @@ module ActiveRecord
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
def read_attribute(attr_name)
- attr_name = attr_name.to_s
- attr_name = self.class.primary_key if attr_name == 'id'
- if !(value = @attributes[attr_name]).nil?
- if column = column_for_attribute(attr_name)
- if unserializable_attribute?(attr_name, column)
- unserialize_attribute(attr_name)
- else
- column.type_cast(value)
- end
- else
- value
- end
- else
- nil
- end
- end
-
- # Returns true if the attribute is of a text column and marked for serialization.
- def unserializable_attribute?(attr_name, column)
- column.text? && self.class.serialized_attributes[attr_name]
- end
-
- # Returns the unserialized object of the attribute.
- def unserialize_attribute(attr_name)
- unserialized_object = object_from_yaml(@attributes[attr_name])
-
- if unserialized_object.is_a?(self.class.serialized_attributes[attr_name]) || unserialized_object.nil?
- @attributes.frozen? ? unserialized_object : @attributes[attr_name] = unserialized_object
- else
- raise SerializationTypeMismatch,
- "#{attr_name} was supposed to be a #{self.class.serialized_attributes[attr_name]}, but was a #{unserialized_object.class.to_s}"
- end
+ _attributes[attr_name]
end
private
diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
index a8e3e28a7a..4ac0c7f608 100644
--- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
+++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
@@ -12,48 +12,20 @@ module ActiveRecord
end
module ClassMethods
+
+ def cache_attribute?(attr_name)
+ time_zone_aware?(attr_name) || super
+ end
+
protected
- # Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
- # This enhanced read method automatically converts the UTC time stored in the database to the time zone stored in Time.zone.
- def define_method_attribute(attr_name)
- if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
- method_body = <<-EOV
- def #{attr_name}(reload = false)
- cached = @attributes_cache['#{attr_name}']
- return cached if cached && !reload
- time = read_attribute('#{attr_name}')
- @attributes_cache['#{attr_name}'] = time.acts_like?(:time) ? time.in_time_zone : time
- end
- EOV
- generated_attribute_methods.module_eval(method_body, __FILE__, __LINE__)
- else
- super
- end
- end
- # Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
- # This enhanced write method will automatically convert the time passed to it to the zone stored in Time.zone.
- def define_method_attribute=(attr_name)
- if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
- method_body = <<-EOV
- def #{attr_name}=(time)
- unless time.acts_like?(:time)
- time = time.is_a?(String) ? Time.zone.parse(time) : time.to_time rescue time
- end
- time = time.in_time_zone rescue nil if time
- write_attribute(:#{attr_name}, time)
- end
- EOV
- generated_attribute_methods.module_eval(method_body, __FILE__, __LINE__)
- else
- super
- end
+ def time_zone_aware?(attr_name)
+ column = columns_hash[attr_name]
+ time_zone_aware_attributes &&
+ !skip_time_zone_conversion_for_attributes.include?(attr_name.to_sym) &&
+ [:datetime, :timestamp].include?(column.type)
end
- private
- def create_time_zone_conversion_attribute?(name, column)
- time_zone_aware_attributes && !skip_time_zone_conversion_for_attributes.include?(name.to_sym) && [:datetime, :timestamp].include?(column.type)
- end
end
end
end
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb
index e31acac050..37eadbe0a9 100644
--- a/activerecord/lib/active_record/attribute_methods/write.rb
+++ b/activerecord/lib/active_record/attribute_methods/write.rb
@@ -17,14 +17,9 @@ module ActiveRecord
# Updates the attribute identified by <tt>attr_name</tt> with the specified +value+. Empty strings for fixnum and float
# columns are turned into +nil+.
def write_attribute(attr_name, value)
- attr_name = attr_name.to_s
- attr_name = self.class.primary_key if attr_name == 'id'
+ attr_name = _attributes.unalias(attr_name)
@attributes_cache.delete(attr_name)
- if (column = column_for_attribute(attr_name)) && column.number?
- @attributes[attr_name] = convert_number_column_value(value)
- else
- @attributes[attr_name] = value
- end
+ _attributes[attr_name] = value
end
private
diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb
new file mode 100644
index 0000000000..e4d9e89821
--- /dev/null
+++ b/activerecord/lib/active_record/attributes.rb
@@ -0,0 +1,37 @@
+module ActiveRecord
+ module Attributes
+
+ # Returns true if the given attribute is in the attributes hash
+ def has_attribute?(attr_name)
+ _attributes.key?(attr_name)
+ end
+
+ # Returns an array of names for the attributes available on this object sorted alphabetically.
+ def attribute_names
+ _attributes.keys.sort!
+ end
+
+ # Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
+ def attributes
+ attributes = _attributes.dup
+ attributes.typecast! unless _attributes.frozen?
+ attributes.to_h
+ end
+
+ protected
+
+ # Not to be confused with the public #attributes method, which returns a typecasted Hash.
+ def _attributes
+ @attributes
+ end
+
+ def initialize_attribute_store(merge_attributes = nil)
+ @attributes = ActiveRecord::Attributes::Store.new
+ @attributes.merge!(merge_attributes) if merge_attributes
+ @attributes.types.merge!(self.class.attribute_types)
+ @attributes.aliases.merge!('id' => self.class.primary_key) unless 'id' == self.class.primary_key
+ @attributes
+ end
+
+ end
+end
diff --git a/activerecord/lib/active_record/attributes/aliasing.rb b/activerecord/lib/active_record/attributes/aliasing.rb
new file mode 100644
index 0000000000..db77739d1f
--- /dev/null
+++ b/activerecord/lib/active_record/attributes/aliasing.rb
@@ -0,0 +1,42 @@
+module ActiveRecord
+ module Attributes
+ module Aliasing
+ # Allows access to keys using aliased names.
+ #
+ # Example:
+ # class Attributes < Hash
+ # include Aliasing
+ # end
+ #
+ # attributes = Attributes.new
+ # attributes.aliases['id'] = 'fancy_primary_key'
+ # attributes['fancy_primary_key'] = 2020
+ #
+ # attributes['id']
+ # => 2020
+ #
+ # Additionally, symbols are always aliases of strings:
+ # attributes[:fancy_primary_key]
+ # => 2020
+ #
+ def [](key)
+ super(unalias(key))
+ end
+
+ def []=(key, value)
+ super(unalias(key), value)
+ end
+
+ def aliases
+ @aliases ||= {}
+ end
+
+ def unalias(key)
+ key = key.to_s
+ aliases[key] || key
+ end
+
+ end
+ end
+end
+
diff --git a/activerecord/lib/active_record/attributes/store.rb b/activerecord/lib/active_record/attributes/store.rb
new file mode 100644
index 0000000000..61109f4acc
--- /dev/null
+++ b/activerecord/lib/active_record/attributes/store.rb
@@ -0,0 +1,15 @@
+module ActiveRecord
+ module Attributes
+ class Store < Hash
+ include ActiveRecord::Attributes::Typecasting
+ include ActiveRecord::Attributes::Aliasing
+
+ # Attributes not mapped to a column are handled using Type::Unknown,
+ # which enables boolean typecasting for unmapped keys.
+ def types
+ @types ||= Hash.new(Type::Unknown.new)
+ end
+
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/attributes/typecasting.rb b/activerecord/lib/active_record/attributes/typecasting.rb
new file mode 100644
index 0000000000..56c32f9895
--- /dev/null
+++ b/activerecord/lib/active_record/attributes/typecasting.rb
@@ -0,0 +1,117 @@
+module ActiveRecord
+ module Attributes
+ module Typecasting
+ # Typecasts values during access based on their key mapping to a Type.
+ #
+ # Example:
+ # class Attributes < Hash
+ # include Typecasting
+ # end
+ #
+ # attributes = Attributes.new
+ # attributes.types['comments_count'] = Type::Integer
+ # attributes['comments_count'] = '5'
+ #
+ # attributes['comments_count']
+ # => 5
+ #
+ # To support keys not mapped to a typecaster, add a default to types.
+ # attributes.types.default = Type::Unknown
+ # attributes['age'] = '25'
+ # attributes['age']
+ # => '25'
+ #
+ # A valid type supports #cast, #precast, #boolean, and #appendable? methods.
+ #
+ def [](key)
+ value = super(key)
+ typecast_read(key, value)
+ end
+
+ def []=(key, value)
+ super(key, typecast_write(key, value))
+ end
+
+ def to_h
+ hash = {}
+ hash.merge!(self)
+ hash
+ end
+
+ def dup # :nodoc:
+ copy = super
+ copy.types = types.dup
+ copy
+ end
+
+ # Provides a duplicate with typecasting disabled.
+ #
+ # Example:
+ # attributes = Attributes.new
+ # attributes.types['comments_count'] = Type::Integer
+ # attributes['comments_count'] = '5'
+ #
+ # attributes.without_typecast['comments_count']
+ # => '5'
+ #
+ def without_typecast
+ dup.without_typecast!
+ end
+
+ def without_typecast!
+ types.clear
+ self
+ end
+
+ def typecast!
+ keys.each { |key| self[key] = self[key] }
+ self
+ end
+
+ # Check if key has a value that typecasts to true.
+ #
+ # attributes = Attributes.new
+ # attributes.types['comments_count'] = Type::Integer
+ #
+ # attributes['comments_count'] = 0
+ # attributes.has?('comments_count')
+ # => false
+ #
+ # attributes['comments_count'] = 1
+ # attributes.has?('comments_count')
+ # => true
+ #
+ def has?(key)
+ value = self[key]
+ boolean_typecast(key, value)
+ end
+
+ def types
+ @types ||= {}
+ end
+
+ protected
+
+ def types=(other_types)
+ @types = other_types
+ end
+
+ def boolean_typecast(key, value)
+ value ? types[key].boolean(value) : false
+ end
+
+ def typecast_read(key, value)
+ type = types[key]
+ value = type.cast(value)
+ self[key] = value if type.appendable? && !frozen?
+
+ value
+ end
+
+ def typecast_write(key, value)
+ types[key].precast(value)
+ end
+
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 76dbd00ad9..4274df54cc 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1644,7 +1644,7 @@ module ActiveRecord #:nodoc:
def instantiate(record)
object = find_sti_class(record[inheritance_column]).allocate
- object.instance_variable_set(:'@attributes', record)
+ object.send(:initialize_attribute_store, record)
object.instance_variable_set(:'@attributes_cache', {})
object.send(:_run_find_callbacks)
@@ -2415,7 +2415,7 @@ module ActiveRecord #:nodoc:
# In both instances, valid attribute keys are determined by the column names of the associated table --
# hence you can't have attributes that aren't part of the table columns.
def initialize(attributes = nil)
- @attributes = attributes_from_column_definition
+ initialize_attribute_store(attributes_from_column_definition)
@attributes_cache = {}
@new_record = true
ensure_proper_type
@@ -2441,7 +2441,7 @@ module ActiveRecord #:nodoc:
callback(:after_initialize) if respond_to_without_attributes?(:after_initialize)
cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast)
cloned_attributes.delete(self.class.primary_key)
- @attributes = cloned_attributes
+ initialize_attribute_store(cloned_attributes)
clear_aggregation_cache
@attributes_cache = {}
@new_record = true
@@ -2667,7 +2667,7 @@ module ActiveRecord #:nodoc:
def reload(options = nil)
clear_aggregation_cache
clear_association_cache
- @attributes.update(self.class.find(self.id, options).instance_variable_get('@attributes'))
+ _attributes.update(self.class.find(self.id, options).instance_variable_get('@attributes'))
@attributes_cache = {}
self
end
@@ -2764,16 +2764,6 @@ module ActiveRecord #:nodoc:
!value.blank?
end
- # Returns true if the given attribute is in the attributes hash
- def has_attribute?(attr_name)
- @attributes.has_key?(attr_name.to_s)
- end
-
- # Returns an array of names for the attributes available on this object sorted alphabetically.
- def attribute_names
- @attributes.keys.sort
- end
-
# Returns the column object for the named attribute.
def column_for_attribute(name)
self.class.columns_hash[name.to_s]
@@ -2897,18 +2887,6 @@ module ActiveRecord #:nodoc:
end
end
- def convert_number_column_value(value)
- if value == false
- 0
- elsif value == true
- 1
- elsif value.is_a?(String) && value.blank?
- nil
- else
- value
- end
- end
-
def remove_attributes_protected_from_mass_assignment(attributes)
safe_attributes =
if self.class.accessible_attributes.nil? && self.class.protected_attributes.nil?
@@ -3027,7 +3005,7 @@ module ActiveRecord #:nodoc:
end
def instantiate_time_object(name, values)
- if self.class.send(:create_time_zone_conversion_attribute?, name, column_for_attribute(name))
+ if self.class.send(:time_zone_aware?, name)
Time.zone.local(*values)
else
Time.time_with_datetime_fallback(@@default_timezone, *values)
@@ -3114,10 +3092,6 @@ module ActiveRecord #:nodoc:
comma_pair_list(quote_columns(quoter, hash))
end
- def object_from_yaml(string)
- return string unless string.is_a?(String) && string =~ /^---/
- YAML::load(string) rescue string
- end
end
Base.class_eval do
@@ -3132,6 +3106,7 @@ module ActiveRecord #:nodoc:
include AttributeMethods::PrimaryKey
include AttributeMethods::TimeZoneConversion
include AttributeMethods::Dirty
+ include Attributes, Types
include Callbacks, ActiveModel::Observing, Timestamp
include Associations, AssociationPreload, NamedScope
include ActiveModel::Conversion
@@ -3141,6 +3116,7 @@ module ActiveRecord #:nodoc:
include AutosaveAssociation, NestedAttributes
include Aggregations, Transactions, Reflection, Batches, Calculations, Serialization
+
end
end
diff --git a/activerecord/lib/active_record/types.rb b/activerecord/lib/active_record/types.rb
new file mode 100644
index 0000000000..74f569352b
--- /dev/null
+++ b/activerecord/lib/active_record/types.rb
@@ -0,0 +1,38 @@
+module ActiveRecord
+ module Types
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+
+ def attribute_types
+ attribute_types = {}
+ columns.each do |column|
+ options = {}
+ options[:time_zone_aware] = time_zone_aware?(column.name)
+ options[:serialize] = serialized_attributes[column.name]
+
+ attribute_types[column.name] = to_type(column, options)
+ end
+ attribute_types
+ end
+
+ private
+
+ def to_type(column, options = {})
+ type_class = if options[:time_zone_aware]
+ Type::TimeWithZone
+ elsif options[:serialize]
+ Type::Serialize
+ elsif [ :integer, :float, :decimal ].include?(column.type)
+ Type::Number
+ else
+ Type::Object
+ end
+
+ type_class.new(column, options)
+ end
+
+ end
+
+ end
+end
diff --git a/activerecord/lib/active_record/types/number.rb b/activerecord/lib/active_record/types/number.rb
new file mode 100644
index 0000000000..cfbe877575
--- /dev/null
+++ b/activerecord/lib/active_record/types/number.rb
@@ -0,0 +1,30 @@
+module ActiveRecord
+ module Type
+ class Number < Object
+
+ def boolean(value)
+ value = cast(value)
+ !(value.nil? || value.zero?)
+ end
+
+ def precast(value)
+ convert_number_column_value(value)
+ end
+
+ private
+
+ def convert_number_column_value(value)
+ if value == false
+ 0
+ elsif value == true
+ 1
+ elsif value.is_a?(String) && value.blank?
+ nil
+ else
+ value
+ end
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/activerecord/lib/active_record/types/object.rb b/activerecord/lib/active_record/types/object.rb
new file mode 100644
index 0000000000..ec3f861abd
--- /dev/null
+++ b/activerecord/lib/active_record/types/object.rb
@@ -0,0 +1,37 @@
+module ActiveRecord
+ module Type
+ module Casting
+
+ def cast(value)
+ typecaster.type_cast(value)
+ end
+
+ def precast(value)
+ value
+ end
+
+ def boolean(value)
+ cast(value).present?
+ end
+
+ # Attributes::Typecasting stores appendable? types (e.g. serialized Arrays) when typecasting reads.
+ def appendable?
+ false
+ end
+
+ end
+
+ class Object
+ include Casting
+
+ attr_reader :name, :options
+ attr_reader :typecaster
+
+ def initialize(typecaster = nil, options = {})
+ @typecaster, @options = typecaster, options
+ end
+
+ end
+
+ end
+end \ No newline at end of file
diff --git a/activerecord/lib/active_record/types/serialize.rb b/activerecord/lib/active_record/types/serialize.rb
new file mode 100644
index 0000000000..7b6af1981f
--- /dev/null
+++ b/activerecord/lib/active_record/types/serialize.rb
@@ -0,0 +1,33 @@
+module ActiveRecord
+ module Type
+ class Serialize < Object
+
+ def cast(value)
+ unserialize(value)
+ end
+
+ def appendable?
+ true
+ end
+
+ protected
+
+ def unserialize(value)
+ unserialized_object = object_from_yaml(value)
+
+ if unserialized_object.is_a?(@options[:serialize]) || unserialized_object.nil?
+ unserialized_object
+ else
+ raise SerializationTypeMismatch,
+ "#{name} was supposed to be a #{@options[:serialize]}, but was a #{unserialized_object.class.to_s}"
+ end
+ end
+
+ def object_from_yaml(string)
+ return string unless string.is_a?(String) && string =~ /^---/
+ YAML::load(string) rescue string
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/activerecord/lib/active_record/types/time_with_zone.rb b/activerecord/lib/active_record/types/time_with_zone.rb
new file mode 100644
index 0000000000..3a8b9292f9
--- /dev/null
+++ b/activerecord/lib/active_record/types/time_with_zone.rb
@@ -0,0 +1,20 @@
+module ActiveRecord
+ module Type
+ class TimeWithZone < Object
+
+ def cast(time)
+ time = super(time)
+ time.acts_like?(:time) ? time.in_time_zone : time
+ end
+
+ def precast(time)
+ unless time.acts_like?(:time)
+ time = time.is_a?(String) ? ::Time.zone.parse(time) : time.to_time rescue time
+ end
+ time = time.in_time_zone rescue nil if time
+ super(time)
+ end
+
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/types/unknown.rb b/activerecord/lib/active_record/types/unknown.rb
new file mode 100644
index 0000000000..f832c7b304
--- /dev/null
+++ b/activerecord/lib/active_record/types/unknown.rb
@@ -0,0 +1,37 @@
+module ActiveRecord
+ module Type
+ # Useful for handling attributes not mapped to types. Performs some boolean typecasting,
+ # but otherwise leaves the value untouched.
+ class Unknown
+
+ def cast(value)
+ value
+ end
+
+ def precast(value)
+ value
+ end
+
+ # Attempts typecasting to handle numeric, false and blank values.
+ def boolean(value)
+ empty = (numeric?(value) && value.to_i.zero?) || false?(value) || value.blank?
+ !empty
+ end
+
+ def appendable?
+ false
+ end
+
+ protected
+
+ def false?(value)
+ ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
+ end
+
+ def numeric?(value)
+ Numeric === value || value !~ /[^0-9]/
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/cases/attributes/aliasing_test.rb b/activerecord/test/cases/attributes/aliasing_test.rb
new file mode 100644
index 0000000000..7ee25779f1
--- /dev/null
+++ b/activerecord/test/cases/attributes/aliasing_test.rb
@@ -0,0 +1,20 @@
+require "cases/helper"
+
+class AliasingTest < ActiveRecord::TestCase
+
+ class AliasingAttributes < Hash
+ include ActiveRecord::Attributes::Aliasing
+ end
+
+ test "attribute access with aliasing" do
+ attributes = AliasingAttributes.new
+ attributes[:name] = 'Batman'
+ attributes.aliases['nickname'] = 'name'
+
+ assert_equal 'Batman', attributes[:name], "Symbols should point to Strings"
+ assert_equal 'Batman', attributes['name']
+ assert_equal 'Batman', attributes['nickname']
+ assert_equal 'Batman', attributes[:nickname]
+ end
+
+end
diff --git a/activerecord/test/cases/attributes/typecasting_test.rb b/activerecord/test/cases/attributes/typecasting_test.rb
new file mode 100644
index 0000000000..8a3b551375
--- /dev/null
+++ b/activerecord/test/cases/attributes/typecasting_test.rb
@@ -0,0 +1,120 @@
+require "cases/helper"
+
+class TypecastingTest < ActiveRecord::TestCase
+
+ class TypecastingAttributes < Hash
+ include ActiveRecord::Attributes::Typecasting
+ end
+
+ module MockType
+ class Object
+
+ def cast(value)
+ value
+ end
+
+ def precast(value)
+ value
+ end
+
+ def boolean(value)
+ !value.blank?
+ end
+
+ def appendable?
+ false
+ end
+
+ end
+
+ class Integer < Object
+
+ def cast(value)
+ value.to_i
+ end
+
+ def precast(value)
+ value ? value : 0
+ end
+
+ def boolean(value)
+ !Float(value).zero?
+ end
+
+ end
+
+ class Serialize < Object
+
+ def cast(value)
+ YAML::load(value) rescue value
+ end
+
+ def precast(value)
+ value
+ end
+
+ def appendable?
+ true
+ end
+
+ end
+ end
+
+ def setup
+ @attributes = TypecastingAttributes.new
+ @attributes.types.default = MockType::Object.new
+ @attributes.types['comments_count'] = MockType::Integer.new
+ end
+
+ test "typecast on read" do
+ attributes = @attributes.merge('comments_count' => '5')
+ assert_equal 5, attributes['comments_count']
+ end
+
+ test "typecast on write" do
+ @attributes['comments_count'] = false
+
+ assert_equal 0, @attributes.to_h['comments_count']
+ end
+
+ test "serialized objects" do
+ attributes = @attributes.merge('tags' => [ 'peanut butter' ].to_yaml)
+ attributes.types['tags'] = MockType::Serialize.new
+ attributes['tags'] << 'jelly'
+
+ assert_equal [ 'peanut butter', 'jelly' ], attributes['tags']
+ end
+
+ test "without typecasting" do
+ @attributes.merge!('comments_count' => '5')
+ attributes = @attributes.without_typecast
+
+ assert_equal '5', attributes['comments_count']
+ assert_equal 5, @attributes['comments_count'], "Original attributes should typecast"
+ end
+
+
+ test "typecast all attributes" do
+ attributes = @attributes.merge('title' => 'I love sandwiches', 'comments_count' => '5')
+ attributes.typecast!
+
+ assert_equal({ 'title' => 'I love sandwiches', 'comments_count' => 5 }, attributes)
+ end
+
+ test "query for has? value" do
+ attributes = @attributes.merge('comments_count' => '1')
+
+ assert_equal true, attributes.has?('comments_count')
+ attributes['comments_count'] = '0'
+ assert_equal false, attributes.has?('comments_count')
+ end
+
+ test "attributes to Hash" do
+ attributes_hash = { 'title' => 'I love sandwiches', 'comments_count' => '5' }
+ attributes = @attributes.merge(attributes_hash)
+
+ assert_equal Hash, attributes.to_h.class
+ assert_equal attributes_hash, attributes.to_h
+ end
+
+end
diff --git a/activerecord/test/cases/types/number_test.rb b/activerecord/test/cases/types/number_test.rb
new file mode 100644
index 0000000000..ee7216a0f1
--- /dev/null
+++ b/activerecord/test/cases/types/number_test.rb
@@ -0,0 +1,30 @@
+require "cases/helper"
+
+class NumberTest < ActiveRecord::TestCase
+
+ def setup
+ @column = ActiveRecord::ConnectionAdapters::Column.new('comments_count', 0, 'integer')
+ @number = ActiveRecord::Type::Number.new(@column)
+ end
+
+ test "typecast" do
+ assert_equal 1, @number.cast(1)
+ assert_equal 1, @number.cast('1')
+ assert_equal 0, @number.cast('')
+
+ assert_equal 0, @number.precast(false)
+ assert_equal 1, @number.precast(true)
+ assert_equal nil, @number.precast('')
+ assert_equal 0, @number.precast(0)
+ end
+
+ test "cast as boolean" do
+ assert_equal true, @number.boolean('1')
+ assert_equal true, @number.boolean(1)
+
+ assert_equal false, @number.boolean(0)
+ assert_equal false, @number.boolean('0')
+ assert_equal false, @number.boolean(nil)
+ end
+
+end
diff --git a/activerecord/test/cases/types/object_test.rb b/activerecord/test/cases/types/object_test.rb
new file mode 100644
index 0000000000..f2667a9b00
--- /dev/null
+++ b/activerecord/test/cases/types/object_test.rb
@@ -0,0 +1,24 @@
+require "cases/helper"
+
+class ObjectTest < ActiveRecord::TestCase
+
+ def setup
+ @column = ActiveRecord::ConnectionAdapters::Column.new('name', '', 'date')
+ @object = ActiveRecord::Type::Object.new(@column)
+ end
+
+ test "typecast with column" do
+ date = Date.new(2009, 7, 10)
+ assert_equal date, @object.cast('10-07-2009')
+ assert_equal nil, @object.cast('')
+
+ assert_equal date, @object.precast(date)
+ end
+
+ test "cast as boolean" do
+ assert_equal false, @object.boolean(nil)
+ assert_equal false, @object.boolean('false')
+ assert_equal true, @object.boolean('10-07-2009')
+ end
+
+end
diff --git a/activerecord/test/cases/types/serialize_test.rb b/activerecord/test/cases/types/serialize_test.rb
new file mode 100644
index 0000000000..e9423a5b9d
--- /dev/null
+++ b/activerecord/test/cases/types/serialize_test.rb
@@ -0,0 +1,20 @@
+require "cases/helper"
+
+class SerializeTest < ActiveRecord::TestCase
+
+ test "typecast" do
+ serializer = ActiveRecord::Type::Serialize.new(column = nil, :serialize => Array)
+
+ assert_equal [], serializer.cast([].to_yaml)
+ assert_equal ['1'], serializer.cast(['1'].to_yaml)
+ assert_equal nil, serializer.cast(nil.to_yaml)
+ end
+
+ test "cast as boolean" do
+ serializer = ActiveRecord::Type::Serialize.new(column = nil, :serialize => Array)
+
+ assert_equal true, serializer.boolean(['1'].to_yaml)
+ assert_equal false, serializer.boolean([].to_yaml)
+ end
+
+end \ No newline at end of file
diff --git a/activerecord/test/cases/types/time_with_zone_test.rb b/activerecord/test/cases/types/time_with_zone_test.rb
new file mode 100644
index 0000000000..b3de79a6c8
--- /dev/null
+++ b/activerecord/test/cases/types/time_with_zone_test.rb
@@ -0,0 +1,42 @@
+require "cases/helper"
+
+class TimeWithZoneTest < ActiveRecord::TestCase
+
+ def setup
+ @column = ActiveRecord::ConnectionAdapters::Column.new('created_at', 0, 'datetime')
+ @time_with_zone = ActiveRecord::Type::TimeWithZone.new(@column)
+ end
+
+ test "typecast" do
+ Time.use_zone("Pacific Time (US & Canada)") do
+ time_string = "2009-10-07 21:29:10"
+ time = Time.zone.parse(time_string)
+
+ # assert_equal time, @time_with_zone.cast(time_string)
+ assert_equal nil, @time_with_zone.cast('')
+ assert_equal nil, @time_with_zone.cast(nil)
+
+ assert_equal time, @time_with_zone.precast(time)
+ assert_equal time, @time_with_zone.precast(time_string)
+ assert_equal time, @time_with_zone.precast(time.to_time)
+ # assert_equal "#{time.to_date.to_s} 00:00:00 -0700", @time_with_zone.precast(time.to_date).to_s
+ end
+ end
+
+ test "cast as boolean" do
+ Time.use_zone('Central Time (US & Canada)') do
+ time = Time.zone.now
+
+ assert_equal true, @time_with_zone.boolean(time)
+ assert_equal true, @time_with_zone.boolean(time.to_date)
+ assert_equal true, @time_with_zone.boolean(time.to_time)
+
+ assert_equal true, @time_with_zone.boolean(time.to_s)
+ assert_equal true, @time_with_zone.boolean(time.to_date.to_s)
+ assert_equal true, @time_with_zone.boolean(time.to_time.to_s)
+
+ assert_equal false, @time_with_zone.boolean('')
+ end
+ end
+
+end
diff --git a/activerecord/test/cases/types/unknown_test.rb b/activerecord/test/cases/types/unknown_test.rb
new file mode 100644
index 0000000000..230d67b2fb
--- /dev/null
+++ b/activerecord/test/cases/types/unknown_test.rb
@@ -0,0 +1,29 @@
+require "cases/helper"
+
+class UnknownTest < ActiveRecord::TestCase
+
+ test "typecast attributes does't modify values" do
+ unkown = ActiveRecord::Type::Unknown.new
+ person = { 'name' => '0' }
+
+ assert_equal person['name'], unkown.cast(person['name'])
+ assert_equal person['name'], unkown.precast(person['name'])
+ end
+
+ test "cast as boolean" do
+ person = { 'id' => 0, 'name' => ' ', 'admin' => 'false', 'votes' => '0' }
+ unkown = ActiveRecord::Type::Unknown.new
+
+ assert_equal false, unkown.boolean(person['votes'])
+ assert_equal false, unkown.boolean(person['admin'])
+ assert_equal false, unkown.boolean(person['name'])
+ assert_equal false, unkown.boolean(person['id'])
+
+ person = { 'id' => 5, 'name' => 'Eric', 'admin' => 'true', 'votes' => '25' }
+ assert_equal true, unkown.boolean(person['votes'])
+ assert_equal true, unkown.boolean(person['admin'])
+ assert_equal true, unkown.boolean(person['name'])
+ assert_equal true, unkown.boolean(person['id'])
+ end
+
+end \ No newline at end of file
diff --git a/activerecord/test/cases/types_test.rb b/activerecord/test/cases/types_test.rb
new file mode 100644
index 0000000000..403a9a6e02
--- /dev/null
+++ b/activerecord/test/cases/types_test.rb
@@ -0,0 +1,32 @@
+require "cases/helper"
+require 'models/topic'
+
+class TypesTest < ActiveRecord::TestCase
+
+ test "attribute types from columns" do
+ begin
+ ActiveRecord::Base.time_zone_aware_attributes = true
+ attribute_type_classes = {}
+ Topic.attribute_types.each { |key, type| attribute_type_classes[key] = type.class }
+
+ expected = { "id" => ActiveRecord::Type::Number,
+ "replies_count" => ActiveRecord::Type::Number,
+ "parent_id" => ActiveRecord::Type::Number,
+ "content" => ActiveRecord::Type::Serialize,
+ "written_on" => ActiveRecord::Type::TimeWithZone,
+ "title" => ActiveRecord::Type::Object,
+ "author_name" => ActiveRecord::Type::Object,
+ "approved" => ActiveRecord::Type::Object,
+ "parent_title" => ActiveRecord::Type::Object,
+ "bonus_time" => ActiveRecord::Type::Object,
+ "type" => ActiveRecord::Type::Object,
+ "last_read" => ActiveRecord::Type::Object,
+ "author_email_address" => ActiveRecord::Type::Object }
+
+ assert_equal expected, attribute_type_classes
+ ensure
+ ActiveRecord::Base.time_zone_aware_attributes = false
+ end
+ end
+
+end
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 621f1c3878..943c939757 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -57,13 +57,6 @@ module Rails
$LOAD_PATH.uniq!
end
- # Bail if boot.rb is outdated
- initializer :freak_out_if_boot_rb_is_outdated do
- unless defined?(Rails::BOOTSTRAP_VERSION)
- abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
- end
- end
-
# Requires all frameworks specified by the Configuration#frameworks
# list. By default, all frameworks (Active Record, Active Support,
# Action Pack, Action Mailer, and Active Resource) are loaded.
@@ -133,15 +126,6 @@ module Rails
end
end
- initializer :add_gem_load_paths do
- require 'rails/gem_dependency'
- Rails::GemDependency.add_frozen_gem_path
- unless config.gems.empty?
- require "rubygems"
- config.gems.each { |gem| gem.add_load_paths }
- end
- end
-
# Preload all frameworks specified by the Configuration#frameworks.
# Used by Passenger to ensure everything's loaded before forking and
# to avoid autoload race conditions in JRuby.
@@ -327,31 +311,6 @@ module Rails
end
end
- initializer :check_for_unbuilt_gems do
- unbuilt_gems = config.gems.select {|gem| gem.frozen? && !gem.built? }
- if unbuilt_gems.size > 0
- # don't print if the gems:build rake tasks are being run
- unless $gems_build_rake_task
- abort <<-end_error
- The following gems have native components that need to be built
- #{unbuilt_gems.map { |gemm| "#{gemm.name} #{gemm.requirement}" } * "\n "}
-
- You're running:
- ruby #{Gem.ruby_version} at #{Gem.ruby}
- rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
-
- Run `rake gems:build` to build the unbuilt gems.
- end_error
- end
- end
- end
-
- initializer :load_gems do
- unless $gems_rake_task
- config.gems.each { |gem| gem.load }
- end
- end
-
# Loads all plugins in <tt>config.plugin_paths</tt>. <tt>plugin_paths</tt>
# defaults to <tt>vendor/plugins</tt> but may also be set to a list of
# paths, such as
@@ -372,49 +331,19 @@ module Rails
plugin_loader.load_plugins
end
- # TODO: Figure out if this needs to run a second time
- # load_gems
-
- initializer :check_gem_dependencies do
- unloaded_gems = config.gems.reject { |g| g.loaded? }
- if unloaded_gems.size > 0
- configuration.gems_dependencies_loaded = false
- # don't print if the gems rake tasks are being run
- unless $gems_rake_task
- abort <<-end_error
- Missing these required gems:
- #{unloaded_gems.map { |gemm| "#{gemm.name} #{gemm.requirement}" } * "\n "}
-
- You're running:
- ruby #{Gem.ruby_version} at #{Gem.ruby}
- rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
-
- Run `rake gems:install` to install the missing gems.
- end_error
- end
- else
- configuration.gems_dependencies_loaded = true
- end
- end
-
# # bail out if gems are missing - note that check_gem_dependencies will have
# # already called abort() unless $gems_rake_task is set
# return unless gems_dependencies_loaded
-
initializer :load_application_initializers do
- if config.gems_dependencies_loaded
- Dir["#{configuration.root}/config/initializers/**/*.rb"].sort.each do |initializer|
- load(initializer)
- end
+ Dir["#{configuration.root}/config/initializers/**/*.rb"].sort.each do |initializer|
+ load(initializer)
end
end
# Fires the user-supplied after_initialize block (Configuration#after_initialize)
initializer :after_initialize do
- if config.gems_dependencies_loaded
- configuration.after_initialize_blocks.each do |block|
- block.call
- end
+ configuration.after_initialize_blocks.each do |block|
+ block.call
end
end
@@ -456,7 +385,7 @@ module Rails
#
# # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
initializer :load_observers do
- if config.gems_dependencies_loaded && configuration.frameworks.include?(:active_record)
+ if configuration.frameworks.include?(:active_record)
ActiveRecord::Base.instantiate_observers
end
end
diff --git a/railties/lib/rails/backtrace_cleaner.rb b/railties/lib/rails/backtrace_cleaner.rb
index 5507f40c0d..2f5632c3e4 100644
--- a/railties/lib/rails/backtrace_cleaner.rb
+++ b/railties/lib/rails/backtrace_cleaner.rb
@@ -1,5 +1,4 @@
require 'active_support/backtrace_cleaner'
-require 'rails/gem_dependency'
module Rails
class BacktraceCleaner < ActiveSupport::BacktraceCleaner
@@ -36,9 +35,6 @@ module Rails
# http://gist.github.com/30430
add_filter { |line| line.sub(/(#{path})\/gems\/([a-z]+)-([0-9.]+)\/(.*)/, '\2 (\3) \4')}
end
-
- vendor_gems_path = Rails::GemDependency.unpacked_path.sub("#{Rails.root}/",'')
- add_filter { |line| line.sub(/(#{vendor_gems_path})\/([a-z]+)-([0-9.]+)\/(.*)/, '\2 (\3) [v] \4')}
end
end
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index ce9c899400..1a7483c548 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -4,7 +4,7 @@ require 'rails/plugin/locator'
module Rails
class Configuration
attr_accessor :cache_classes, :load_paths,
- :load_once_paths, :gems_dependencies_loaded, :after_initialize_blocks,
+ :load_once_paths, :after_initialize_blocks,
:frameworks, :framework_root_path, :root, :plugin_paths, :plugins,
:plugin_loader, :plugin_locators, :gems, :loaded_plugins, :reload_plugins,
:i18n, :gems, :whiny_nils, :consider_all_requests_local,
@@ -230,25 +230,6 @@ module Rails
end
end
- # Adds a single Gem dependency to the rails application. By default, it will require
- # the library with the same name as the gem. Use :lib to specify a different name.
- #
- # # gem 'aws-s3', '>= 0.4.0'
- # # require 'aws/s3'
- # config.gem 'aws-s3', :lib => 'aws/s3', :version => '>= 0.4.0', \
- # :source => "http://code.whytheluckystiff.net"
- #
- # To require a library be installed, but not attempt to load it, pass :lib => false
- #
- # config.gem 'qrp', :version => '0.4.1', :lib => false
- def gem(name, options = {})
- gems << Rails::GemDependency.new(name, options)
- end
-
- def gems
- @gems ||= []
- end
-
def environment_path
"#{root}/config/environments/#{RAILS_ENV}.rb"
end
diff --git a/railties/lib/rails/deprecation.rb b/railties/lib/rails/deprecation.rb
index 42bba151d6..3c5b8bdec7 100644
--- a/railties/lib/rails/deprecation.rb
+++ b/railties/lib/rails/deprecation.rb
@@ -14,4 +14,12 @@ RAILS_ROOT = (Class.new(ActiveSupport::Deprecation::DeprecationProxy) do
msg = "RAILS_ROOT is deprecated! Use Rails.root instead."
ActiveSupport::Deprecation.warn(msg, callstack)
end
-end).new \ No newline at end of file
+end).new
+
+module Rails
+ class Configuration
+ def gem(*args)
+ ActiveSupport::Deprecation.warn("config.gem has been deprecated in favor of the Gemfile.")
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/gem_builder.rb b/railties/lib/rails/gem_builder.rb
deleted file mode 100644
index 79c61cc034..0000000000
--- a/railties/lib/rails/gem_builder.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'rubygems'
-require 'rubygems/installer'
-
-module Rails
-
- # this class hijacks the functionality of Gem::Installer by overloading its
- # initializer to only provide the information needed by
- # Gem::Installer#build_extensions (which happens to be what we have)
- class GemBuilder < Gem::Installer
-
- def initialize(spec, gem_dir)
- @spec = spec
- @gem_dir = gem_dir
- end
-
- # silence the underlying builder
- def say(message)
- end
-
- end
-end
diff --git a/railties/lib/rails/gem_dependency.rb b/railties/lib/rails/gem_dependency.rb
deleted file mode 100644
index 804bd75e55..0000000000
--- a/railties/lib/rails/gem_dependency.rb
+++ /dev/null
@@ -1,311 +0,0 @@
-require 'rails/vendor_gem_source_index'
-
-module Gem
- def self.source_index=(index)
- @@source_index = index
- end
-end
-
-module Rails
- class GemDependency < Gem::Dependency
- attr_accessor :lib, :source, :dep
-
- def self.unpacked_path
- @unpacked_path ||= File.join(Rails.root, 'vendor', 'gems')
- end
-
- @@framework_gems = {}
-
- def self.add_frozen_gem_path
- @@paths_loaded ||= begin
- source_index = Rails::VendorGemSourceIndex.new(Gem.source_index)
- Gem.clear_paths
- Gem.source_index = source_index
- # loaded before us - we can't change them, so mark them
- Gem.loaded_specs.each do |name, spec|
- @@framework_gems[name] = spec
- end
- true
- end
- end
-
- def self.from_directory_name(directory_name, load_spec=true)
- directory_name_parts = File.basename(directory_name).split('-')
- name = directory_name_parts[0..-2].join('-')
- version = directory_name_parts.last
- result = self.new(name, :version => version)
- spec_filename = File.join(directory_name, '.specification')
- if load_spec
- raise "Missing specification file in #{File.dirname(spec_filename)}. Perhaps you need to do a 'rake gems:refresh_specs'?" unless File.exists?(spec_filename)
- spec = YAML::load_file(spec_filename)
- result.specification = spec
- end
- result
- rescue ArgumentError => e
- raise "Unable to determine gem name and version from '#{directory_name}'"
- end
-
- def initialize(name, options = {})
- require 'rubygems' unless Object.const_defined?(:Gem)
-
- if options[:requirement]
- req = options[:requirement]
- elsif options[:version]
- req = Gem::Requirement.create(options[:version])
- else
- req = Gem::Requirement.default
- end
-
- @lib = options[:lib]
- @source = options[:source]
- @loaded = @frozen = @load_paths_added = false
-
- super(name, req)
- end
-
- def add_load_paths
- self.class.add_frozen_gem_path
- return if @loaded || @load_paths_added
- if framework_gem?
- @load_paths_added = @loaded = @frozen = true
- return
- end
- gem self
- @spec = Gem.loaded_specs[name]
- @frozen = @spec.loaded_from.include?(self.class.unpacked_path) if @spec
- @load_paths_added = true
- rescue Gem::LoadError
- end
-
- def dependencies
- return [] if framework_gem?
- return [] unless installed?
- specification.dependencies.reject do |dependency|
- dependency.type == :development
- end.map do |dependency|
- GemDependency.new(dependency.name, :requirement => dependency.version_requirements)
- end
- end
-
- def specification
- # code repeated from Gem.activate. Find a matching spec, or the currently loaded version.
- # error out if loaded version and requested version are incompatible.
- @spec ||= begin
- matches = Gem.source_index.search(self)
- matches << @@framework_gems[name] if framework_gem?
- if Gem.loaded_specs[name] then
- # This gem is already loaded. If the currently loaded gem is not in the
- # list of candidate gems, then we have a version conflict.
- existing_spec = Gem.loaded_specs[name]
- unless matches.any? { |spec| spec.version == existing_spec.version } then
- raise Gem::Exception,
- "can't activate #{@dep}, already activated #{existing_spec.full_name}"
- end
- # we're stuck with it, so change to match
- version_requirements = Gem::Requirement.create("=#{existing_spec.version}")
- existing_spec
- else
- # new load
- matches.last
- end
- end
- end
-
- def specification=(s)
- @spec = s
- end
-
- def requirement
- r = version_requirements
- (r == Gem::Requirement.default) ? nil : r
- end
-
- def built?
- return false unless frozen?
-
- if vendor_gem?
- specification.extensions.each do |ext|
- makefile = File.join(unpacked_gem_directory, File.dirname(ext), 'Makefile')
- return false unless File.exists?(makefile)
- end
- end
-
- true
- end
-
- def framework_gem?
- @@framework_gems.has_key?(name)
- end
-
- def frozen?
- @frozen ||= vendor_rails? || vendor_gem?
- end
-
- def installed?
- Gem.loaded_specs.keys.include?(name)
- end
-
- def load_paths_added?
- # always try to add load paths - even if a gem is loaded, it may not
- # be a compatible version (ie random_gem 0.4 is loaded and a later spec
- # needs >= 0.5 - gem 'random_gem' will catch this and error out)
- @load_paths_added
- end
-
- def loaded?
- @loaded ||= begin
- if vendor_rails?
- true
- elsif specification.nil?
- false
- else
- # check if the gem is loaded by inspecting $"
- # specification.files lists all the files contained in the gem
- gem_files = specification.files
- # select only the files contained in require_paths - typically in bin and lib
- require_paths_regexp = Regexp.new("^(#{specification.require_paths*'|'})/")
- gem_lib_files = gem_files.select { |f| require_paths_regexp.match(f) }
- # chop the leading directory off - a typical file might be in
- # lib/gem_name/file_name.rb, but it will be 'require'd as gem_name/file_name.rb
- gem_lib_files.map! { |f| f.split('/', 2)[1] }
- # if any of the files from the above list appear in $", the gem is assumed to
- # have been loaded
- !(gem_lib_files & $").empty?
- end
- end
- end
-
- def vendor_rails?
- Gem.loaded_specs.has_key?(name) && Gem.loaded_specs[name].loaded_from.empty?
- end
-
- def vendor_gem?
- specification && File.exists?(unpacked_gem_directory)
- end
-
- def build(options={})
- require 'rails/gem_builder'
- return if specification.nil?
- if options[:force] || !built?
- return unless File.exists?(unpacked_specification_filename)
- spec = YAML::load_file(unpacked_specification_filename)
- Rails::GemBuilder.new(spec, unpacked_gem_directory).build_extensions
- puts "Built gem: '#{unpacked_gem_directory}'"
- end
- dependencies.each { |dep| dep.build(options) }
- end
-
- def install
- unless installed?
- cmd = "#{gem_command} #{install_command.join(' ')}"
- puts cmd
- puts %x(#{cmd})
- end
- end
-
- def load
- return if @loaded || @load_paths_added == false
- require(@lib || name) unless @lib == false
- @loaded = true
- rescue LoadError
- puts $!.to_s
- $!.backtrace.each { |b| puts b }
- end
-
- def refresh
- Rails::VendorGemSourceIndex.silence_spec_warnings = true
- real_gems = Gem.source_index.installed_source_index
- exact_dep = Gem::Dependency.new(name, "= #{specification.version}")
- matches = real_gems.search(exact_dep)
- installed_spec = matches.first
- if frozen?
- if installed_spec
- # we have a real copy
- # get a fresh spec - matches should only have one element
- # note that there is no reliable method to check that the loaded
- # spec is the same as the copy from real_gems - Gem.activate changes
- # some of the fields
- real_spec = Gem::Specification.load(matches.first.loaded_from)
- write_specification(real_spec)
- puts "Reloaded specification for #{name} from installed gems."
- else
- # the gem isn't installed locally - write out our current specs
- write_specification(specification)
- puts "Gem #{name} not loaded locally - writing out current spec."
- end
- else
- if framework_gem?
- puts "Gem directory for #{name} not found - check if it's loading before rails."
- else
- puts "Something bad is going on - gem directory not found for #{name}."
- end
- end
- end
-
- def unpack(options={})
- unless frozen? || framework_gem?
- FileUtils.mkdir_p unpack_base
- Dir.chdir unpack_base do
- Gem::GemRunner.new.run(unpack_command)
- end
- # Gem.activate changes the spec - get the original
- real_spec = Gem::Specification.load(specification.loaded_from)
- write_specification(real_spec)
- end
- dependencies.each { |dep| dep.unpack(options) } if options[:recursive]
- end
-
- def write_specification(spec)
- # copy the gem's specification into GEMDIR/.specification so that
- # we can access information about the gem on deployment systems
- # without having the gem installed
- File.open(unpacked_specification_filename, 'w') do |file|
- file.puts spec.to_yaml
- end
- end
-
- def ==(other)
- self.name == other.name && self.requirement == other.requirement
- end
- alias_method :"eql?", :"=="
-
- private
-
- def gem_command
- case RUBY_PLATFORM
- when /win32/
- 'gem.bat'
- when /java/
- 'jruby -S gem'
- else
- 'gem'
- end
- end
-
- def install_command
- cmd = %w(install) << name
- cmd << "--version" << %("#{requirement.to_s}") if requirement
- cmd << "--source" << @source if @source
- cmd
- end
-
- def unpack_command
- cmd = %w(unpack) << name
- cmd << "--version" << "= "+specification.version.to_s if requirement
- cmd
- end
-
- def unpack_base
- Rails::GemDependency.unpacked_path
- end
-
- def unpacked_gem_directory
- File.join(unpack_base, specification.full_name)
- end
-
- def unpacked_specification_filename
- File.join(unpacked_gem_directory, '.specification')
- end
-
- end
-end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 1010e51c94..d1bdbd5253 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -92,8 +92,6 @@ module Rails
generator_path = File.join(spec.full_gem_path, "lib/generators")
paths << generator_path if File.exist?(generator_path)
end
- elsif defined?(Rails.root)
- paths += Dir[File.join(Rails.root, "vendor", "gems", "gems", "*", "lib", "generators")]
end
paths
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 49b13cae2b..93d9ac553d 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -1,4 +1,4 @@
-require 'digest/md5'
+require 'digest/md5'
require 'active_support/secure_random'
require 'rails/version' unless defined?(Rails::VERSION)
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index bcbaa432b7..abe8c1556c 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -5,6 +5,17 @@ gem "rails", "<%= Rails::VERSION::STRING %>"
# Bundling edge rails:
# gem "rails", "<%= Rails::VERSION::STRING %>", :git => "git://github.com/rails/rails.git"
-# You can list more dependencies here
-# gem "nokogiri"
-# gem "merb" # ;) \ No newline at end of file
+# Specify gemcutter as a gem source
+# source "http://gemcutter.org"
+
+# Specify gems that this application depends on and have them installed with rake gems:install
+# gem "bj"
+# gem "hpricot", "0.6"
+# gem "sqlite3-ruby", :require_as => "sqlite3"
+# gem "aws-s3", :require_as => "aws/s3"
+
+# Specify gems that should only be required in certain environments
+# gem "rspec", :only => :test
+# only :test do
+# gem "webrat"
+# end \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/app/templates/Rakefile b/railties/lib/rails/generators/rails/app/templates/Rakefile
index 1dce9863f2..2450a927f0 100755
--- a/railties/lib/rails/generators/rails/app/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/app/templates/Rakefile
@@ -1,7 +1,7 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
-require File.expand_path(File.join(File.dirname(__FILE__), 'config', 'environment'))
+require File.expand_path(File.join(File.dirname(__FILE__), 'config', 'application'))
require 'rake'
require 'rake/testtask'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index cf786093ba..bb30136686 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -1,4 +1,3 @@
-# Bootstrap the Rails environment, frameworks, and default configuration
require File.expand_path(File.join(File.dirname(__FILE__), 'boot'))
Rails::Initializer.run do |config|
@@ -9,12 +8,6 @@ Rails::Initializer.run do |config|
# Add additional load paths for your own custom dirs
# config.load_paths += %W( #{root}/extras )
- # Specify gems that this application depends on and have them installed with rake gems:install
- # config.gem "bj"
- # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
- # config.gem "sqlite3-ruby", :lib => "sqlite3"
- # config.gem "aws-s3", :lib => "aws/s3"
-
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
@@ -45,4 +38,4 @@ Rails::Initializer.run do |config|
# g.template_engine :erb
# g.test_framework :test_unit, :fixture => true
# end
-end \ No newline at end of file
+end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/boot.rb b/railties/lib/rails/generators/rails/app/templates/config/boot.rb
index 928b195d8d..44c884623e 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/boot.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/boot.rb
@@ -1,138 +1,18 @@
-# Don't change this file!
-# Configure your app in config/environment.rb and config/environments/*.rb
-
-module Rails
- # Mark the version of Rails that generated the boot.rb file. This is
- # a temporary solution and will most likely be removed as Rails 3.0
- # comes closer.
- BOOTSTRAP_VERSION = "3.0"
-
- class << self
- def boot!
- unless booted?
- root = File.expand_path('../..', __FILE__)
- booter = File.exist?("#{root}/vendor/rails") ? VendorBoot : GemBoot
- booter.new(root).run
- end
- end
-
- def booted?
- defined? Rails::Initializer
- end
- end
-
- class Boot
- def initialize(root)
- @root = root
- end
-
- def run
- preinitialize
- set_load_paths
- load_initializer
- end
-
- def preinitialize
- path = "#{@root}/config/preinitializer.rb"
- load(path) if File.exist?(path)
- end
-
- def set_load_paths
- %w(
- actionmailer/lib
- actionpack/lib
- activemodel/lib
- activerecord/lib
- activeresource/lib
- activesupport/lib
- railties/lib
- railties
- ).reverse_each do |path|
- path = "#{framework_root_path}/#{path}"
- $LOAD_PATH.unshift(path) if File.directory?(path)
- $LOAD_PATH.uniq!
- end
- end
-
- def framework_root_path
- defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{@root}/vendor/rails"
- end
- end
-
- class VendorBoot < Boot
- def load_initializer
- require "rails"
- install_gem_spec_stubs
- end
-
- def install_gem_spec_stubs
- begin; require "rubygems"; rescue LoadError; return; end
-
- %w(rails activesupport activerecord actionpack actionmailer activeresource).each do |stub|
- Gem.loaded_specs[stub] ||= Gem::Specification.new do |s|
- s.name = stub
- s.version = Rails::VERSION::STRING
- s.loaded_from = ""
- end
- end
- end
- end
-
- class GemBoot < Boot
- def load_initializer
- load_rubygems
- load_rails_gem
- require 'rails'
- end
-
- def load_rails_gem
- if version = gem_version
- gem 'rails', version
- else
- gem 'rails'
- end
- rescue Gem::LoadError => load_error
- $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
- exit 1
- end
-
- def rubygems_version
- Gem::RubyGemsVersion rescue nil
- end
-
- def gem_version
- if defined? RAILS_GEM_VERSION
- RAILS_GEM_VERSION
- elsif ENV.include?('RAILS_GEM_VERSION')
- ENV['RAILS_GEM_VERSION']
- else
- parse_gem_version(read_environment_rb)
- end
- end
-
- def load_rubygems
- min_version = '1.3.2'
- require 'rubygems'
- unless rubygems_version >= min_version
- $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
- exit 1
- end
-
- rescue LoadError
- $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
- exit 1
- end
-
- def parse_gem_version(text)
- $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
- end
-
- private
- def read_environment_rb
- File.read("#{@root}/config/environment.rb")
- end
- end
+# Package management
+# Choose one
+
+environment = File.expand_path('../../vendor/gems/environment', __FILE__)
+vendor_rails = File.expand_path('../../vendor/rails', __FILE__)
+
+if File.exist?(environment)
+ # Use Bundler (preferred)
+ require environment
+elsif File.exist?(vendor_rails)
+ # Use 2.x style vendor/rails directory
+ Dir["#{vendor_rails}/*/lib"].each { |path| $:.unshift(path) }
+else
+ # Load Rails from traditional RubyGems
+ require 'rubygems'
end
-# All that for this:
-Rails.boot!
+require 'rails'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environment.rb b/railties/lib/rails/generators/rails/app/templates/config/environment.rb
index 3bb0f2619e..e5362b21cc 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environment.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/environment.rb
@@ -1,9 +1,5 @@
-# Be sure to restart your server when you modify this file
-
-# Specifies gem version of Rails to use when vendor/rails is not present
-<%= '# ' if options[:freeze] %>RAILS_GEM_VERSION = '<%= Rails::VERSION::STRING %>' unless defined? RAILS_GEM_VERSION
-
# Load the rails application
require File.expand_path(File.join(File.dirname(__FILE__), 'application'))
+
# Initialize the rails application
Rails.initialize!
diff --git a/railties/lib/rails/initializer.rb b/railties/lib/rails/initializer.rb
index 070a385052..2ad1e52746 100644
--- a/railties/lib/rails/initializer.rb
+++ b/railties/lib/rails/initializer.rb
@@ -4,7 +4,6 @@ require 'rails/initializable'
require 'rails/application'
require 'rails/railties_path'
require 'rails/version'
-require 'rails/gem_dependency'
require 'rails/rack'
require 'rails/paths'
require 'rails/core'
diff --git a/railties/lib/rails/plugin/locator.rb b/railties/lib/rails/plugin/locator.rb
index 1057c004e0..56cbaf37c6 100644
--- a/railties/lib/rails/plugin/locator.rb
+++ b/railties/lib/rails/plugin/locator.rb
@@ -78,7 +78,7 @@ module Rails
# a <tt>rails/init.rb</tt> file.
class GemLocator < Locator
def plugins
- gem_index = initializer.configuration.gems.inject({}) { |memo, gem| memo.update gem.specification => gem }
+ gem_index = {}
specs = gem_index.keys
specs += Gem.loaded_specs.values.select do |spec|
spec.loaded_from && # prune stubs
diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb
index 148a3d4d30..82113a297c 100644
--- a/railties/lib/rails/tasks.rb
+++ b/railties/lib/rails/tasks.rb
@@ -6,7 +6,6 @@ $VERBOSE = nil
databases
documentation
framework
- gems
log
middleware
misc
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index 3d7e4b5453..1611d1d94d 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -100,11 +100,6 @@ namespace :rails do
generator.invoke(method)
end
- desc "Update config/boot.rb from your current rails install"
- task :configs do
- invoke_from_app_generator :create_boot_file
- end
-
desc "Update Prototype javascripts from your current rails install"
task :javascripts do
invoke_from_app_generator :create_prototype_files
diff --git a/railties/lib/rails/tasks/gems.rake b/railties/lib/rails/tasks/gems.rake
deleted file mode 100644
index 1903efd5f6..0000000000
--- a/railties/lib/rails/tasks/gems.rake
+++ /dev/null
@@ -1,78 +0,0 @@
-desc "List the gems that this rails application depends on"
-task :gems => 'gems:base' do
- Rails.configuration.gems.each do |gem|
- print_gem_status(gem)
- end
- puts
- puts "I = Installed"
- puts "F = Frozen"
- puts "R = Framework (loaded before rails starts)"
-end
-
-namespace :gems do
- task :base do
- $gems_rake_task = true
- require 'rubygems'
- require 'rubygems/gem_runner'
- Rake::Task[:environment].invoke
- end
-
- desc "Build any native extensions for unpacked gems"
- task :build do
- $gems_build_rake_task = true
- frozen_gems.each { |gem| gem.build }
- end
-
- namespace :build do
- desc "Force the build of all gems"
- task :force do
- $gems_build_rake_task = true
- frozen_gems.each { |gem| gem.build(:force => true) }
- end
- end
-
- desc "Installs all required gems."
- task :install => :base do
- current_gems.each { |gem| gem.install }
- end
-
- desc "Unpacks all required gems into vendor/gems."
- task :unpack => :install do
- current_gems.each { |gem| gem.unpack }
- end
-
- namespace :unpack do
- desc "Unpacks all required gems and their dependencies into vendor/gems."
- task :dependencies => :install do
- current_gems.each { |gem| gem.unpack(:recursive => true) }
- end
- end
-
- desc "Regenerate gem specifications in correct format."
- task :refresh_specs do
- frozen_gems(false).each { |gem| gem.refresh }
- end
-end
-
-def current_gems
- gems = Rails.configuration.gems
- gems = gems.select { |gem| gem.name == ENV['GEM'] } unless ENV['GEM'].blank?
- gems
-end
-
-def frozen_gems(load_specs=true)
- Dir[File.join(Rails.root, 'vendor', 'gems', '*-*')].map do |gem_dir|
- Rails::GemDependency.from_directory_name(gem_dir, load_specs)
- end
-end
-
-def print_gem_status(gem, indent=1)
- code = case
- when gem.framework_gem? then 'R'
- when gem.frozen? then 'F'
- when gem.installed? then 'I'
- else ' '
- end
- puts " "*(indent-1)+" - [#{code}] #{gem.name} #{gem.requirement.to_s}"
- gem.dependencies.each { |g| print_gem_status(g, indent+1) }
-end
diff --git a/railties/lib/rails/tasks/statistics.rake b/railties/lib/rails/tasks/statistics.rake
index 2dcc7bdf9d..40f8c1034a 100644
--- a/railties/lib/rails/tasks/statistics.rake
+++ b/railties/lib/rails/tasks/statistics.rake
@@ -1,14 +1,13 @@
STATS_DIRECTORIES = [
%w(Controllers app/controllers),
- %w(Helpers app/helpers),
+ %w(Helpers app/helpers),
%w(Models app/models),
%w(Libraries lib/),
%w(APIs app/apis),
%w(Integration\ tests test/integration),
%w(Functional\ tests test/functional),
%w(Unit\ tests test/unit)
-
-].collect { |name, dir| [ name, "#{RAILS_ROOT}/#{dir}" ] }.select { |name, dir| File.directory?(dir) }
+].collect { |name, dir| [ name, "#{Rails.root}/#{dir}" ] }.select { |name, dir| File.directory?(dir) }
desc "Report code statistics (KLOCs, etc) from the application"
task :stats do
diff --git a/railties/lib/rails/vendor_gem_source_index.rb b/railties/lib/rails/vendor_gem_source_index.rb
deleted file mode 100644
index 5b7721f303..0000000000
--- a/railties/lib/rails/vendor_gem_source_index.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-require 'rubygems'
-require 'yaml'
-
-module Rails
-
- class VendorGemSourceIndex
- # VendorGemSourceIndex acts as a proxy for the Gem source index, allowing
- # gems to be loaded from vendor/gems. Rather than the standard gem repository format,
- # vendor/gems contains unpacked gems, with YAML specifications in .specification in
- # each gem directory.
- include Enumerable
-
- attr_reader :installed_source_index
- attr_reader :vendor_source_index
-
- @@silence_spec_warnings = false
-
- def self.silence_spec_warnings
- @@silence_spec_warnings
- end
-
- def self.silence_spec_warnings=(v)
- @@silence_spec_warnings = v
- end
-
- def initialize(installed_index, vendor_dir=Rails::GemDependency.unpacked_path)
- @installed_source_index = installed_index
- @vendor_dir = vendor_dir
- refresh!
- end
-
- def refresh!
- # reload the installed gems
- @installed_source_index.refresh!
- vendor_gems = {}
-
- # handle vendor Rails gems - they are identified by having loaded_from set to ""
- # we add them manually to the list, so that other gems can find them via dependencies
- Gem.loaded_specs.each do |n, s|
- next unless s.loaded_from.empty?
- vendor_gems[s.full_name] = s
- end
-
- # load specifications from vendor/gems
- Dir[File.join(Rails::GemDependency.unpacked_path, '*')].each do |d|
- dir_name = File.basename(d)
- dir_version = version_for_dir(dir_name)
- spec = load_specification(d)
- if spec
- if spec.full_name != dir_name
- # mismatched directory name and gem spec - produced by 2.1.0-era unpack code
- if dir_version
- # fix the spec version - this is not optimal (spec.files may be wrong)
- # but it's better than breaking apps. Complain to remind users to get correct specs.
- # use ActiveSupport::Deprecation.warn, as the logger is not set yet
- $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems has a mismatched specification file."+
- " Run 'rake gems:refresh_specs' to fix this.") unless @@silence_spec_warnings
- spec.version = dir_version
- else
- $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems is not in a versioned directory"+
- "(should be #{spec.full_name}).") unless @@silence_spec_warnings
- # continue, assume everything is OK
- end
- end
- else
- # no spec - produced by early-2008 unpack code
- # emulate old behavior, and complain.
- $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems has no specification file."+
- " Run 'rake gems:refresh_specs' to fix this.") unless @@silence_spec_warnings
- if dir_version
- spec = Gem::Specification.new
- spec.version = dir_version
- spec.require_paths = ['lib']
- ext_path = File.join(d, 'ext')
- spec.require_paths << 'ext' if File.exist?(ext_path)
- spec.name = /^(.*)-[^-]+$/.match(dir_name)[1]
- files = ['lib']
- # set files to everything in lib/
- files += Dir[File.join(d, 'lib', '*')].map { |v| v.gsub(/^#{d}\//, '') }
- files += Dir[File.join(d, 'ext', '*')].map { |v| v.gsub(/^#{d}\//, '') } if ext_path
- spec.files = files
- else
- $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems not in a versioned directory."+
- " Giving up.") unless @@silence_spec_warnings
- next
- end
- end
- spec.loaded_from = File.join(d, '.specification')
- # finally, swap out full_gem_path
- # it would be better to use a Gem::Specification subclass, but the YAML loads an explicit class
- class << spec
- def full_gem_path
- path = File.join installation_path, full_name
- return path if File.directory? path
- File.join installation_path, original_name
- end
- end
- vendor_gems[File.basename(d)] = spec
- end
- @vendor_source_index = Gem::SourceIndex.new(vendor_gems)
- end
-
- def version_for_dir(d)
- matches = /-([^-]+)$/.match(d)
- Gem::Version.new(matches[1]) if matches
- end
-
- def load_specification(gem_dir)
- spec_file = File.join(gem_dir, '.specification')
- YAML.load_file(spec_file) if File.exist?(spec_file)
- end
-
- def find_name(*args)
- @installed_source_index.find_name(*args) + @vendor_source_index.find_name(*args)
- end
-
- def search(*args)
- # look for vendor gems, and then installed gems - later elements take priority
- @installed_source_index.search(*args) + @vendor_source_index.search(*args)
- end
-
- def each(&block)
- @vendor_source_index.each(&block)
- @installed_source_index.each(&block)
- end
-
- def add_spec(spec)
- @vendor_source_index.add_spec spec
- end
-
- def remove_spec(spec)
- @vendor_source_index.remove_spec spec
- end
-
- def size
- @vendor_source_index.size + @installed_source_index.size
- end
-
- end
-end
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 0452208cae..a3e1916494 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -7,7 +7,6 @@ module ApplicationTests
def setup
build_app
boot_rails
- Object.send(:remove_const, :RAILS_ROOT)
end
test "the application root is set correctly" do
diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb
index 03fecffdd0..445a867c85 100644
--- a/railties/test/application/generators_test.rb
+++ b/railties/test/application/generators_test.rb
@@ -7,6 +7,7 @@ module ApplicationTests
def setup
build_app
boot_rails
+ require "rails"
require "rails/generators"
end
diff --git a/railties/test/application/initializer_test.rb b/railties/test/application/initializer_test.rb
index c2e64374d0..f42954079b 100644
--- a/railties/test/application/initializer_test.rb
+++ b/railties/test/application/initializer_test.rb
@@ -7,6 +7,7 @@ module ApplicationTests
def setup
build_app
boot_rails
+ require "rails"
end
test "initializing an application initializes rails" do
diff --git a/railties/test/application/notifications_test.rb b/railties/test/application/notifications_test.rb
index 0fdb4a083a..83c18be057 100644
--- a/railties/test/application/notifications_test.rb
+++ b/railties/test/application/notifications_test.rb
@@ -24,7 +24,7 @@ module ApplicationTests
def setup
build_app
boot_rails
-
+ require "rails"
require "active_support/notifications"
Rails::Initializer.run do |c|
c.notifications.queue = MyQueue.new
diff --git a/railties/test/application/plugins_test.rb b/railties/test/application/plugins_test.rb
index 0926ed106b..80a19856d7 100644
--- a/railties/test/application/plugins_test.rb
+++ b/railties/test/application/plugins_test.rb
@@ -11,6 +11,7 @@ module ApplicationTests
def setup
build_app
boot_rails
+ require "rails"
@failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
# Tmp hax to get tests working
FileUtils.cp_r "#{File.dirname(__FILE__)}/../fixtures/plugins", "#{app_path}/vendor"
diff --git a/railties/test/backtrace_cleaner_test.rb b/railties/test/backtrace_cleaner_test.rb
index f9b9d3168d..64a47712b7 100644
--- a/railties/test/backtrace_cleaner_test.rb
+++ b/railties/test/backtrace_cleaner_test.rb
@@ -35,7 +35,7 @@ class BacktraceCleanerVendorGemTest < ActiveSupport::TestCase
end
test "should format installed gems correctly" do
- @backtrace = [ "#{Gem.default_dir}/gems/nosuchgem-1.2.3/lib/foo.rb" ]
+ @backtrace = [ "#{Gem.path[0]}/gems/nosuchgem-1.2.3/lib/foo.rb" ]
@result = @cleaner.clean(@backtrace)
assert_equal "nosuchgem (1.2.3) lib/foo.rb", @result[0]
end
@@ -50,10 +50,4 @@ class BacktraceCleanerVendorGemTest < ActiveSupport::TestCase
end
end
- test "should format vendor gems correctly" do
- @backtrace = [ "#{Rails::GemDependency.unpacked_path}/nosuchgem-1.2.3/lib/foo.rb" ]
- @result = @cleaner.clean(@backtrace)
- assert_equal "nosuchgem (1.2.3) [v] lib/foo.rb", @result[0]
- end
-
end
diff --git a/railties/test/gem_dependency_test.rb b/railties/test/gem_dependency_test.rb
deleted file mode 100644
index 92132be992..0000000000
--- a/railties/test/gem_dependency_test.rb
+++ /dev/null
@@ -1,220 +0,0 @@
-require 'plugin_test_helper'
-require 'rails/gem_dependency'
-
-class Rails::GemDependency
- public :install_command, :unpack_command
-end
-
-Rails::VendorGemSourceIndex.silence_spec_warnings = true
-
-class GemDependencyTest < Test::Unit::TestCase
- def setup
- @gem = Rails::GemDependency.new "xhpricotx"
- @gem_with_source = Rails::GemDependency.new "xhpricotx", :source => "http://code.whytheluckystiff.net"
- @gem_with_version = Rails::GemDependency.new "xhpricotx", :version => "= 0.6"
- @gem_with_lib = Rails::GemDependency.new "xaws-s3x", :lib => "aws/s3"
- @gem_without_load = Rails::GemDependency.new "xhpricotx", :lib => false
- end
-
- def test_configuration_adds_gem_dependency
- config = Rails::Configuration.new
- config.gem "xaws-s3x", :lib => "aws/s3", :version => "0.4.0"
- assert_equal [["install", "xaws-s3x", "--version", '"= 0.4.0"']], config.gems.collect { |g| g.install_command }
- end
-
- def test_gem_creates_install_command
- assert_equal %w(install xhpricotx), @gem.install_command
- end
-
- def test_gem_with_source_creates_install_command
- assert_equal %w(install xhpricotx --source http://code.whytheluckystiff.net), @gem_with_source.install_command
- end
-
- def test_gem_with_version_creates_install_command
- assert_equal ["install", "xhpricotx", "--version", '"= 0.6"'], @gem_with_version.install_command
- end
-
- def test_gem_creates_unpack_command
- assert_equal %w(unpack xhpricotx), @gem.unpack_command
- end
-
- def test_gem_with_version_unpack_install_command
- # stub out specification method, or else test will fail if hpricot 0.6 isn't installed
- mock_spec = mock()
- mock_spec.stubs(:version).returns('0.6')
- @gem_with_version.stubs(:specification).returns(mock_spec)
- assert_equal ["unpack", "xhpricotx", "--version", '= 0.6'], @gem_with_version.unpack_command
- end
-
- def test_gem_adds_load_paths
- @gem.expects(:gem).with(@gem)
- @gem.add_load_paths
- end
-
- def test_gem_with_version_adds_load_paths
- @gem_with_version.expects(:gem).with(@gem_with_version)
- @gem_with_version.add_load_paths
- assert @gem_with_version.load_paths_added?
- end
-
- def test_gem_loading
- @gem.expects(:gem).with(@gem)
- @gem.expects(:require).with(@gem.name)
- @gem.add_load_paths
- @gem.load
- assert @gem.loaded?
- end
-
- def test_gem_with_lib_loading
- @gem_with_lib.expects(:gem).with(@gem_with_lib)
- @gem_with_lib.expects(:require).with(@gem_with_lib.lib)
- @gem_with_lib.add_load_paths
- @gem_with_lib.load
- assert @gem_with_lib.loaded?
- end
-
- def test_gem_without_lib_loading
- @gem_without_load.expects(:gem).with(@gem_without_load)
- @gem_without_load.expects(:require).with(@gem_without_load.lib).never
- @gem_without_load.add_load_paths
- @gem_without_load.load
- end
-
- def test_gem_dependencies_compare_for_uniq
- gem1 = Rails::GemDependency.new "gem1"
- gem1a = Rails::GemDependency.new "gem1"
- gem2 = Rails::GemDependency.new "gem2"
- gem2a = Rails::GemDependency.new "gem2"
- gem3 = Rails::GemDependency.new "gem2", :version => ">=0.1"
- gem3a = Rails::GemDependency.new "gem2", :version => ">=0.1"
- gem4 = Rails::GemDependency.new "gem3"
- gems = [gem1, gem2, gem1a, gem3, gem2a, gem4, gem3a, gem2, gem4]
- assert_equal 4, gems.uniq.size
- end
-
- def test_gem_load_frozen
- dummy_gem = Rails::GemDependency.new "dummy-gem-a"
- dummy_gem.add_load_paths
- dummy_gem.load
- assert_not_nil DUMMY_GEM_A_VERSION
- end
-
- def test_gem_load_frozen_specific_version
- dummy_gem = Rails::GemDependency.new "dummy-gem-b", :version => '0.4.0'
- dummy_gem.add_load_paths
- dummy_gem.load
- assert_not_nil DUMMY_GEM_B_VERSION
- assert_equal '0.4.0', DUMMY_GEM_B_VERSION
- end
-
- def test_gem_load_frozen_minimum_version
- dummy_gem = Rails::GemDependency.new "dummy-gem-c", :version => '>=0.5.0'
- dummy_gem.add_load_paths
- dummy_gem.load
- assert_not_nil DUMMY_GEM_C_VERSION
- assert_equal '0.6.0', DUMMY_GEM_C_VERSION
- end
-
- def test_gem_load_missing_specification
- dummy_gem = Rails::GemDependency.new "dummy-gem-d"
- dummy_gem.add_load_paths
- dummy_gem.load
- assert_not_nil DUMMY_GEM_D_VERSION
- assert_equal '1.0.0', DUMMY_GEM_D_VERSION
- assert_equal ['lib', 'lib/dummy-gem-d.rb'], dummy_gem.specification.files
- end
-
- def test_gem_load_bad_specification
- dummy_gem = Rails::GemDependency.new "dummy-gem-e", :version => "= 1.0.0"
- dummy_gem.add_load_paths
- dummy_gem.load
- assert_not_nil DUMMY_GEM_E_VERSION
- assert_equal '1.0.0', DUMMY_GEM_E_VERSION
- end
-
- def test_gem_handle_missing_dependencies
- dummy_gem = Rails::GemDependency.new "dummy-gem-g"
- dummy_gem.add_load_paths
- dummy_gem.load
- assert_equal 1, dummy_gem.dependencies.size
- assert_equal 1, dummy_gem.dependencies.first.dependencies.size
- assert_nothing_raised do
- dummy_gem.dependencies.each do |g|
- g.dependencies
- end
- end
- end
-
- def test_gem_ignores_development_dependencies
- dummy_gem = Rails::GemDependency.new "dummy-gem-k"
- dummy_gem.add_load_paths
- dummy_gem.load
- assert_equal 1, dummy_gem.dependencies.size
- end
-
- def test_gem_guards_against_duplicate_unpacks
- dummy_gem = Rails::GemDependency.new "dummy-gem-a"
- dummy_gem.stubs(:frozen?).returns(true)
- dummy_gem.expects(:unpack_base).never
- dummy_gem.unpack
- end
-
- def test_gem_does_not_unpack_framework_gems
- dummy_gem = Rails::GemDependency.new "dummy-gem-a"
- dummy_gem.stubs(:framework_gem?).returns(true)
- dummy_gem.expects(:unpack_base).never
- dummy_gem.unpack
- end
-
- def test_gem_from_directory_name_attempts_to_load_specification
- assert_raises RuntimeError do
- dummy_gem = Rails::GemDependency.from_directory_name('dummy-gem-1.1')
- end
- end
-
- def test_gem_from_directory_name
- dummy_gem = Rails::GemDependency.from_directory_name('dummy-gem-1.1', false)
- assert_equal 'dummy-gem', dummy_gem.name
- assert_equal '= 1.1', dummy_gem.version_requirements.to_s
- end
-
- def test_gem_from_directory_name_loads_specification_successfully
- assert_nothing_raised do
- dummy_gem = Rails::GemDependency.from_directory_name(File.join(Rails::GemDependency.unpacked_path, 'dummy-gem-g-1.0.0'))
- assert_not_nil dummy_gem.specification
- end
- end
-
- def test_gem_from_invalid_directory_name
- assert_raises RuntimeError do
- dummy_gem = Rails::GemDependency.from_directory_name('dummy-gem')
- end
- assert_raises RuntimeError do
- dummy_gem = Rails::GemDependency.from_directory_name('dummy')
- end
- end
-
- def test_gem_determines_build_status
- assert_equal true, Rails::GemDependency.new("dummy-gem-a").built?
- assert_equal true, Rails::GemDependency.new("dummy-gem-i").built?
- assert_equal false, Rails::GemDependency.new("dummy-gem-j").built?
- end
-
- def test_gem_determines_build_status_only_on_vendor_gems
- framework_gem = Rails::GemDependency.new('dummy-framework-gem')
- framework_gem.stubs(:framework_gem?).returns(true) # already loaded
- framework_gem.stubs(:vendor_rails?).returns(false) # but not in vendor/rails
- framework_gem.stubs(:vendor_gem?).returns(false) # and not in vendor/gems
- framework_gem.add_load_paths # freeze framework gem early
- assert framework_gem.built?
- end
-
- def test_gem_build_passes_options_to_dependencies
- start_gem = Rails::GemDependency.new("dummy-gem-g")
- dep_gem = Rails::GemDependency.new("dummy-gem-f")
- start_gem.stubs(:dependencies).returns([dep_gem])
- dep_gem.expects(:build).with({ :force => true }).once
- start_gem.build(:force => true)
- end
-
-end
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index adc61f6d8a..199b5fa8b4 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -89,7 +89,7 @@ class ActionsTest < GeneratorsTestCase
def test_environment_should_include_data_in_environment_initializer_block
run_generator
- load_paths = 'config.load_paths += %w["#{RAILS_ROOT}/app/extras"]'
+ load_paths = 'config.load_paths += %w["#{Rails.root}/app/extras"]'
action :environment, load_paths
assert_file 'config/application.rb', /#{Regexp.escape(load_paths)}/
end
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 5d6a9f6de9..3eefaf9b02 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -114,11 +114,11 @@ class AppGeneratorTest < GeneratorsTestCase
generator(:freeze => true, :database => "sqlite3").expects(:run).
with("rake rails:freeze:edge", :verbose => false)
silence(:stdout){ generator.invoke }
- assert_file 'config/environment.rb', /# RAILS_GEM_VERSION/
+ assert_file 'config/environment.rb'
end
def test_template_from_dir_pwd
- FileUtils.cd(RAILS_ROOT)
+ FileUtils.cd(Rails.root)
assert_match /It works from file!/, run_generator(["-m", "lib/template.rb"])
end
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index 7e6b7b183c..178b5ef6de 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -80,7 +80,7 @@ class GeneratorsTest < GeneratorsTestCase
Rails::Generators.instance_variable_set(:@load_paths, nil)
spec = Gem::Specification.new
- spec.expects(:full_gem_path).returns(File.join(RAILS_ROOT, 'vendor', 'another_gem_path', 'xspec'))
+ spec.expects(:full_gem_path).returns(File.join(Rails.root, 'vendor', 'another_gem_path', 'xspec'))
Gem.expects(:respond_to?).with(:loaded_specs).returns(true)
Gem.expects(:loaded_specs).returns(:spec => spec)
@@ -101,10 +101,11 @@ class GeneratorsTest < GeneratorsTestCase
def test_rails_generators_with_others_information
output = capture(:stdout){ Rails::Generators.help }.split("\n").last
- assert_equal "Others: active_record:fixjour, fixjour, mspec, rails:javascripts, wrong.", output
+ assert_equal "Others: active_record:fixjour, fixjour, mspec, rails:javascripts.", output
end
def test_warning_is_shown_if_generator_cant_be_loaded
+ Rails::Generators.load_paths << File.expand_path("../fixtures/vendor/gems/gems/wrong", __FILE__)
output = capture(:stderr){ Rails::Generators.find_by_namespace(:wrong) }
assert_match /\[WARNING\] Could not load generator at/, output
assert_match /Error: uninitialized constant Rails::Generator/, output
@@ -118,7 +119,7 @@ class GeneratorsTest < GeneratorsTestCase
end
def test_rails_root_templates
- template = File.join(RAILS_ROOT, "lib", "templates", "active_record", "model", "model.rb")
+ template = File.join(Rails.root, "lib", "templates", "active_record", "model", "model.rb")
# Create template
mkdir_p(File.dirname(template))
@@ -170,6 +171,6 @@ class GeneratorsTest < GeneratorsTestCase
def test_source_paths_for_not_namespaced_generators
mspec = Rails::Generators.find_by_namespace :mspec
- assert mspec.source_paths.include?(File.join(RAILS_ROOT, "lib", "templates", "mspec"))
+ assert mspec.source_paths.include?(File.join(Rails.root, "lib", "templates", "mspec"))
end
end
diff --git a/railties/test/initializer/check_ruby_version_test.rb b/railties/test/initializer/check_ruby_version_test.rb
index 0c725311ad..cf956e68fb 100644
--- a/railties/test/initializer/check_ruby_version_test.rb
+++ b/railties/test/initializer/check_ruby_version_test.rb
@@ -7,6 +7,7 @@ module InitializerTests
def setup
build_app
boot_rails
+ require "rails"
end
test "rails does not initialize with ruby version 1.8.1" do
diff --git a/railties/test/initializer/initialize_i18n_test.rb b/railties/test/initializer/initialize_i18n_test.rb
index 04b44cedd0..d664f96ad1 100644
--- a/railties/test/initializer/initialize_i18n_test.rb
+++ b/railties/test/initializer/initialize_i18n_test.rb
@@ -7,6 +7,7 @@ module InitializerTests
def setup
build_app
boot_rails
+ require "rails"
end
# test_config_defaults_and_settings_should_be_added_to_i18n_defaults
diff --git a/railties/test/initializer/path_test.rb b/railties/test/initializer/path_test.rb
index 9c36bb2000..1b58a58555 100644
--- a/railties/test/initializer/path_test.rb
+++ b/railties/test/initializer/path_test.rb
@@ -6,6 +6,7 @@ class PathsTest < Test::Unit::TestCase
def setup
build_app
boot_rails
+ require "rails"
Rails::Initializer.run do |config|
config.root = app_path
config.frameworks = [:action_controller, :action_view, :action_mailer, :active_record]
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 750ec5d319..aafc9f68bb 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -114,16 +114,19 @@ module TestHelpers
end
def boot_rails
- # TMP mega hax to prevent boot.rb from actually booting
- Object.class_eval <<-RUBY, __FILE__, __LINE__+1
- module Rails
- Initializer = 'lol'
- require "#{app_path}/config/boot"
- remove_const(:Initializer)
- booter = VendorBoot.new('#{app_path}')
- booter.run
- end
- RUBY
+ %w(
+ actionmailer/lib
+ actionpack/lib
+ activemodel/lib
+ activerecord/lib
+ activeresource/lib
+ activesupport/lib
+ railties/lib
+ railties
+ ).reverse_each do |path|
+ path = File.expand_path("../../../../#{path}", __FILE__)
+ $:.unshift(path)
+ end
end
end
end
diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb
index 99cf9168e1..a0484c0868 100644
--- a/railties/test/rails_info_controller_test.rb
+++ b/railties/test/rails_info_controller_test.rb
@@ -4,10 +4,6 @@ require 'action_controller'
require 'rails/info'
require 'rails/info_controller'
-ActionController::Routing::Routes.draw do |map|
- map.connect ':controller/:action/:id'
-end
-
module ActionController
class Base
include ActionController::Testing
@@ -18,9 +14,17 @@ class InfoControllerTest < ActionController::TestCase
tests Rails::InfoController
def setup
+ ActionController::Routing.use_controllers!(['rails/info'])
+ ActionController::Routing::Routes.draw do |map|
+ map.connect ':controller/:action/:id'
+ end
@controller.stubs(:consider_all_requests_local => false, :local_request? => true)
end
+ def teardown
+ ActionController::Routing.use_controllers! nil
+ end
+
test "info controller does not allow remote requests" do
@controller.stubs(:consider_all_requests_local => false, :local_request? => false)
get :properties