aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile5
-rwxr-xr-xRakefile5
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/action_controller/test_case.rb2
-rw-r--r--actionpack/lib/action_view.rb1
-rw-r--r--actionpack/lib/action_view/asset_paths.rb79
-rw-r--r--actionpack/lib/action_view/helpers/asset_paths.rb82
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb3
-rw-r--r--actionpack/lib/action_view/helpers/cache_helper.rb10
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb1
-rw-r--r--actionpack/lib/sprockets/helpers/rails_helper.rb3
-rw-r--r--actionpack/lib/sprockets/railtie.rb4
-rw-r--r--actionpack/test/template/text_helper_test.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb2
-rw-r--r--activerecord/lib/active_record/query_cache.rb8
-rw-r--r--activerecord/lib/active_record/railties/databases.rake2
-rw-r--r--activerecord/test/cases/connection_management_test.rb7
-rw-r--r--activerecord/test/cases/migration_test.rb12
-rw-r--r--activerecord/test/cases/query_cache_test.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb24
-rw-r--r--activesupport/test/core_ext/class/attribute_test.rb6
-rw-r--r--railties/lib/rails.rb23
-rw-r--r--railties/lib/rails/generators.rb3
-rw-r--r--railties/lib/rails/generators/actions.rb8
-rw-r--r--railties/lib/rails/generators/app_base.rb6
-rw-r--r--railties/lib/rails/generators/base.rb6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile18
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb7
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/Gemfile7
-rw-r--r--railties/lib/rails/tasks/assets.rake21
-rw-r--r--railties/test/application/assets_test.rb28
-rw-r--r--railties/test/application/configuration_test.rb15
-rw-r--r--railties/test/fixtures/lib/generators/wrong_generator.rb3
-rw-r--r--railties/test/generators_test.rb6
-rw-r--r--railties/test/isolation/abstract_unit.rb4
37 files changed, 293 insertions, 152 deletions
diff --git a/Gemfile b/Gemfile
index fc4fdb17f5..ef9f613955 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,7 +10,7 @@ end
gem "coffee-script"
gem "sass"
-gem "uglifier", :git => "git://github.com/lautis/uglifier.git"
+gem "uglifier", ">= 1.0.0"
gem "rake", ">= 0.8.7"
gem "mocha", ">= 0.9.8"
@@ -26,9 +26,6 @@ gem "memcache-client", ">= 1.8.5"
platforms :mri_18 do
gem "system_timer"
- # ruby-debug requires linecache which depends on require_relative but doesn't explicitly
- # declare this in its gemspec
- gem "require_relative"
gem "ruby-debug", ">= 0.10.3"
gem "json"
end
diff --git a/Rakefile b/Rakefile
index b3bde156d1..d18dac0dbd 100755
--- a/Rakefile
+++ b/Rakefile
@@ -61,6 +61,9 @@ RDoc::Task.new do |rdoc|
# The temporary solution is to have a README.rdoc without backslashes for
# GitHub, and gsub it to generate the main page of the API.
#
+ # Also, relative links in GitHub have to point to blobs, whereas in the API
+ # they need to point to files.
+ #
# The idea for the future is to have totally different files, since the
# API is no longer a generic entry point to Rails and deserves a
# dedicated main page specifically thought as an API entry point.
@@ -71,7 +74,7 @@ RDoc::Task.new do |rdoc|
# since no autolinking happens there and RDoc displays the backslash
# otherwise.
rdoc_main.gsub!(/^(?=\S).*?\b(?=Rails)\b/) { "#$&\\" }
- rdoc_main.gsub!(/link:blob\/master\/(\w+)\/README.rdoc/, "link:files/\\1/README_rdoc.html")
+ rdoc_main.gsub!(%r{link:blob/master/(\w+)/README\.rdoc}, "link:files/\\1/README_rdoc.html")
File.open(RDOC_MAIN, 'w') do |f|
f.write(rdoc_main)
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index 37a3d960f1..96ab168674 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
s.add_dependency('rack', '~> 1.3.0')
s.add_dependency('rack-test', '~> 0.6.0')
s.add_dependency('rack-mount', '~> 0.8.1')
- s.add_dependency('sprockets', '~> 2.0.0.beta.10')
+ s.add_dependency('sprockets', '~> 2.0.0.beta.11')
s.add_dependency('tzinfo', '~> 0.3.27')
s.add_dependency('erubis', '~> 2.7.0')
end
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index d14bb666cc..45bb641aee 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -210,7 +210,7 @@ module ActionController
DEFAULT_OPTIONS = Rack::Session::Abstract::ID::DEFAULT_OPTIONS
def initialize(session = {})
- @env, @by = nil, nil
+ super(nil, nil)
replace(session.stringify_keys)
@loaded = true
end
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 78eddb7530..d7229419a9 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -30,6 +30,7 @@ module ActionView
extend ActiveSupport::Autoload
eager_autoload do
+ autoload :AssetPaths
autoload :Base
autoload :Context
autoload :Helpers
diff --git a/actionpack/lib/action_view/asset_paths.rb b/actionpack/lib/action_view/asset_paths.rb
new file mode 100644
index 0000000000..2b1fe545a6
--- /dev/null
+++ b/actionpack/lib/action_view/asset_paths.rb
@@ -0,0 +1,79 @@
+require 'active_support/core_ext/file'
+
+module ActionView
+ class AssetPaths #:nodoc:
+ attr_reader :config, :controller
+
+ def initialize(config, controller)
+ @config = config
+ @controller = controller
+ end
+
+ # Add the extension +ext+ if not present. Return full or scheme-relative URLs otherwise untouched.
+ # Prefix with <tt>/dir/</tt> if lacking a leading +/+. Account for relative URL
+ # roots. Rewrite the asset path for cache-busting asset ids. Include
+ # asset host, if configured, with the correct request protocol.
+ def compute_public_path(source, dir, ext = nil, include_host = true)
+ source = source.to_s
+ return source if is_uri?(source)
+
+ source = rewrite_extension(source, dir, ext) if ext
+ source = rewrite_asset_path(source, dir)
+
+ if controller && include_host
+ has_request = controller.respond_to?(:request)
+ source = rewrite_host_and_protocol(source, has_request)
+ end
+
+ source
+ end
+
+ def is_uri?(path)
+ path =~ %r{^[-a-z]+://|^cid:|^//}
+ end
+
+ private
+
+ def rewrite_extension(source, dir, ext)
+ raise NotImplementedError
+ end
+
+ def rewrite_asset_path(source, path = nil)
+ raise NotImplementedError
+ end
+
+ def rewrite_relative_url_root(source, relative_url_root)
+ relative_url_root && !source.starts_with?("#{relative_url_root}/") ? "#{relative_url_root}#{source}" : source
+ end
+
+ def rewrite_host_and_protocol(source, has_request)
+ source = rewrite_relative_url_root(source, controller.config.relative_url_root) if has_request
+ host = compute_asset_host(source)
+ if has_request && host && !is_uri?(host)
+ host = "#{controller.request.protocol}#{host}"
+ end
+ "#{host}#{source}"
+ end
+
+ # Pick an asset host for this source. Returns +nil+ if no host is set,
+ # the host if no wildcard is set, the host interpolated with the
+ # numbers 0-3 if it contains <tt>%d</tt> (the number is the source hash mod 4),
+ # or the value returned from invoking call on an object responding to call
+ # (proc or otherwise).
+ def compute_asset_host(source)
+ if host = config.asset_host
+ if host.respond_to?(:call)
+ case host.is_a?(Proc) ? host.arity : host.method(:call).arity
+ when 2
+ request = controller.respond_to?(:request) && controller.request
+ host.call(source, request)
+ else
+ host.call(source)
+ end
+ else
+ (host =~ /%d/) ? host % (source.hash % 4) : host
+ end
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_view/helpers/asset_paths.rb b/actionpack/lib/action_view/helpers/asset_paths.rb
index 9a99c3cf52..fae2e4fc1c 100644
--- a/actionpack/lib/action_view/helpers/asset_paths.rb
+++ b/actionpack/lib/action_view/helpers/asset_paths.rb
@@ -1,83 +1,7 @@
-require 'active_support/core_ext/file'
+ActiveSupport::Deprecation.warn "ActionView::Helpers::AssetPaths is deprecated. Please use ActionView::AssetPaths instead."
module ActionView
module Helpers
-
- class AssetPaths #:nodoc:
- attr_reader :config, :controller
-
- def initialize(config, controller)
- @config = config
- @controller = controller
- end
-
- # Add the extension +ext+ if not present. Return full or scheme-relative URLs otherwise untouched.
- # Prefix with <tt>/dir/</tt> if lacking a leading +/+. Account for relative URL
- # roots. Rewrite the asset path for cache-busting asset ids. Include
- # asset host, if configured, with the correct request protocol.
- def compute_public_path(source, dir, ext = nil, include_host = true)
- source = source.to_s
- return source if is_uri?(source)
-
- source = rewrite_extension(source, dir, ext) if ext
- source = rewrite_asset_path(source, dir)
-
- if controller && include_host
- has_request = controller.respond_to?(:request)
- source = rewrite_host_and_protocol(source, has_request)
- end
-
- source
- end
-
- def is_uri?(path)
- path =~ %r{^[-a-z]+://|^cid:|^//}
- end
-
- private
-
- def rewrite_extension(source, dir, ext)
- raise NotImplementedError
- end
-
- def rewrite_asset_path(source, path = nil)
- raise NotImplementedError
- end
-
- def rewrite_relative_url_root(source, relative_url_root)
- relative_url_root && !source.starts_with?("#{relative_url_root}/") ? "#{relative_url_root}#{source}" : source
- end
-
- def rewrite_host_and_protocol(source, has_request)
- source = rewrite_relative_url_root(source, controller.config.relative_url_root) if has_request
- host = compute_asset_host(source)
- if has_request && host && !is_uri?(host)
- host = "#{controller.request.protocol}#{host}"
- end
- "#{host}#{source}"
- end
-
- # Pick an asset host for this source. Returns +nil+ if no host is set,
- # the host if no wildcard is set, the host interpolated with the
- # numbers 0-3 if it contains <tt>%d</tt> (the number is the source hash mod 4),
- # or the value returned from invoking call on an object responding to call
- # (proc or otherwise).
- def compute_asset_host(source)
- if host = config.asset_host
- if host.respond_to?(:call)
- case host.is_a?(Proc) ? host.arity : host.method(:call).arity
- when 2
- request = controller.respond_to?(:request) && controller.request
- host.call(source, request)
- else
- host.call(source)
- end
- else
- (host =~ /%d/) ? host % (source.hash % 4) : host
- end
- end
- end
- end
-
+ AssetPaths = ::ActionView::AssetPaths
end
-end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb
index 2d49823412..12a304b395 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb
@@ -1,11 +1,10 @@
require 'active_support/core_ext/file'
-require 'action_view/helpers/asset_paths'
module ActionView
module Helpers
module AssetTagHelper
- class AssetPaths < ActionView::Helpers::AssetPaths #:nodoc:
+ class AssetPaths < ::ActionView::AssetPaths #:nodoc:
# You can enable or disable the asset tag ids cache.
# With the cache enabled, the asset tag helper methods will make fewer
# expensive file system calls (the default implementation checks the file
diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb
index b57617b3d1..f81ce3e31c 100644
--- a/actionpack/lib/action_view/helpers/cache_helper.rb
+++ b/actionpack/lib/action_view/helpers/cache_helper.rb
@@ -51,12 +51,10 @@ module ActionView
# This dance is needed because Builder can't use capture
pos = output_buffer.length
yield
- if output_buffer.is_a?(ActionView::OutputBuffer)
- safe_output_buffer = output_buffer.to_str
- fragment = safe_output_buffer.slice!(pos..-1)
- self.output_buffer = ActionView::OutputBuffer.new(safe_output_buffer)
- else
- fragment = output_buffer.slice!(pos..-1)
+ output_safe = output_buffer.html_safe?
+ fragment = output_buffer.slice!(pos..-1)
+ if output_safe
+ self.output_buffer = output_buffer.html_safe
end
controller.write_fragment(name, fragment, options)
end
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 4be95d8f7e..ae71ade588 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -256,6 +256,7 @@ module ActionView
# # => "<p><span>I'm allowed!</span> It's true.</p>"
def simple_format(text, html_options={}, options={})
text = '' if text.nil?
+ text = text.dup if text.frozen?
start_tag = tag('p', html_options, true)
text = sanitize(text) unless options[:sanitize] == false
text = text.to_str
diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb
index 0b6bd8ca40..b977fabdaa 100644
--- a/actionpack/lib/sprockets/helpers/rails_helper.rb
+++ b/actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -1,4 +1,3 @@
-require "action_view/helpers/asset_paths"
require "action_view/helpers/asset_tag_helper"
module Sprockets
@@ -71,7 +70,7 @@ module Sprockets
body ? "#{path}?body=1" : path
end
- class AssetPaths < ActionView::Helpers::AssetPaths #:nodoc:
+ class AssetPaths < ::ActionView::AssetPaths #:nodoc:
def compute_public_path(source, dir, ext=nil, include_host=true)
super(source, Rails.application.config.assets.prefix, ext, include_host)
end
diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb
index 38eb00ce01..ab5101f6fc 100644
--- a/actionpack/lib/sprockets/railtie.rb
+++ b/actionpack/lib/sprockets/railtie.rb
@@ -63,6 +63,10 @@ module Sprockets
env.logger = Rails.logger
+ if env.respond_to?(:cache)
+ env.cache = Rails.cache
+ end
+
if assets.compress
# temporarily hardcode default JS compressor to uglify. Soon, it will work
# the same as SCSS, where a default plugin sets the default.
diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb
index 5a43b5f864..f7c3986bb1 100644
--- a/actionpack/test/template/text_helper_test.rb
+++ b/actionpack/test/template/text_helper_test.rb
@@ -36,8 +36,8 @@ class TextHelperTest < ActionView::TestCase
text = "A\r\n \nB\n\n\r\n\t\nC\nD".freeze
assert_equal "<p>A\n<br /> \n<br />B</p>\n\n<p>\t\n<br />C\n<br />D</p>", simple_format(text)
- assert_equal %q(<p class="test">This is a classy test</p>), simple_format("This is a classy test", :class => 'test')
- assert_equal %Q(<p class="test">para 1</p>\n\n<p class="test">para 2</p>), simple_format("para 1\n\npara 2", :class => 'test')
+ assert_equal %q(<p class="test">This is a classy test</p>), simple_format("This is a classy test", :class => 'test')
+ assert_equal %Q(<p class="test">para 1</p>\n\n<p class="test">para 2</p>), simple_format("para 1\n\npara 2", :class => 'test')
end
def test_simple_format_should_sanitize_input_when_sanitize_option_is_not_false
@@ -48,6 +48,13 @@ class TextHelperTest < ActionView::TestCase
assert_equal "<p><b> test with unsafe string </b><script>code!</script></p>", simple_format("<b> test with unsafe string </b><script>code!</script>", {}, :sanitize => false)
end
+ def test_simple_format_should_not_change_the_frozen_text_passed
+ text = "<b>Ok</b><script>code!</script>"
+ text_clone = text.dup
+ simple_format(text.freeze)
+ assert_equal text_clone, text
+ end
+
def test_truncate_should_not_be_html_safe
assert !truncate("Hello World!", :length => 12).html_safe?
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index dd1d2d4fba..090f6bc6fe 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -426,6 +426,14 @@ module ActiveRecord
@testing = testing
end
+ def method_missing(method_sym, *arguments, &block)
+ @body.send(method_sym, *arguments, &block)
+ end
+
+ def respond_to?(method_sym, include_private = false)
+ super || @body.respond_to?(method_sym)
+ end
+
def each(&block)
body.each(&block)
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index a9e3c83eb0..82f564e41d 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -328,7 +328,7 @@ module ActiveRecord
end
# Checks to see if a column exists. See SchemaStatements#column_exists?
- def column_exists?(column_name, type = nil, options = nil)
+ def column_exists?(column_name, type = nil, options = {})
@base.column_exists?(@table_name, column_name, type, options)
end
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index 3eddb69e73..a7856539b7 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -1,3 +1,5 @@
+require 'set'
+
module ActiveRecord
# :stopdoc:
module ConnectionAdapters
diff --git a/activerecord/lib/active_record/query_cache.rb b/activerecord/lib/active_record/query_cache.rb
index 4e61671473..e485901440 100644
--- a/activerecord/lib/active_record/query_cache.rb
+++ b/activerecord/lib/active_record/query_cache.rb
@@ -33,6 +33,14 @@ module ActiveRecord
@target = target
end
+ def method_missing(method_sym, *arguments, &block)
+ @target.send(method_sym, *arguments, &block)
+ end
+
+ def respond_to?(method_sym, include_private = false)
+ super || @target.respond_to?(method_sym)
+ end
+
def each(&block)
@target.each(&block)
end
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index 6ef24a4eaf..83909b0766 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -369,7 +369,7 @@ db_namespace = namespace :db do
ENV['PGPASSWORD'] = abcs[Rails.env]['password'].to_s if abcs[Rails.env]['password']
search_path = abcs[Rails.env]['schema_search_path']
unless search_path.blank?
- search_path = search_path.split(",").map{|search_path| "--schema=#{search_path.strip}" }.join(" ")
+ search_path = search_path.split(",").map{|search_path_part| "--schema=#{search_path_part.strip}" }.join(" ")
end
`pg_dump -i -U "#{abcs[Rails.env]['username']}" -s -x -O -f db/#{Rails.env}_structure.sql #{search_path} #{abcs[Rails.env]['database']}`
raise 'Error dumping database' if $?.exitstatus == 1
diff --git a/activerecord/test/cases/connection_management_test.rb b/activerecord/test/cases/connection_management_test.rb
index 85871aebdf..a1d1177289 100644
--- a/activerecord/test/cases/connection_management_test.rb
+++ b/activerecord/test/cases/connection_management_test.rb
@@ -77,6 +77,13 @@ module ActiveRecord
@management.call(@env)
assert ActiveRecord::Base.connection_handler.active_connections?
end
+
+ test "proxy is polite to it's body and responds to it" do
+ body = Class.new(String) { def to_path; "/path"; end }.new
+ proxy = ConnectionManagement::Proxy.new(body)
+ assert proxy.respond_to?(:to_path)
+ assert_equal proxy.to_path, "/path"
+ end
end
end
end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index bf7565a0d0..93a1249e43 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -1071,6 +1071,18 @@ if ActiveRecord::Base.connection.supports_migrations?
Person.connection.drop_table :testings rescue nil
end
+ def test_column_exists_on_table_with_no_options_parameter_supplied
+ Person.connection.create_table :testings do |t|
+ t.string :foo
+ end
+ Person.connection.change_table :testings do |t|
+ assert t.column_exists?(:foo)
+ assert !(t.column_exists?(:bar))
+ end
+ ensure
+ Person.connection.drop_table :testings rescue nil
+ end
+
def test_add_table
assert !Reminder.table_exists?
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index a61180cfaf..ad17f6f83a 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -203,3 +203,14 @@ class QueryCacheExpiryTest < ActiveRecord::TestCase
end
end
end
+
+class QueryCacheBodyProxyTest < ActiveRecord::TestCase
+
+ test "is polite to it's body and responds to it" do
+ body = Class.new(String) { def to_path; "/path"; end }.new
+ proxy = ActiveRecord::QueryCache::BodyProxy.new(nil, body)
+ assert proxy.respond_to?(:to_path)
+ assert_equal proxy.to_path, "/path"
+ end
+
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
index 7baba75ad3..ca9b2c1b60 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/module/remove_method'
+require 'active_support/core_ext/array/extract_options'
class Class
# Declare a class-level attribute whose value is inheritable by subclasses.
@@ -56,11 +57,18 @@ class Class
# object.setting # => false
# Base.setting # => true
#
+ # To opt out of the instance reader method, pass :instance_reader => false.
+ #
+ # object.setting # => NoMethodError
+ # object.setting? # => NoMethodError
+ #
# To opt out of the instance writer method, pass :instance_writer => false.
#
# object.setting = false # => NoMethodError
def class_attribute(*attrs)
- instance_writer = !attrs.last.is_a?(Hash) || attrs.pop[:instance_writer]
+ options = attrs.extract_options!
+ instance_reader = options.fetch(:instance_reader, true)
+ instance_writer = options.fetch(:instance_writer, true)
attrs.each do |name|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -84,13 +92,15 @@ class Class
val
end
- remove_possible_method :#{name}
- def #{name}
- defined?(@#{name}) ? @#{name} : self.class.#{name}
- end
+ if instance_reader
+ remove_possible_method :#{name}
+ def #{name}
+ defined?(@#{name}) ? @#{name} : self.class.#{name}
+ end
- def #{name}?
- !!#{name}
+ def #{name}?
+ !!#{name}
+ end
end
RUBY
diff --git a/activesupport/test/core_ext/class/attribute_test.rb b/activesupport/test/core_ext/class/attribute_test.rb
index d58b60482b..e290a6e012 100644
--- a/activesupport/test/core_ext/class/attribute_test.rb
+++ b/activesupport/test/core_ext/class/attribute_test.rb
@@ -60,6 +60,12 @@ class ClassAttributeTest < ActiveSupport::TestCase
assert_raise(NoMethodError) { object.setting = 'boom' }
end
+ test 'disabling instance reader' do
+ object = Class.new { class_attribute :setting, :instance_reader => false }.new
+ assert_raise(NoMethodError) { object.setting }
+ assert_raise(NoMethodError) { object.setting? }
+ end
+
test 'works well with singleton classes' do
object = @klass.new
object.singleton_class.setting = 'foo'
diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb
index cca0891835..df92934457 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -87,6 +87,29 @@ module Rails
RAILS_CACHE
end
+ # Returns all rails groups for loading based on:
+ #
+ # * The Rails environment;
+ # * The environment variable RAILS_GROUPS;
+ # * The optional hash given as argument with group dependencies;
+ #
+ # == Examples
+ #
+ # groups :assets => [:development, :test]
+ #
+ # # Returns
+ # # => [:default, :development, :assets] for Rails.env == "development"
+ # # => [:default, :production] for Rails.env == "production"
+ #
+ def groups(hash={})
+ env = Rails.env
+ groups = [:default, env]
+ groups.concat ENV["RAILS_GROUPS"].to_s.split(",")
+ groups.concat hash.map { |k,v| k if v.map(&:to_s).include?(env) }
+ groups.compact!
+ groups
+ end
+
def version
VERSION::STRING
end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 355b05ce0b..ea9f023511 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -299,9 +299,6 @@ module Rails
return
rescue LoadError => e
raise unless e.message =~ /#{Regexp.escape(path)}$/
- rescue NameError => e
- raise unless e.message =~ /Rails::Generator([\s(::)]|$)/
- warn "[WARNING] Could not load generator #{path.inspect} because it's a Rails 2.x generator, which is not supported anymore. Error: #{e.message}.\n#{e.backtrace.join("\n")}"
rescue Exception => e
warn "[WARNING] Could not load generator #{path.inspect}. Error: #{e.message}.\n#{e.backtrace.join("\n")}"
end
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index d31a3262e3..433a56dc57 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -114,11 +114,11 @@ module Rails
# git :add => "this.file that.rb"
# git :add => "onefile.rb", :rm => "badfile.cxx"
#
- def git(command={})
- if command.is_a?(Symbol)
- run "git #{command}"
+ def git(commands={})
+ if commands.is_a?(Symbol)
+ run "git #{commands}"
else
- command.each do |command, options|
+ commands.each do |command, options|
run "git #{command} #{options}"
end
end
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 1196e2b7eb..bbf0447985 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -164,7 +164,7 @@ module Rails
end
end
- def gem_for_ruby_debugger
+ def ruby_debugger_gemfile_entry
if RUBY_VERSION < "1.9"
"gem 'ruby-debug'"
else
@@ -172,7 +172,7 @@ module Rails
end
end
- def gem_for_turn
+ def turn_gemfile_entry
unless RUBY_VERSION < "1.9.2" || options[:skip_test_unit]
<<-GEMFILE.strip_heredoc
group :test do
@@ -183,7 +183,7 @@ module Rails
end
end
- def gem_for_javascript
+ def javascript_gemfile_entry
"gem '#{options[:javascript]}-rails'" unless options[:skip_javascript]
end
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index 1f6a7a2f59..b9dc31457a 100644
--- a/railties/lib/rails/generators/base.rb
+++ b/railties/lib/rails/generators/base.rb
@@ -259,9 +259,9 @@ module Rails
extra << false unless Object.method(:const_defined?).arity == 1
# Extract the last Module in the nesting
- last = nesting.inject(Object) do |last, nest|
- break unless last.const_defined?(nest, *extra)
- last.const_get(nest)
+ last = nesting.inject(Object) do |last_module, nest|
+ break unless last_module.const_defined?(nest, *extra)
+ last_module.const_get(nest)
end
if last && last.const_defined?(last_name.camelize, *extra)
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index ebe38bf8e6..cd674ddbdd 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -5,13 +5,17 @@ source 'http://rubygems.org'
<%= database_gemfile_entry -%>
<%= "gem 'jruby-openssl'\n" if defined?(JRUBY_VERSION) -%>
-# Asset template engines
<%= "gem 'json'\n" if RUBY_VERSION < "1.9.2" -%>
-gem 'sass-rails'
-gem 'coffee-script'
-gem 'uglifier'
-<%= gem_for_javascript %>
+# Gems used only for assets and not required
+# in production environments by default.
+group :assets do
+ gem 'sass-rails'
+ gem 'coffee-script'
+ gem 'uglifier'
+end
+
+<%= javascript_gemfile_entry %>
# Use unicorn as the web server
# gem 'unicorn'
@@ -20,6 +24,6 @@ gem 'uglifier'
# gem 'capistrano'
# To use debugger
-# <%= gem_for_ruby_debugger %>
+# <%= ruby_debugger_gemfile_entry %>
-<%= gem_for_turn -%>
+<%= turn_gemfile_entry -%>
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 37c2fb1263..7f623a7af9 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -11,9 +11,10 @@ require "active_resource/railtie"
<%= comment_if :skip_test_unit %> require "rails/test_unit/railtie"
<% end -%>
-# If you have a Gemfile, require the gems listed there, including any gems
-# you've limited to :test, :development, or :production.
-Bundler.require(:default, Rails.env) if defined?(Bundler)
+# If you have a Gemfile, require the default gems, the ones in the
+# current environment and also include :assets gems if in development
+# or test environments.
+Bundler.require *Rails.groups(:assets => %w(development test)) if defined?(Bundler)
module <%= app_const_base %>
class Application < Rails::Application
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
index c28e568711..7e6eb18341 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
@@ -7,9 +7,8 @@ source "http://rubygems.org"
<% end -%>
<% if mountable? -%>
-<%= gem_for_javascript -%>
+<%= javascript_gemfile_entry -%>
<% end -%>
-if RUBY_VERSION < '1.9'
- gem "ruby-debug", ">= 0.10.3"
-end
+# To use debugger
+# <%= ruby_debugger_gemfile_entry %> \ No newline at end of file
diff --git a/railties/lib/rails/tasks/assets.rake b/railties/lib/rails/tasks/assets.rake
index 4678ea460e..0236350576 100644
--- a/railties/lib/rails/tasks/assets.rake
+++ b/railties/lib/rails/tasks/assets.rake
@@ -1,21 +1,26 @@
namespace :assets do
desc "Compile all the assets named in config.assets.precompile"
- task :precompile => :environment do
- # Give assets access to asset_path
- Sprockets::Helpers::RailsHelper
+ task :precompile do
+ if ENV["RAILS_GROUPS"].to_s.empty?
+ ENV["RAILS_GROUPS"] = "assets"
+ Kernel.exec $0, *ARGV
+ else
+ Rake::Task["environment"].invoke
+ Sprockets::Helpers::RailsHelper
- assets = Rails.application.config.assets.precompile
- Rails.application.assets.precompile(*assets)
+ assets = Rails.application.config.assets.precompile
+ Rails.application.assets.precompile(*assets)
+ end
end
desc "Remove compiled assets"
task :clean => :environment do
assets = Rails.application.config.assets
public_asset_path = Rails.public_path + assets.prefix
- file_list = FileList.new("#{public_asset_path}/*.js", "#{public_asset_path}/*.css")
+ file_list = FileList.new("#{public_asset_path}/**/*")
file_list.each do |file|
- rm file
- rm "#{file}.gz", :force => true
+ rm_rf file
+ rm_rf "#{file}.gz"
end
end
end
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index 2b593005a2..b76dae8e18 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -1,8 +1,9 @@
require 'isolation/abstract_unit'
+require 'active_support/core_ext/kernel/reporting'
require 'rack/test'
module ApplicationTests
- class RoutingTest < Test::Unit::TestCase
+ class AssetsTest < Test::Unit::TestCase
include ActiveSupport::Testing::Isolation
include Rack::Test::Methods
@@ -34,6 +35,31 @@ module ApplicationTests
assert_match "alert()", last_response.body
end
+ test "assets are compiled properly" do
+ app_file "app/assets/javascripts/application.js", "alert();"
+
+ capture(:stdout) do
+ Dir.chdir(app_path){ `bundle exec rake assets:precompile` }
+ end
+
+ file = Dir["#{app_path}/public/assets/application-*.js"][0]
+ assert_not_nil file, "Expected application.js asset to be generated, but none found"
+ assert_equal "alert();\n", File.read(file)
+ end
+
+ test "assets are cleaned up properly" do
+ app_file "public/assets/application.js", "alert();"
+ app_file "public/assets/application.css", "a { color: green; }"
+ app_file "public/assets/subdir/broken.png", "not really an image file"
+
+ capture(:stdout) do
+ Dir.chdir(app_path){ `bundle exec rake assets:clean` }
+ end
+
+ files = Dir["#{app_path}/public/assets/**/*"]
+ assert_equal 0, files.length, "Expected no assets, but found #{files.join(', ')}"
+ end
+
test "does not stream session cookies back" do
app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 477dada820..2547863d12 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -39,6 +39,21 @@ module ApplicationTests
FileUtils.rm_rf(new_app) if File.directory?(new_app)
end
+ test "Rails.groups returns available groups" do
+ require "rails"
+
+ Rails.env = "development"
+ assert_equal [:default, "development"], Rails.groups
+ assert_equal [:default, "development", :assets], Rails.groups(:assets => [:development])
+ assert_equal [:default, "development", :assets], Rails.groups(:assets => %w(development))
+
+ Rails.env = "test"
+ assert_equal [:default, "test"], Rails.groups(:assets => [:development])
+
+ ENV["RAILS_GROUPS"] = "javascripts,stylesheets"
+ assert_equal [:default, "test", "javascripts", "stylesheets"], Rails.groups
+ end
+
test "Rails.application is nil until app is initialized" do
require 'rails'
assert_nil Rails.application
diff --git a/railties/test/fixtures/lib/generators/wrong_generator.rb b/railties/test/fixtures/lib/generators/wrong_generator.rb
deleted file mode 100644
index 6aa7cb052e..0000000000
--- a/railties/test/fixtures/lib/generators/wrong_generator.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# Old generator version
-class WrongGenerator < Rails::Generator::NamedBase
-end
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index 301ae80bcf..56329f3183 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -88,12 +88,6 @@ class GeneratorsTest < Rails::Generators::TestCase
assert Rails::Generators.find_by_namespace(:model)
end
- def test_find_by_namespace_show_warning_if_generator_cant_be_loaded
- output = capture(:stderr) { Rails::Generators.find_by_namespace(:wrong) }
- assert_match(/\[WARNING\] Could not load generator/, output)
- assert_match(/Rails 2\.x generator/, output)
- end
-
def test_invoke_with_nested_namespaces
model_generator = mock('ModelGenerator') do
expects(:start).with(["Account"], {})
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 0a203fd4d0..685d1b154b 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -238,6 +238,10 @@ module TestHelpers
end
end
+ def remove_file(path)
+ FileUtils.rm_rf "#{app_path}/#{path}"
+ end
+
def controller(name, contents)
app_file("app/controllers/#{name}_controller.rb", contents)
end