Skip to content
Browse files

Merge branch 'master' of git@github.com:rails/rails

  • Loading branch information...
2 parents 54f4851 + 1026d77 commit e7312105c73c20b286ebf17b16808001803e2c61 @jeremy jeremy committed Jul 1, 2009
Showing with 3,270 additions and 1,254 deletions.
  1. +1 −1 actionmailer/Rakefile
  2. +3 −3 actionmailer/lib/action_mailer/version.rb
  3. +0 −3 actionmailer/test/abstract_unit.rb
  4. +1 −1 actionpack/Rakefile
  5. +4 −0 actionpack/lib/action_controller/base/filter_parameter_logging.rb
  6. +1 −1 actionpack/lib/action_controller/base/http.rb
  7. +1 −1 actionpack/lib/action_controller/base/streaming.rb
  8. +1 −2 actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
  9. +1 −1 actionpack/lib/action_controller/routing/route_set.rb
  10. 0 actionpack/lib/action_controller/testing/{performance.rb → performance_test.rb}
  11. +1 −1 actionpack/lib/action_dispatch/http/mime_type.rb
  12. +3 −3 actionpack/lib/action_pack/version.rb
  13. +4 −5 actionpack/lib/action_view/base.rb
  14. +28 −4 actionpack/lib/action_view/helpers/asset_tag_helper.rb
  15. +22 −0 actionpack/lib/action_view/helpers/capture_helper.rb
  16. +5 −0 actionpack/lib/action_view/helpers/form_tag_helper.rb
  17. +0 −26 actionpack/lib/action_view/render/partials.rb
  18. +2 −4 actionpack/lib/action_view/render/rendering.rb
  19. +1 −2 actionpack/lib/action_view/template/handlers/builder.rb
  20. +2 −1 actionpack/lib/action_view/template/handlers/erb.rb
  21. +6 −3 actionpack/test/activerecord/polymorphic_routes_test.rb
  22. +2 −1 actionpack/test/controller/filter_params_test.rb
  23. +0 −7 actionpack/test/controller/render_test.rb
  24. +11 −0 actionpack/test/controller/routing_test.rb
  25. +1 −1 actionpack/test/controller/send_file_test.rb
  26. +1 −0 actionpack/test/fixtures/public/.gitignore
  27. +1 −0 actionpack/test/fixtures/public/elsewhere/cools.js
  28. +1 −0 actionpack/test/fixtures/public/elsewhere/file.css
  29. +1 −0 actionpack/test/fixtures/public/javascripts/common.javascript
  30. +1 −0 actionpack/test/fixtures/public/stylesheets/random.styles
  31. +3 −3 actionpack/test/lib/fixture_template.rb
  32. +0 −3 actionpack/test/old_base/abstract_unit.rb
  33. +88 −30 actionpack/test/template/asset_tag_helper_test.rb
  34. +15 −0 actionpack/test/template/capture_helper_test.rb
  35. +12 −0 actionpack/test/template/form_tag_helper_test.rb
  36. +0 −2 activemodel/test/cases/helper.rb
  37. +1 −1 activerecord/Rakefile
  38. +13 −1 activerecord/lib/active_record/associations/association_collection.rb
  39. +1 −9 activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
  40. +1 −9 activerecord/lib/active_record/associations/has_many_association.rb
  41. +1 −9 activerecord/lib/active_record/associations/has_many_through_association.rb
  42. +7 −0 activerecord/lib/active_record/associations/through_association_scope.rb
  43. +29 −3 activerecord/lib/active_record/base.rb
  44. +1 −1 activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
  45. +6 −1 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
  46. +13 −0 activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
  47. +11 −0 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
  48. +11 −1 activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
  49. +3 −3 activerecord/lib/active_record/version.rb
  50. +15 −0 activerecord/test/cases/adapter_test.rb
  51. +7 −0 activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
  52. +5 −0 activerecord/test/cases/associations/has_many_associations_test.rb
  53. +6 −0 activerecord/test/cases/associations/has_many_through_associations_test.rb
  54. +7 −3 activerecord/test/cases/base_test.rb
  55. +2 −2 activerecord/test/cases/calculations_test.rb
  56. +2 −2 activerecord/test/cases/finder_test.rb
  57. +0 −2 activerecord/test/cases/helper.rb
  58. +2 −2 activerecord/test/cases/inheritance_test.rb
  59. +33 −0 activerecord/test/cases/migration_test.rb
  60. +9 −3 activerecord/test/cases/reflection_test.rb
  61. +8 −0 activerecord/test/fixtures/companies.yml
  62. +4 −0 activerecord/test/models/company.rb
  63. +2 −0 activerecord/test/models/post.rb
  64. +6 −0 activerecord/test/models/project.rb
  65. +1 −0 activerecord/test/schema/schema.rb
  66. +1 −1 activeresource/Rakefile
  67. +3 −3 activeresource/lib/active_resource/version.rb
  68. +1 −3 activeresource/test/abstract_unit.rb
  69. +16 −3 activesupport/lib/active_support/cache.rb
  70. +13 −1 activesupport/lib/active_support/cache/file_store.rb
  71. +0 −4 activesupport/lib/active_support/cache/mem_cache_store.rb
  72. +1 −1 activesupport/lib/active_support/cache/memory_store.rb
  73. +1 −1 activesupport/lib/active_support/inflector.rb
  74. +9 −8 activesupport/lib/active_support/test_case.rb
  75. +0 −6 activesupport/lib/active_support/testing/declarative.rb
  76. +98 −0 activesupport/lib/active_support/testing/isolation.rb
  77. +0 −2 activesupport/lib/active_support/testing/setup_and_teardown.rb
  78. +0 −1 activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
  79. +0 −1 activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
  80. +0 −1 activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
  81. +3 −3 activesupport/lib/active_support/version.rb
  82. +2 −3 activesupport/test/abstract_unit.rb
  83. +22 −0 activesupport/test/caching_test.rb
  84. +6 −0 activesupport/test/inflector_test.rb
  85. +7 −0 activesupport/test/inflector_test_cases.rb
  86. +141 −0 activesupport/test/isolation_test.rb
  87. +5 −5 railties/Rakefile
  88. +424 −991 railties/lib/initializer.rb
  89. +1,137 −0 railties/lib/initializer_old.rb
  90. +1 −1 railties/lib/performance_test_help.rb
  91. +267 −0 railties/lib/rails/configuration.rb
  92. +97 −0 railties/lib/rails/core.rb
  93. +124 −0 railties/lib/rails/paths.rb
  94. +2 −2 railties/lib/rails/plugin/loader.rb
  95. +3 −3 railties/lib/rails/version.rb
  96. +1 −1 railties/lib/railties_path.rb
  97. +1 −0 railties/lib/test_help.rb
  98. +3 −3 railties/test/abstract_unit.rb
  99. +5 −3 railties/test/generator_lookup_test.rb
  100. +103 −0 railties/test/initializer/path_test.rb
  101. 0 railties/test/initializer/root/app/controllers/.keep
  102. 0 railties/test/initializer/root/app/helpers/.keep
  103. 0 railties/test/initializer/root/app/metal/.keep
  104. 0 railties/test/initializer/root/app/models/.keep
  105. 0 railties/test/initializer/root/app/views/.keep
  106. +4 −0 railties/test/initializer/root/config/database.yml
  107. 0 railties/test/initializer/root/config/environments/.keep
  108. 0 railties/test/initializer/root/config/locales/.keep
  109. 0 railties/test/initializer/root/config/routes.rb
  110. 0 railties/test/initializer/root/lib/.keep
  111. 0 railties/test/initializer/root/tmp/.keep
  112. 0 railties/test/initializer/root/tmp/cache/.keep
  113. 0 railties/test/initializer/root/vendor/.keep
  114. +38 −39 railties/test/initializer_test.rb
  115. +165 −0 railties/test/new_initializer_test.rb
  116. +126 −0 railties/test/paths_test.rb
  117. +2 −1 railties/test/plugin_loader_test.rb
  118. +2 −1 railties/test/plugin_locator_test.rb
  119. +2 −1 railties/test/plugin_test.rb
  120. +3 −0 railties/test/rails_generator_test.rb
View
2 actionmailer/Rakefile
@@ -60,7 +60,7 @@ spec = Gem::Specification.new do |s|
s.rubyforge_project = "actionmailer"
s.homepage = "http://www.rubyonrails.org"
- s.add_dependency('actionpack', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('actionpack', '= 3.0.pre' + PKG_BUILD)
s.has_rdoc = true
s.requirements << 'none'
View
6 actionmailer/lib/action_mailer/version.rb
@@ -1,8 +1,8 @@
module ActionMailer
module VERSION #:nodoc:
- MAJOR = 2
- MINOR = 3
- TINY = 2
+ MAJOR = 3
+ MINOR = 0
+ TINY = "pre"
STRING = [MAJOR, MINOR, TINY].join('.')
end
View
3 actionmailer/test/abstract_unit.rb
@@ -1,9 +1,6 @@
require 'rubygems'
require 'test/unit'
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
-
$:.unshift "#{File.dirname(__FILE__)}/../lib"
$:.unshift "#{File.dirname(__FILE__)}/../../activesupport/lib"
$:.unshift "#{File.dirname(__FILE__)}/../../actionpack/lib"
View
2 actionpack/Rakefile
@@ -115,7 +115,7 @@ spec = Gem::Specification.new do |s|
s.has_rdoc = true
s.requirements << 'none'
- s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 3.0.pre' + PKG_BUILD)
s.require_path = 'lib'
s.autorequire = 'action_controller'
View
4 actionpack/lib/action_controller/base/filter_parameter_logging.rb
@@ -43,6 +43,10 @@ def filter_parameter_logging(*filter_words, &block)
filtered_parameters[key] = '[FILTERED]'
elsif value.is_a?(Hash)
filtered_parameters[key] = filter_parameters(value)
+ elsif value.is_a?(Array)
+ filtered_parameters[key] = value.collect do |item|
+ filter_parameters(item)
+ end
elsif block_given?
key = key.dup
value = value.dup if value
View
2 actionpack/lib/action_controller/base/http.rb
@@ -36,7 +36,7 @@ def controller_name
# ==== Returns
# String
def self.controller_path
- @controller_path ||= self.name.sub(/Controller$/, '').underscore
+ @controller_path ||= name && name.sub(/Controller$/, '').underscore
end
# Delegates to the class' #controller_path
View
2 actionpack/lib/action_controller/base/streaming.rb
@@ -168,7 +168,7 @@ def send_file_headers!(options)
end
headers.merge!(
- 'Content-Length' => options[:length],
+ 'Content-Length' => options[:length].to_s,
'Content-Disposition' => disposition,
'Content-Transfer-Encoding' => 'binary'
)
View
3 actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
@@ -112,8 +112,7 @@ def polymorphic_url(record_or_hash_or_array, options = {})
# Returns the path component of a URL for the given record. It uses
# <tt>polymorphic_url</tt> with <tt>:routing_type => :path</tt>.
def polymorphic_path(record_or_hash_or_array, options = {})
- options[:routing_type] = :path
- polymorphic_url(record_or_hash_or_array, options)
+ polymorphic_url(record_or_hash_or_array, options.merge(:routing_type => :path))
end
%w(edit new).each do |action|
View
2 actionpack/lib/action_controller/routing/route_set.rb
@@ -436,7 +436,7 @@ def call(env)
def recognize(request)
params = recognize_path(request.path, extract_request_environment(request))
request.path_parameters = params.with_indifferent_access
- "#{params[:controller].camelize}Controller".constantize
+ "#{params[:controller].to_s.camelize}Controller".constantize
end
def recognize_path(path, environment={})
View
0 .../action_controller/testing/performance.rb → ...on_controller/testing/performance_test.rb
File renamed without changes.
View
2 actionpack/lib/action_dispatch/http/mime_type.rb
@@ -10,7 +10,7 @@ def symbols
%w(<< concat shift unshift push pop []= clear compact! collect!
delete delete_at delete_if flatten! map! insert reject! reverse!
replace slice! sort! uniq!).each do |method|
- define_method(method) { @symbols = nil; super }
+ define_method(method) {|*args| @symbols = nil; super(*args) }
end
end
View
6 actionpack/lib/action_pack/version.rb
@@ -1,8 +1,8 @@
module ActionPack #:nodoc:
module VERSION #:nodoc:
- MAJOR = 2
- MINOR = 3
- TINY = 2
+ MAJOR = 3
+ MINOR = 0
+ TINY = "pre"
STRING = [MAJOR, MINOR, TINY].join('.')
end
View
9 actionpack/lib/action_view/base.rb
@@ -230,7 +230,7 @@ def include(*args)
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc:
@formats = formats || [:html]
- @assigns = assigns_for_first_render
+ @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) }
@controller = controller
@helpers = ProxyModule.new(self)
@_content_for = Hash.new {|h,k| h[k] = "" }
@@ -245,6 +245,7 @@ def view_paths=(paths)
end
def with_template(current_template)
+ _evaluate_assigns_and_ivars
last_template, self.template = template, current_template
last_formats, self.formats = formats, [current_template.mime_type.to_sym] + Mime::SET.symbols
yield
@@ -260,10 +261,7 @@ def punctuate_body!(part)
# Evaluates the local assigns and controller ivars, pushes them to the view.
def _evaluate_assigns_and_ivars #:nodoc:
- return if @assigns_added
- @assigns.each { |key, value| instance_variable_set("@#{key}", value) }
- _copy_ivars_from_controller
- @assigns_added = true
+ @assigns_added ||= _copy_ivars_from_controller
end
private
@@ -274,6 +272,7 @@ def _copy_ivars_from_controller #:nodoc:
variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) }
end
+ true
end
end
View
32 actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -1,6 +1,7 @@
require 'cgi'
require 'action_view/helpers/url_helper'
require 'action_view/helpers/tag_helper'
+require 'active_support/core_ext/file'
module ActionView
module Helpers #:nodoc:
@@ -285,7 +286,7 @@ def javascript_include_tag(*sources)
end
javascript_src_tag(joined_javascript_name, options)
else
- expand_javascript_sources(sources, recursive).collect { |source| javascript_src_tag(source, options) }.join("\n")
+ ensure_javascript_sources!(expand_javascript_sources(sources, recursive)).collect { |source| javascript_src_tag(source, options) }.join("\n")
end
end
@@ -434,7 +435,7 @@ def stylesheet_link_tag(*sources)
end
stylesheet_tag(joined_stylesheet_name, options)
else
- expand_stylesheet_sources(sources, recursive).collect { |source| stylesheet_tag(source, options) }.join("\n")
+ ensure_stylesheet_sources!(expand_stylesheet_sources(sources, recursive)).collect { |source| stylesheet_tag(source, options) }.join("\n")
end
end
@@ -664,13 +665,28 @@ def determine_source(source, collection)
end
end
+ def ensure_stylesheet_sources!(sources)
+ sources.each do |source|
+ asset_file_path!(path_to_stylesheet(source))
+ end
+ return sources
+ end
+
+ def ensure_javascript_sources!(sources)
+ sources.each do |source|
+ asset_file_path!(path_to_javascript(source))
+ end
+ return sources
+ end
+
def join_asset_file_contents(paths)
- paths.collect { |path| File.read(asset_file_path(path)) }.join("\n\n")
+ paths.collect { |path| File.read(asset_file_path!(path)) }.join("\n\n")
end
def write_asset_file_contents(joined_asset_path, asset_paths)
+
FileUtils.mkdir_p(File.dirname(joined_asset_path))
- File.open(joined_asset_path, "w+") { |cache| cache.write(join_asset_file_contents(asset_paths)) }
+ File.atomic_write(joined_asset_path) { |cache| cache.write(join_asset_file_contents(asset_paths)) }
# Set mtime to the latest of the combined files to allow for
# consistent ETag without a shared filesystem.
@@ -682,6 +698,14 @@ def asset_file_path(path)
File.join(ASSETS_DIR, path.split('?').first)
end
+ def asset_file_path!(path)
+ unless path =~ %r{^[-a-z]+://}
+ absolute_path = asset_file_path(path)
+ raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
+ return absolute_path
+ end
+ end
+
def collect_asset_files(*path)
dir = path.first
View
22 actionpack/lib/action_view/helpers/capture_helper.rb
@@ -117,6 +117,28 @@ def content_for(name, content = nil, &block)
@_content_for[name]
end
+ # content_for? simply checks whether any content has been captured yet using content_for
+ # Useful to render parts of your layout differently based on what is in your views.
+ #
+ # ==== Examples
+ #
+ # Perhaps you will use different css in you layout if no content_for :right_column
+ #
+ # <%# This is the layout %>
+ # <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ # <head>
+ # <title>My Website</title>
+ # <%= yield :script %>
+ # </head>
+ # <body class="<%= content_for?(:right_col) ? 'one-column' : 'two-column' %>">
+ # <%= yield %>
+ # <%= yield :right_col %>
+ # </body>
+ # </html>
+ def content_for?(name)
+ @_content_for[name].present?
+ end
+
# Use an alternate output buffer for the duration of the block.
# Defaults to a new empty string.
def with_output_buffer(buf = nil) #:nodoc:
View
5 actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -231,6 +231,8 @@ def password_field_tag(name = "password", value = nil, options = {})
# * <tt>:rows</tt> - Specify the number of rows in the textarea
# * <tt>:cols</tt> - Specify the number of columns in the textarea
# * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
+ # * <tt>:escape</tt> - By default, the contents of the text input are HTML escaped.
+ # If you need unescaped contents, set this to false.
# * Any other key creates standard HTML attributes for the tag.
#
# ==== Examples
@@ -258,6 +260,9 @@ def text_area_tag(name, content = nil, options = {})
options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
end
+ escape = options.key?("escape") ? options.delete("escape") : true
+ content = html_escape(content) if escape
+
content_tag :textarea, content, { "name" => name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
end
View
26 actionpack/lib/action_view/render/partials.rb
@@ -232,18 +232,6 @@ def _render_partial_with_block(layout, block, options)
ensure
@_proc_for_layout = nil
end
-
- def _deprecated_ivar_assign(template)
- if respond_to?(:controller)
- ivar = :"@#{template.variable_name}"
- object =
- if controller.instance_variable_defined?(ivar)
- ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
- controller.instance_variable_get(ivar),
- "#{ivar} will no longer be implicitly assigned to #{template.variable_name}")
- end
- end
- end
def _render_partial_with_layout(layout, options)
if layout
@@ -253,18 +241,6 @@ def _render_partial_with_layout(layout, options)
content = _render_partial(options)
return _render_content_with_layout(content, layout, options[:locals])
end
-
- def _deprecated_ivar_assign(template)
- if respond_to?(:controller)
- ivar = :"@#{template.variable_name}"
- object =
- if controller.instance_variable_defined?(ivar)
- ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
- controller.instance_variable_get(ivar),
- "#{ivar} will no longer be implicitly assigned to #{template.variable_name}")
- end
- end
- end
def _array_like_objects
array_like = [Array]
@@ -290,8 +266,6 @@ def _render_partial_object(template, options, object = nil)
end
def _set_locals(object, locals, template, options)
- object ||= _deprecated_ivar_assign(template)
-
locals[:object] = locals[template.variable_name] = object
locals[options[:as]] = object if options[:as]
end
View
6 actionpack/lib/action_view/render/rendering.rb
@@ -84,7 +84,7 @@ def _render_content_with_layout(content, layout, locals)
# ==== Example
#
# # The template
- # <% render :layout => "my_layout" do |name| %>Hello <%= customer.name %><% end %>
+ # <% render :layout => "my_layout" do |customer| %>Hello <%= customer.name %><% end %>
#
# # The layout
# <html><% yield Struct.new(:name).new("David") %></html>
@@ -99,14 +99,12 @@ def layout_proc(name)
def _render_template(template, local_assigns = {})
with_template(template) do
- _evaluate_assigns_and_ivars
-
template.render(self, local_assigns) do |*names|
capture(*names, &layout_proc(names.first))
end
end
rescue Exception => e
- if TemplateError === e
+ if e.is_a?(TemplateError)
e.sub_template_of(template)
raise e
else
View
3 actionpack/lib/action_view/template/handlers/builder.rb
@@ -1,5 +1,3 @@
-require 'builder'
-
module ActionView
module TemplateHandlers
class Builder < TemplateHandler
@@ -8,6 +6,7 @@ class Builder < TemplateHandler
self.default_format = Mime::XML
def compile(template)
+ require 'builder'
"xml = ::Builder::XmlMarkup.new(:indent => 2);" +
"self.output_buffer = xml.target!;" +
template.source +
View
3 actionpack/lib/action_view/template/handlers/erb.rb
@@ -1,4 +1,3 @@
-require 'erb'
require 'active_support/core_ext/class/attribute_accessors'
module ActionView
@@ -16,6 +15,8 @@ class ERB < TemplateHandler
self.default_format = Mime::HTML
def compile(template)
+ require 'erb'
+
magic = $1 if template.source =~ /\A(<%#.*coding:\s*(\S+)\s*-?%>)/
erb = "#{magic}<% __in_erb_template=true %>#{template.source}"
::ERB.new(erb, nil, erb_trim_mode, '@output_buffer').src
View
9 actionpack/test/activerecord/polymorphic_routes_test.rb
@@ -234,10 +234,13 @@ def test_polymorphic_path_does_not_modify_arguments
with_admin_test_routes do
@project.save
@task.save
+
+ options = {}
object_array = [:admin, @project, @task]
- assert_no_difference 'object_array.size' do
- polymorphic_url(object_array)
- end
+ original_args = [object_array.dup, options.dup]
+
+ assert_no_difference('object_array.size') { polymorphic_path(object_array, options) }
+ assert_equal original_args, [object_array, options]
end
end
View
3 actionpack/test/controller/filter_params_test.rb
@@ -40,7 +40,8 @@ def test_filter_parameters
[{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'],
[{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'],
[{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'],
- [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana']]
+ [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana'],
+ [{'baz'=>[{'foo'=>'baz'}]}, {'baz'=>[{'foo'=>'[FILTERED]'}]}, %w(foo)]]
test_hashes.each do |before_filter, after_filter, filter_words|
FilterParamController.filter_parameter_logging(*filter_words)
View
7 actionpack/test/controller/render_test.rb
@@ -1268,13 +1268,6 @@ def test_partial_hash_collection_with_locals
assert_equal "Hola: PratikHola: Amy", @response.body
end
- def test_partial_with_implicit_local_assignment
- assert_deprecated do
- get :partial_with_implicit_local_assignment
- assert_equal "Hello: Marcel", @response.body
- end
- end
-
def test_render_missing_partial_template
assert_raise(ActionView::MissingTemplate) do
get :missing_partial
View
11 actionpack/test/controller/routing_test.rb
@@ -1667,6 +1667,17 @@ def test_draw
assert_equal 1, set.routes.size
end
+ def test_draw_symbol_controller_name
+ assert_equal 0, set.routes.size
+ set.draw do |map|
+ map.connect '/users/index', :controller => :users, :action => :index
+ end
+ @request = ActionController::TestRequest.new
+ @request.request_uri = '/users/index'
+ assert_nothing_raised { set.recognize(@request) }
+ assert_equal 1, set.routes.size
+ end
+
def test_named_draw
assert_equal 0, set.routes.size
set.draw do |map|
View
2 actionpack/test/controller/send_file_test.rb
@@ -115,7 +115,7 @@ def test_send_file_headers!
@controller.send(:send_file_headers!, options)
h = @controller.headers
- assert_equal 1, h['Content-Length']
+ assert_equal '1', h['Content-Length']
assert_equal 'image/png', @controller.content_type
assert_equal 'disposition; filename="filename"', h['Content-Disposition']
assert_equal 'binary', h['Content-Transfer-Encoding']
View
1 actionpack/test/fixtures/public/.gitignore
@@ -0,0 +1 @@
+absolute
View
1 actionpack/test/fixtures/public/elsewhere/cools.js
@@ -0,0 +1 @@
+// cools.js
View
1 actionpack/test/fixtures/public/elsewhere/file.css
@@ -0,0 +1 @@
+/*file.css*/
View
1 actionpack/test/fixtures/public/javascripts/common.javascript
@@ -0,0 +1 @@
+// common.javascript
View
1 actionpack/test/fixtures/public/stylesheets/random.styles
@@ -0,0 +1 @@
+/* random.styles */
View
6 actionpack/test/lib/fixture_template.rb
@@ -12,7 +12,7 @@ def find_templates(name, details, prefix, partial)
@hash.select { |k,v| k =~ regexp }.each do |path, source|
templates << Template.new(source, path, *path_to_details(path))
end
- templates
+ templates.sort_by {|t| -t.details.values.compact.size }
end
end
end
@@ -44,15 +44,15 @@ def details_to_regexp(name, details, prefix, partial)
k == :formats ? formats_regexp : ''
end
end
-
+
%r'^#{Regexp.escape(path)}#{extensions}#{handler_regexp}$'
end
# TODO: fix me
# :api: plugin
def path_to_details(path)
# [:erb, :format => :html, :locale => :en, :partial => true/false]
- if m = path.match(%r'(_)?[\w-]+(\.[\w-]+)*\.(\w+)$')
+ if m = path.match(%r'(_)?[\w-]+((?:\.[\w-]+)*)\.(\w+)$')
partial = m[1] == '_'
details = (m[2]||"").split('.').reject { |e| e.empty? }
handler = Template.handler_class_for_extension(m[3])
View
3 actionpack/test/old_base/abstract_unit.rb
@@ -12,9 +12,6 @@
require 'stringio'
require 'test/unit'
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
-
begin
require 'ruby-debug'
Debugger.settings[:autoeval] = true
View
118 actionpack/test/template/asset_tag_helper_test.rb
@@ -75,22 +75,22 @@ def teardown
}
JavascriptIncludeToTag = {
- %(javascript_include_tag("xmlhr")) => %(<script src="/javascripts/xmlhr.js" type="text/javascript"></script>),
- %(javascript_include_tag("xmlhr.js")) => %(<script src="/javascripts/xmlhr.js" type="text/javascript"></script>),
- %(javascript_include_tag("xmlhr", :lang => "vbscript")) => %(<script lang="vbscript" src="/javascripts/xmlhr.js" type="text/javascript"></script>),
+ %(javascript_include_tag("bank")) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>),
+ %(javascript_include_tag("bank.js")) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>),
+ %(javascript_include_tag("bank", :lang => "vbscript")) => %(<script lang="vbscript" src="/javascripts/bank.js" type="text/javascript"></script>),
%(javascript_include_tag("common.javascript", "/elsewhere/cools")) => %(<script src="/javascripts/common.javascript" type="text/javascript"></script>\n<script src="/elsewhere/cools.js" type="text/javascript"></script>),
%(javascript_include_tag(:defaults)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
%(javascript_include_tag(:all)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
%(javascript_include_tag(:all, :recursive => true)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
- %(javascript_include_tag(:defaults, "test")) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/test.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
- %(javascript_include_tag("test", :defaults)) => %(<script src="/javascripts/test.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>)
+ %(javascript_include_tag(:defaults, "bank")) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
+ %(javascript_include_tag("bank", :defaults)) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>)
}
StylePathToTag = {
- %(stylesheet_path("style")) => %(/stylesheets/style.css),
- %(stylesheet_path("style.css")) => %(/stylesheets/style.css),
- %(stylesheet_path('dir/file')) => %(/stylesheets/dir/file.css),
- %(stylesheet_path('/dir/file.rcss')) => %(/dir/file.rcss)
+ %(stylesheet_path("bank")) => %(/stylesheets/bank.css),
+ %(stylesheet_path("bank.css")) => %(/stylesheets/bank.css),
+ %(stylesheet_path('subdir/subdir')) => %(/stylesheets/subdir/subdir.css),
+ %(stylesheet_path('/subdir/subdir.css')) => %(/subdir/subdir.css)
}
PathToStyleToTag = {
@@ -101,15 +101,16 @@ def teardown
}
StyleLinkToTag = {
- %(stylesheet_link_tag("style")) => %(<link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />),
- %(stylesheet_link_tag("style.css")) => %(<link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />),
- %(stylesheet_link_tag("/dir/file")) => %(<link href="/dir/file.css" media="screen" rel="stylesheet" type="text/css" />),
- %(stylesheet_link_tag("dir/file")) => %(<link href="/stylesheets/dir/file.css" media="screen" rel="stylesheet" type="text/css" />),
- %(stylesheet_link_tag("style", :media => "all")) => %(<link href="/stylesheets/style.css" media="all" rel="stylesheet" type="text/css" />),
+ %(stylesheet_link_tag("bank")) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />),
+ %(stylesheet_link_tag("bank.css")) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />),
+ %(stylesheet_link_tag("/elsewhere/file")) => %(<link href="/elsewhere/file.css" media="screen" rel="stylesheet" type="text/css" />),
+ %(stylesheet_link_tag("subdir/subdir")) => %(<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" type="text/css" />),
+ %(stylesheet_link_tag("bank", :media => "all")) => %(<link href="/stylesheets/bank.css" media="all" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag(:all)) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag(:all, :recursive => true)) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag(:all, :media => "all")) => %(<link href="/stylesheets/bank.css" media="all" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/robber.css" media="all" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/version.1.0.css" media="all" rel="stylesheet" type="text/css" />),
- %(stylesheet_link_tag("random.styles", "/css/stylish")) => %(<link href="/stylesheets/random.styles" media="screen" rel="stylesheet" type="text/css" />\n<link href="/css/stylish.css" media="screen" rel="stylesheet" type="text/css" />),
+ %(stylesheet_link_tag("random.styles", "/elsewhere/file")) => %(<link href="/stylesheets/random.styles" media="screen" rel="stylesheet" type="text/css" />\n<link href="/elsewhere/file.css" media="screen" rel="stylesheet" type="text/css" />),
+
%(stylesheet_link_tag("http://www.example.com/styles/style")) => %(<link href="http://www.example.com/styles/style.css" media="screen" rel="stylesheet" type="text/css" />)
}
@@ -160,33 +161,48 @@ def test_javascript_include_tag_with_blank_asset_id
JavascriptIncludeToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
+ def test_javascript_include_tag_with_missing_source
+ assert_raise(Errno::ENOENT) {
+ javascript_include_tag('missing_security_guard')
+ }
+
+ assert_raise(Errno::ENOENT) {
+ javascript_include_tag(:defaults, 'missing_security_guard')
+ }
+
+ assert_nothing_raised {
+ javascript_include_tag('http://example.com/css/missing_security_guard')
+ }
+ end
+
def test_javascript_include_tag_with_given_asset_id
ENV["RAILS_ASSET_ID"] = "1"
assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>), javascript_include_tag(:defaults))
end
def test_register_javascript_include_default
ENV["RAILS_ASSET_ID"] = ""
- ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'slider'
- assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/slider.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
+ ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'bank'
+ assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
end
def test_register_javascript_include_default_mixed_defaults
ENV["RAILS_ASSET_ID"] = ""
- ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'slider'
- ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'lib1', '/elsewhere/blub/lib2'
- assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/slider.js" type="text/javascript"></script>\n<script src="/javascripts/lib1.js" type="text/javascript"></script>\n<script src="/elsewhere/blub/lib2.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
+ ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'bank'
+ ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'robber', '/elsewhere/cools.js'
+ assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/elsewhere/cools.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
end
def test_custom_javascript_expansions
- ActionView::Helpers::AssetTagHelper::register_javascript_expansion :monkey => ["head", "body", "tail"]
- assert_dom_equal %(<script src="/javascripts/first.js" type="text/javascript"></script>\n<script src="/javascripts/head.js" type="text/javascript"></script>\n<script src="/javascripts/body.js" type="text/javascript"></script>\n<script src="/javascripts/tail.js" type="text/javascript"></script>\n<script src="/javascripts/last.js" type="text/javascript"></script>), javascript_include_tag('first', :monkey, 'last')
+ ENV["RAILS_ASSET_ID"] = ""
+ ActionView::Helpers::AssetTagHelper::register_javascript_expansion :robbery => ["bank", "robber"]
+ assert_dom_equal %(<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>), javascript_include_tag('controls', :robbery, 'effects')
end
def test_custom_javascript_expansions_and_defaults_puts_application_js_at_the_end
ENV["RAILS_ASSET_ID"] = ""
- ActionView::Helpers::AssetTagHelper::register_javascript_expansion :monkey => ["head", "body", "tail"]
- assert_dom_equal %(<script src="/javascripts/first.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/head.js" type="text/javascript"></script>\n<script src="/javascripts/body.js" type="text/javascript"></script>\n<script src="/javascripts/tail.js" type="text/javascript"></script>\n<script src="/javascripts/last.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag('first', :defaults, :monkey, 'last')
+ ActionView::Helpers::AssetTagHelper::register_javascript_expansion :robbery => ["bank", "robber"]
+ assert_dom_equal %(<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag('controls',:defaults, :robbery, 'effects')
end
def test_custom_javascript_expansions_with_undefined_symbol
@@ -195,6 +211,7 @@ def test_custom_javascript_expansions_with_undefined_symbol
end
def test_stylesheet_path
+ ENV["RAILS_ASSET_ID"] = ""
StylePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
@@ -207,9 +224,20 @@ def test_stylesheet_link_tag
StyleLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
+ def test_stylesheet_link_tag_with_missing_source
+ assert_raise(Errno::ENOENT) {
+ stylesheet_link_tag('missing_security_guard')
+ }
+
+ assert_nothing_raised {
+ stylesheet_link_tag('http://example.com/css/missing_security_guard')
+ }
+ end
+
def test_custom_stylesheet_expansions
- ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :monkey => ["head", "body", "tail"]
- assert_dom_equal %(<link href="/stylesheets/first.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/head.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/body.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/tail.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/last.css" media="screen" rel="stylesheet" type="text/css" />), stylesheet_link_tag('first', :monkey, 'last')
+ ENV["RAILS_ASSET_ID"] = ''
+ ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :robbery => ["bank", "robber"]
+ assert_dom_equal %(<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" type="text/css" />), stylesheet_link_tag('version.1.0', :robbery, 'subdir/subdir')
end
def test_custom_stylesheet_expansions_with_undefined_symbol
@@ -546,8 +574,14 @@ def test_caching_stylesheet_link_tag_when_caching_on
stylesheet_link_tag(:all, :cache => true)
)
- expected = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/*.css"].map { |p| File.mtime(p) }.max
- assert_equal expected, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
+ files_to_be_joined = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/[^all]*.css"]
+
+ expected_mtime = files_to_be_joined.map { |p| File.mtime(p) }.max
+ assert_equal expected_mtime, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
+
+ bytes_added_by_join = "\n\n".size * files_to_be_joined.size - "\n\n".size
+ expected_size = files_to_be_joined.sum { |p| File.size(p) } + bytes_added_by_join
+ assert_equal expected_size, File.size(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
assert_dom_equal(
%(<link href="http://a0.example.com/stylesheets/money.css" media="screen" rel="stylesheet" type="text/css" />),
@@ -598,6 +632,28 @@ def test_concat_stylesheet_link_tag_when_caching_off
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute'))
end
+ def test_caching_stylesheet_link_tag_when_caching_on_and_missing_css_file
+ ENV["RAILS_ASSET_ID"] = ""
+ ActionController::Base.asset_host = 'http://a0.example.com'
+ ActionController::Base.perform_caching = true
+
+ assert_raise(Errno::ENOENT) {
+ stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => true)
+ }
+
+ assert ! File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
+
+ assert_raise(Errno::ENOENT) {
+ stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => "money")
+ }
+
+ assert ! File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
+
+ ensure
+ FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
+ FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
+ end
+
def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" }
@@ -625,8 +681,10 @@ def test_caching_stylesheet_link_tag_with_relative_url_root
stylesheet_link_tag(:all, :cache => true)
)
- expected = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/*.css"].map { |p| File.mtime(p) }.max
- assert_equal expected, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
+ files_to_be_joined = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/[^all]*.css"]
+
+ expected_mtime = files_to_be_joined.map { |p| File.mtime(p) }.max
+ assert_equal expected_mtime, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
assert_dom_equal(
%(<link href="/collaboration/hieraki/stylesheets/money.css" media="screen" rel="stylesheet" type="text/css" />),
View
15 actionpack/test/template/capture_helper_test.rb
@@ -0,0 +1,15 @@
+require 'abstract_unit'
+
+class CaptureHelperTest < ActionView::TestCase
+ def setup
+ super
+ @_content_for = Hash.new {|h,k| h[k] = "" }
+ end
+
+ def test_content_for
+ assert ! content_for?(:title)
+ content_for :title, 'title'
+ assert content_for?(:title)
+ assert ! content_for?(:something_else)
+ end
+end
View
12 actionpack/test/template/form_tag_helper_test.rb
@@ -159,6 +159,18 @@ def test_text_area_tag_id_sanitized
assert_match VALID_HTML_ID, input_elem['id']
end
+ def test_text_area_tag_escape_content
+ actual = text_area_tag "body", "<b>hello world</b>", :size => "20x40"
+ expected = %(<textarea cols="20" id="body" name="body" rows="40">&lt;b&gt;hello world&lt;/b&gt;</textarea>)
+ assert_dom_equal expected, actual
+ end
+
+ def test_text_area_tag_unescaped_content
+ actual = text_area_tag "body", "<b>hello world</b>", :size => "20x40", :escape => false
+ expected = %(<textarea cols="20" id="body" name="body" rows="40"><b>hello world</b></textarea>)
+ assert_dom_equal expected, actual
+ end
+
def test_text_field_tag
actual = text_field_tag "title", "Hello!"
expected = %(<input id="title" name="title" type="text" value="Hello!" />)
View
2 activemodel/test/cases/helper.rb
@@ -10,8 +10,6 @@
require 'rubygems'
require 'test/unit'
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
begin
require 'ruby-debug'
View
2 activerecord/Rakefile
@@ -187,7 +187,7 @@ spec = Gem::Specification.new do |s|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
end
- s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 3.0.pre' + PKG_BUILD)
s.files.delete FIXTURES_ROOT + "/fixture_database.sqlite"
s.files.delete FIXTURES_ROOT + "/fixture_database_2.sqlite"
View
14 activerecord/lib/active_record/associations/association_collection.rb
@@ -351,7 +351,19 @@ def proxy_respond_to?(method, include_private = false)
protected
def construct_find_options!(options)
end
-
+
+ def construct_counter_sql
+ if @reflection.options[:counter_sql]
+ @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
+ elsif @reflection.options[:finder_sql]
+ # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
+ @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT\b(\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
+ @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
+ else
+ @counter_sql = @finder_sql
+ end
+ end
+
def load_target
if !@owner.new_record? || foreign_key_present
begin
View
10 activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
@@ -85,15 +85,7 @@ def construct_sql
@join_sql = "INNER JOIN #{@owner.connection.quote_table_name @reflection.options[:join_table]} ON #{@reflection.quoted_table_name}.#{@reflection.klass.primary_key} = #{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.association_foreign_key}"
- if @reflection.options[:counter_sql]
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- elsif @reflection.options[:finder_sql]
- # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
- @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- else
- @counter_sql = @finder_sql
- end
+ construct_counter_sql
end
def construct_scope
View
10 activerecord/lib/active_record/associations/has_many_association.rb
@@ -97,15 +97,7 @@ def construct_sql
@finder_sql << " AND (#{conditions})" if conditions
end
- if @reflection.options[:counter_sql]
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- elsif @reflection.options[:finder_sql]
- # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
- @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- else
- @counter_sql = @finder_sql
- end
+ construct_counter_sql
end
def construct_scope
View
10 activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -90,15 +90,7 @@ def construct_sql
@finder_sql = construct_conditions
end
- if @reflection.options[:counter_sql]
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- elsif @reflection.options[:finder_sql]
- # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
- @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- else
- @counter_sql = @finder_sql
- end
+ construct_counter_sql
end
def has_cached_counter?
View
7 activerecord/lib/active_record/associations/through_association_scope.rb
@@ -94,10 +94,17 @@ def construct_owner_attributes(reflection)
def construct_join_attributes(associate)
# TODO: revist this to allow it for deletion, supposing dependent option is supported
raise ActiveRecord::HasManyThroughCantAssociateThroughHasManyReflection.new(@owner, @reflection) if @reflection.source_reflection.macro == :has_many
+
join_attributes = construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id)
+
if @reflection.options[:source_type]
join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name.to_s)
end
+
+ if @reflection.through_reflection.options[:conditions].is_a?(Hash)
+ join_attributes.merge!(@reflection.through_reflection.options[:conditions])
+ end
+
join_attributes
end
View
32 activerecord/lib/active_record/base.rb
@@ -67,6 +67,25 @@ class RecordNotSaved < ActiveRecordError
class StatementInvalid < ActiveRecordError
end
+ # Parent class for all specific exceptions which wrap database driver exceptions
+ # provides access to the original exception also.
+ class WrappedDatabaseException < StatementInvalid
+ attr_reader :original_exception
+
+ def initialize(message, original_exception)
+ super(message)
+ @original_exception, = original_exception
+ end
+ end
+
+ # Raised when a record cannot be inserted because it would violate a uniqueness constraint.
+ class RecordNotUnique < WrappedDatabaseException
+ end
+
+ # Raised when a record cannot be inserted or updated because it references a non-existent record.
+ class InvalidForeignKey < WrappedDatabaseException
+ end
+
# Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example, when using +find+ method)
# does not match number of expected variables.
#
@@ -1385,14 +1404,14 @@ def human_attribute_name(attribute_key_name, options = {})
end
# Transform the modelname into a more humane format, using I18n.
- # Defaults to the basic humanize method.
+ # By default, it will underscore then humanize the class name (BlogPost.human_name #=> "Blog post").
# Default scope of the translation is activerecord.models
# Specify +options+ with additional translating options.
def human_name(options = {})
defaults = self_and_descendants_from_active_record.map do |klass|
:"#{klass.name.underscore}"
- end
- defaults << self.name.humanize
+ end
+ defaults << self.name.underscore.humanize
I18n.translate(defaults.shift, {:scope => [:activerecord, :models], :count => 1, :default => defaults}.merge(options))
end
@@ -2851,6 +2870,13 @@ def frozen?
@attributes.frozen?
end
+ # Returns duplicated record with unfreezed attributes.
+ def dup
+ obj = super
+ obj.instance_variable_set('@attributes', instance_variable_get('@attributes').dup)
+ obj
+ end
+
# Returns +true+ if the record is read only. Records loaded through joins with piggy-back
# attributes will be marked as read only since they cannot be saved.
def readonly?
View
2 activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -101,7 +101,7 @@ def create_table(table_name, options = {})
table_definition = TableDefinition.new(self)
table_definition.primary_key(options[:primary_key] || Base.get_primary_key(table_name)) unless options[:id] == false
- yield table_definition
+ yield table_definition if block_given?
if options[:force] && table_exists?(table_name)
drop_table(table_name, options)
View
7 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -211,9 +211,14 @@ def log(sql, name)
@last_verification = 0
message = "#{e.class.name}: #{e.message}: #{sql}"
log_info(message, name, 0)
- raise ActiveRecord::StatementInvalid, message
+ raise translate_exception(e, message)
end
+ def translate_exception(e, message)
+ # override in derived class
+ ActiveRecord::StatementInvalid.new(message)
+ end
+
def format_log_entry(message, dump = nil)
if ActiveRecord::Base.colorize_logging
if @@row_even
View
13 activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -563,6 +563,19 @@ def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
where_sql
end
+ protected
+
+ def translate_exception(exception, message)
+ case exception.errno
+ when 1062
+ RecordNotUnique.new(message, exception)
+ when 1452
+ InvalidForeignKey.new(message, exception)
+ else
+ super
+ end
+ end
+
private
def connect
encoding = @config[:encoding]
View
11 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -941,6 +941,17 @@ def postgresql_version
end
end
+ def translate_exception(exception, message)
+ case exception.message
+ when /duplicate key value violates unique constraint/
+ RecordNotUnique.new(message, exception)
+ when /violates foreign key constraint/
+ InvalidForeignKey.new(message, exception)
+ else
+ super
+ end
+ end
+
private
# The internal PostgreSQL identifier of the money data type.
MONEY_COLUMN_TYPE_OID = 790 #:nodoc:
View
12 activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -245,7 +245,7 @@ def remove_index(table_name, options={}) #:nodoc:
end
def rename_table(name, new_name)
- execute "ALTER TABLE #{name} RENAME TO #{new_name}"
+ execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
end
# See: http://www.sqlite.org/lang_altertable.html
@@ -431,6 +431,16 @@ def default_primary_key_type
'INTEGER PRIMARY KEY NOT NULL'.freeze
end
end
+
+ def translate_exception(exception, message)
+ case exception.message
+ when /column(s)? .* (is|are) not unique/
+ RecordNotUnique.new(message, exception)
+ else
+ super
+ end
+ end
+
end
class SQLite2Adapter < SQLiteAdapter # :nodoc:
View
6 activerecord/lib/active_record/version.rb
@@ -1,8 +1,8 @@
module ActiveRecord
module VERSION #:nodoc:
- MAJOR = 2
- MINOR = 3
- TINY = 2
+ MAJOR = 3
+ MINOR = 0
+ TINY = "pre"
STRING = [MAJOR, MINOR, TINY].join('.')
end
View
15 activerecord/test/cases/adapter_test.rb
@@ -130,4 +130,19 @@ def test_add_limit_offset_should_sanitize_sql_injection_for_limit_with_comas
assert_equal " LIMIT 1,7 OFFSET 7", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
end
end
+
+ def test_uniqueness_violations_are_translated_to_specific_exception
+ @connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
+ assert_raises(ActiveRecord::RecordNotUnique) do
+ @connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
+ end
+ end
+
+ def test_foreign_key_violations_are_translated_to_specific_exception
+ unless @connection.adapter_name == 'SQLite'
+ assert_raises(ActiveRecord::InvalidForeignKey) do
+ @connection.execute "INSERT INTO fk_test_has_fk (fk_id) VALUES (0)"
+ end
+ end
+ end
end
View
7 activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -803,6 +803,13 @@ def test_count_with_counter_sql
assert_equal 1, developer.projects.count
end
+ unless current_adapter?(:PostgreSQLAdapter)
+ def test_count_with_finder_sql
+ assert_equal 3, projects(:active_record).developers_with_finder_sql.count
+ assert_equal 3, projects(:active_record).developers_with_multiline_finder_sql.count
+ end
+ end
+
def test_association_proxy_transaction_method_starts_transaction_in_association_class
Post.expects(:transaction)
Category.find(:first).posts.transaction do
View
5 activerecord/test/cases/associations/has_many_associations_test.rb
@@ -163,6 +163,11 @@ def test_counting_non_existant_items_using_sql
assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size
end
+ def test_counting_using_finder_sql
+ assert_equal 2, Firm.find(4).clients_using_sql.count
+ assert_equal 2, Firm.find(4).clients_using_multiline_sql.count
+ end
+
def test_belongs_to_sanity
c = Client.new
assert_nil c.firm
View
6 activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -157,6 +157,12 @@ def test_associate_with_create_and_no_options
assert_equal peeps + 1, posts(:thinking).people.count
end
+ def test_associate_with_create_with_through_having_conditions
+ impatient_people = posts(:thinking).impatient_people.count
+ posts(:thinking).impatient_people.create!(:first_name => 'foo')
+ assert_equal impatient_people + 1, posts(:thinking).impatient_people.count
+ end
+
def test_associate_with_create_exclamation_and_no_options
peeps = posts(:thinking).people.count
posts(:thinking).people.create!(:first_name => 'foo')
View
10 activerecord/test/cases/base_test.rb
@@ -599,9 +599,9 @@ def test_destroy_all
end
def test_destroy_many
- assert_equal 3, Client.count
- Client.destroy([2, 3])
- assert_equal 1, Client.count
+ assert_difference('Client.count', -2) do
+ Client.destroy([2, 3])
+ end
end
def test_delete_many
@@ -2116,4 +2116,8 @@ def test_create_with_custom_timestamps
assert_equal custom_datetime, parrot[attribute]
end
end
+
+ def test_dup
+ assert !Minimalistic.new.freeze.dup.frozen?
+ end
end
View
4 activerecord/test/cases/calculations_test.rb
@@ -203,15 +203,15 @@ def test_should_calculate_grouped_by_function
c = Company.count(:all, :group => "UPPER(#{QUOTED_TYPE})")
assert_equal 2, c[nil]
assert_equal 1, c['DEPENDENTFIRM']
- assert_equal 3, c['CLIENT']
+ assert_equal 4, c['CLIENT']
assert_equal 2, c['FIRM']
end
def test_should_calculate_grouped_by_function_with_table_alias
c = Company.count(:all, :group => "UPPER(companies.#{QUOTED_TYPE})")
assert_equal 2, c[nil]
assert_equal 1, c['DEPENDENTFIRM']
- assert_equal 3, c['CLIENT']
+ assert_equal 4, c['CLIENT']
assert_equal 2, c['FIRM']
end
View
4 activerecord/test/cases/finder_test.rb
@@ -1044,8 +1044,8 @@ def test_select_value
end
def test_select_values
- assert_equal ["1","2","3","4","5","6","7","8","9"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
- assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
+ assert_equal ["1","2","3","4","5","6","7","8","9", "10"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
+ assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy", "Ex Nihilo Part Deux"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
end
def test_select_rows
View
2 activerecord/test/cases/helper.rb
@@ -6,8 +6,6 @@
require 'rubygems'
require 'test/unit'
require 'stringio'
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
require 'active_record'
require 'active_record/test_case'
View
4 activerecord/test/cases/inheritance_test.rb
@@ -112,9 +112,9 @@ def test_alt_inheritance_save
end
def test_inheritance_condition
- assert_equal 9, Company.count
+ assert_equal 10, Company.count
assert_equal 2, Firm.count
- assert_equal 3, Client.count
+ assert_equal 4, Client.count
end
def test_alt_inheritance_condition
View
33 activerecord/test/cases/migration_test.rb
@@ -293,6 +293,13 @@ def test_create_table_with_timestamps_should_create_datetime_columns_with_option
Person.connection.drop_table table_name rescue nil
end
+ def test_create_table_without_a_block
+ table_name = :testings
+ Person.connection.create_table table_name
+ ensure
+ Person.connection.drop_table table_name rescue nil
+ end
+
# Sybase, and SQLite3 will not allow you to add a NOT NULL
# column to a table without a default value.
unless current_adapter?(:SybaseAdapter, :SQLiteAdapter)
@@ -635,6 +642,32 @@ def test_change_type_of_not_null_column
end
end
+ if current_adapter?(:SQLiteAdapter)
+ def test_rename_table_for_sqlite_should_work_with_reserved_words
+ begin
+ assert_nothing_raised do
+ ActiveRecord::Base.connection.rename_table :references, :old_references
+ ActiveRecord::Base.connection.create_table :octopuses do |t|
+ t.column :url, :string
+ end
+ end
+
+ assert_nothing_raised { ActiveRecord::Base.connection.rename_table :octopuses, :references }
+
+ # Using explicit id in insert for compatibility across all databases
+ con = ActiveRecord::Base.connection
+ assert_nothing_raised do
+ con.execute "INSERT INTO 'references' (#{con.quote_column_name('id')}, #{con.quote_column_name('url')}) VALUES (1, 'http://rubyonrails.com')"
+ end
+ assert_equal 'http://rubyonrails.com', ActiveRecord::Base.connection.select_value("SELECT url FROM 'references' WHERE id=1")
+
+ ensure
+ ActiveRecord::Base.connection.drop_table :references
+ ActiveRecord::Base.connection.rename_table :old_references, :references
+ end
+ end
+ end
+
def test_rename_table
begin
ActiveRecord::Base.connection.create_table :octopuses do |t|
View
12 activerecord/test/cases/reflection_test.rb
@@ -5,14 +5,20 @@
require 'models/company_in_module'
require 'models/subscriber'
require 'models/pirate'
+require 'models/price_estimate'
class ReflectionTest < ActiveRecord::TestCase
- fixtures :topics, :customers, :companies, :subscribers
+ fixtures :topics, :customers, :companies, :subscribers, :price_estimates
def setup
@first = Topic.find(1)
end
+ def test_human_name
+ assert_equal "Price estimate", PriceEstimate.human_name
+ assert_equal "Subscriber", Subscriber.human_name
+ end
+
def test_column_null_not_null
subscriber = Subscriber.find(:first)
assert subscriber.column_for_attribute("name").null
@@ -170,8 +176,8 @@ def test_association_reflection_in_modules
def test_reflection_of_all_associations
# FIXME these assertions bust a lot
- assert_equal 28, Firm.reflect_on_all_associations.size
- assert_equal 21, Firm.reflect_on_all_associations(:has_many).size
+ assert_equal 29, Firm.reflect_on_all_associations.size
+ assert_equal 22, Firm.reflect_on_all_associations(:has_many).size
assert_equal 7, Firm.reflect_on_all_associations(:has_one).size
assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
end
View
8 activerecord/test/fixtures/companies.yml
@@ -35,6 +35,14 @@ another_client:
name: Ex Nihilo
ruby_type: Client
+a_third_client:
+ id: 10
+ type: Client
+ firm_id: 4
+ client_of: 4
+ name: Ex Nihilo Part Deux
+ ruby_type: Client
+
rails_core:
id: 6
name: RailsCore
View
4 activerecord/test/models/company.rb
@@ -48,6 +48,10 @@ class Firm < Company
has_many :clients_with_interpolated_conditions, :class_name => "Client", :conditions => 'rating > #{rating}'
has_many :clients_like_ms_with_hash_conditions, :conditions => { :name => 'Microsoft' }, :class_name => "Client", :order => "id"
has_many :clients_using_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}'
+ has_many :clients_using_multiline_sql, :class_name => "Client", :finder_sql => '
+ SELECT
+ companies.*
+ FROM companies WHERE companies.client_of = #{id}'
has_many :clients_using_counter_sql, :class_name => "Client",
:finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}',
:counter_sql => 'SELECT COUNT(*) FROM companies WHERE client_of = #{id}'
View
2 activerecord/test/models/post.rb
@@ -69,6 +69,8 @@ def add_joins_and_select
:after_add => lambda {|owner, reader| log(:added, :after, reader.first_name) },
:before_remove => lambda {|owner, reader| log(:removed, :before, reader.first_name) },
:after_remove => lambda {|owner, reader| log(:removed, :after, reader.first_name) }
+ has_many :skimmers, :class_name => 'Reader', :conditions => { :skimmer => true }
+ has_many :impatient_people, :through => :skimmers, :source => :person
def self.top(limit)
ranked_by_comments.limit(limit)
View
6 activerecord/test/models/project.rb
@@ -8,6 +8,12 @@ class Project < ActiveRecord::Base
has_and_belongs_to_many :developers_named_david_with_hash_conditions, :class_name => "Developer", :conditions => { :name => 'David' }, :uniq => true
has_and_belongs_to_many :salaried_developers, :class_name => "Developer", :conditions => "salary > 0"
has_and_belongs_to_many :developers_with_finder_sql, :class_name => "Developer", :finder_sql => 'SELECT t.*, j.* FROM developers_projects j, developers t WHERE t.id = j.developer_id AND j.project_id = #{id} ORDER BY t.id'
+ has_and_belongs_to_many :developers_with_multiline_finder_sql, :class_name => "Developer", :finder_sql => '
+ SELECT
+ t.*, j.*
+ FROM
+ developers_projects j,
+ developers t WHERE t.id = j.developer_id AND j.project_id = #{id} ORDER BY t.id'
has_and_belongs_to_many :developers_by_sql, :class_name => "Developer", :delete_sql => "DELETE FROM developers_projects WHERE project_id = \#{id} AND developer_id = \#{record.id}"
has_and_belongs_to_many :developers_with_callbacks, :class_name => "Developer", :before_add => Proc.new {|o, r| o.developers_log << "before_adding#{r.id || '<new>'}"},
:after_add => Proc.new {|o, r| o.developers_log << "after_adding#{r.id || '<new>'}"},
View
1 activerecord/test/schema/schema.rb
@@ -364,6 +364,7 @@ def create_table(*args, &block)
create_table :readers, :force => true do |t|
t.integer :post_id, :null => false
t.integer :person_id, :null => false
+ t.boolean :skimmer, :default => false
end
create_table :shape_expressions, :force => true do |t|
View
2 activeresource/Rakefile
@@ -73,7 +73,7 @@ spec = Gem::Specification.new do |s|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
end
- s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 3.0.pre' + PKG_BUILD)
s.require_path = 'lib'
s.autorequire = 'active_resource'
View
6 activeresource/lib/active_resource/version.rb
@@ -1,8 +1,8 @@
module ActiveResource
module VERSION #:nodoc:
- MAJOR = 2
- MINOR = 3
- TINY = 2
+ MAJOR = 3
+ MINOR = 0
+ TINY = "pre"
STRING = [MAJOR, MINOR, TINY].join('.')
end
View
4 activeresource/test/abstract_unit.rb
@@ -1,8 +1,6 @@
require 'rubygems'
require 'test/unit'
-
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
+require 'active_support/test_case'
$:.unshift "#{File.dirname(__FILE__)}/../lib"
require 'active_resource'
View
19 activesupport/lib/active_support/cache.rb
@@ -2,7 +2,12 @@
require 'active_support/core_ext/benchmark'
require 'active_support/core_ext/exception'
require 'active_support/core_ext/class/attribute_accessors'
-require 'active_support/core_ext' # FIXME: pulling in all to_param extensions
+
+%w(hash nil string time date date_time array big_decimal range object boolean).each do |library|
+ require "active_support/core_ext/#{library}/conversions"
+end
+
+# require 'active_support/core_ext' # FIXME: pulling in all to_param extensions
module ActiveSupport
# See ActiveSupport::Cache::Store for documentation.
@@ -129,8 +134,8 @@ def silence!
#
# For example, MemCacheStore's #write method supports the +:expires_in+
# option, which tells the memcached server to automatically expire the
- # cache item after a certain period. We can use this option with #fetch
- # too:
+ # cache item after a certain period. This options is also supported by
+ # FileStore's #read method. We can use this option with #fetch too:
#
# cache = ActiveSupport::Cache::MemCacheStore.new
# cache.fetch("foo", :force => true, :expires_in => 5.seconds) do
@@ -169,6 +174,10 @@ def fetch(key, options = {})
# You may also specify additional options via the +options+ argument.
# The specific cache store implementation will decide what to do with
# +options+.
+ #
+ # For example, FileStore supports the +:expires_in+ option, which
+ # makes the method return nil for cache items older than the specified
+ # period.
def read(key, options = nil)
log("read", key, options)
end
@@ -223,6 +232,10 @@ def decrement(key, amount = 1)
end
private
+ def expires_in(options)
+ (options && options[:expires_in]) || 0
+ end
+
def log(operation, key, options)
logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !@silence && !@logger_off
end
View
14 activesupport/lib/active_support/cache/file_store.rb
@@ -10,11 +10,23 @@ def initialize(cache_path)
@cache_path = cache_path
end
+ # Reads a value from the cache.
+ #
+ # Possible options:
+ # - +:expires_in+ - the number of seconds that this value may stay in
+ # the cache.
def read(name, options = nil)
super
- File.open(real_file_path(name), 'rb') { |f| Marshal.load(f) } rescue nil
+
+ file_name = real_file_path(name)
+ expires = expires_in(options)
+
+ if File.exist?(file_name) && (expires <= 0 || Time.now - File.mtime(file_name) < expires)
+ File.open(file_name, 'rb') { |f| Marshal.load(f) }
+ end
end
+ # Writes a value to the cache.
def write(name, value, options = nil)
super
ensure_cache_path(File.dirname(real_file_path(name)))
View
4 activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -130,10 +130,6 @@ def stats
end
private
- def expires_in(options)
- (options && options[:expires_in]) || 0
- end
-
def raw?(options)
options && options[:raw]
end
View
2 activesupport/lib/active_support/cache/memory_store.rb
@@ -26,7 +26,7 @@ def read(name, options = nil)
def write(name, value, options = nil)
super
- @data[name] = value.freeze