diff --git a/actionpack/lib/action_controller/routing/route_set.rb b/actionpack/lib/action_controller/routing/route_set.rb index 87b4b0571c3b376304f5a8ae00ccb40100cf23c7..f5a4b1e1db57808ce5c4cf537ae9c6d40df2df90 100644 --- a/actionpack/lib/action_controller/routing/route_set.rb +++ b/actionpack/lib/action_controller/routing/route_set.rb @@ -305,6 +305,7 @@ def routes_changed_at end def add_route(path, options = {}) + options.each { |k, v| options[k] = v.to_s if [:controller, :action].include?(k) && v.is_a?(Symbol) } route = builder.build(path, options) routes << route route diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 14cdc7a02539982b2d8bfe4296c64b9ee94938c6..6d2c28f969eccf4da36c309f74480d444e9f6dd6 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -454,6 +454,21 @@ def image_path(source) end alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route + # Computes the path to a video asset in the public videos directory. + # Full paths from the document root will be passed through. + # Used internally by +video_tag+ to build the video path. + # + # ==== Examples + # video_path("hd") # => /videos/hd + # video_path("hd.avi") # => /videos/hd.avi + # video_path("trailers/hd.avi") # => /videos/trailers/hd.avi + # video_path("/trailers/hd.avi") # => /videos/hd.avi + # video_path("http://www.railsapplication.com/vid/hd.avi") # => http://www.railsapplication.com/vid/hd.avi + def video_path(source) + compute_public_path(source, 'videos') + end + alias_method :path_to_video, :video_path # aliased to avoid conflicts with an video_path named route + # Returns an html image tag for the +source+. The +source+ can be a full # path or a file that exists in your public images directory. # @@ -490,8 +505,8 @@ def image_path(source) def image_tag(source, options = {}) options.symbolize_keys! - options[:src] = path_to_image(source) - options[:alt] ||= File.basename(options[:src], '.*').split('.').first.to_s.capitalize + src = options[:src] = path_to_image(source) + options[:alt] ||= File.basename(src, '.*').split('.').first.to_s.capitalize if size = options.delete(:size) options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$} @@ -499,12 +514,64 @@ def image_tag(source, options = {}) if mouseover = options.delete(:mouseover) options[:onmouseover] = "this.src='#{image_path(mouseover)}'" - options[:onmouseout] = "this.src='#{image_path(options[:src])}'" + options[:onmouseout] = "this.src='#{src}'" end tag("img", options) end + # Returns an html video tag for the +sources+. If +sources+ is a string, + # a single video tag will be returned. If +sources+ is an array, a video + # tag with nested source tags for each source will be returned. The + # +sources+ can be full paths or files that exists in your public videos + # directory. + # + # ==== Options + # You can add HTML attributes using the +options+. The +options+ supports + # two additional keys for convenience and conformance: + # + # * :poster - Set an image (like a screenshot) to be shown + # before the video loads. The path is calculated like the +src+ of +image_tag+. + # * :size - Supplied as "{Width}x{Height}", so "30x45" becomes + # width="30" and height="45". :size will be ignored if the + # value is not in the correct format. + # + # ==== Examples + # video_tag("trailer") # => + # + # video_tag("trailer.ogg") # => + # + # video_tag("trailer.ogg", :controls => true, :autobuffer => true) # => + # + # video_tag("trailer.m4v", :size => "16x10", :poster => "screenshot.png") # => + # + # video_tag("/trailers/hd.avi", :size => "16x16") # => + # + # video_tag("/trailers/hd.avi", :height => '32', :width => '32') # => + # + # video_tag(["trailer.ogg", "trailer.flv"]) # => + # + # video_tag(["trailer.ogg", "trailer.flv"] :size => "160x120") # => + # + def video_tag(sources, options = {}) + options.symbolize_keys! + + options[:poster] = path_to_image(options[:poster]) if options[:poster] + + if size = options.delete(:size) + options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$} + end + + if sources.is_a?(Array) + content_tag("video", options) do + sources.map { |source| tag("source", :src => source) }.join + end + else + options[:src] = path_to_video(sources) + tag("video", options) + end + end + def self.cache_asset_timestamps @@cache_asset_timestamps end diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 8ecec87b10a6de97cc5b533f7649003fb8c379ef..6d6d62393831bbbd9a057143fe6bdfa2ea5a132e 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -926,6 +926,7 @@ class FormBuilder #:nodoc: attr_accessor :object_name, :object, :options def initialize(object_name, object, template, options, proc) + @nested_child_index = {} @object_name, @object, @template, @options, @proc = object_name, object, template, options, proc @default_options = @options ? @options.slice(:index) : {} if @object_name.to_s.match(/\[\]$/) @@ -1028,7 +1029,7 @@ def fields_for_with_nested_attributes(association_name, args, block) explicit_child_index = args.last[:child_index] if args.last.is_a?(Hash) children.map do |child| - fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index}]", child, args, block) + fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, args, block) end.join else fields_for_nested_model(name, explicit_object || association, args, block) @@ -1046,9 +1047,9 @@ def fields_for_nested_model(name, object, args, block) end end - def nested_child_index - @nested_child_index ||= -1 - @nested_child_index += 1 + def nested_child_index(name) + @nested_child_index[name] ||= -1 + @nested_child_index[name] += 1 end end end @@ -1056,5 +1057,6 @@ def nested_child_index class << Base attr_accessor :default_form_builder end + Base.default_form_builder = ::ActionView::Helpers::FormBuilder end diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 66d75928742668f426b1ae5e31d5496b02bae689..9b6e9d201f6ebe9a23969aa7517d680ea3fc0d75 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -8,7 +8,8 @@ module Helpers #:nodoc: module TagHelper include ERB::Util - BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked).to_set + BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer + autoplay controls loop).to_set BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attr| attr.to_sym }) # Returns an empty HTML tag of type +name+ which by default is XHTML diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 16d7df48431847bb5a00aee29dd1cedddc000216..fb83dba3954f7d23bb68178b77dd7c6253332296 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -2492,6 +2492,16 @@ def test_route_requirement_recognize_with_xi_modifiers end assert_equal({:controller => 'pages', :action => 'show', :name => 'JAMIS'}, set.recognize_path('/page/JAMIS')) end + + def test_routes_with_symbols + set.draw do |map| + map.connect 'unnamed', :controller => :pages, :action => :show, :name => :as_symbol + map.named 'named', :controller => :pages, :action => :show, :name => :as_symbol + end + assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/unnamed')) + assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/named')) + end + end class RouteLoadingTest < Test::Unit::TestCase diff --git a/actionpack/test/template/active_record_helper_test.rb b/actionpack/test/template/active_record_helper_test.rb index 4691049a410f2c47f5fb410455abc7295cae40c0..e1be0488385dbf93d4040c65b58358b178db2a20 100644 --- a/actionpack/test/template/active_record_helper_test.rb +++ b/actionpack/test/template/active_record_helper_test.rb @@ -171,7 +171,7 @@ def test_form_with_protect_against_forgery @request_forgery_protection_token = 'authenticity_token' @form_authenticity_token = '123' assert_dom_equal( - %(
), + %(), form("post") ) end diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 65289a59bc50a796edd957dc40537d7fba0fb8d0..e7d70302f8d9d0856ac8309dc2245ce4c436ef0c 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -138,11 +138,38 @@ def teardown %(image_tag("error.png", "size" => "45 x 70")) => %(), %(image_tag("error.png", "size" => "x")) => %(), %(image_tag("http://www.rubyonrails.com/images/rails.png")) => %(), - %(image_tag("http://www.rubyonrails.com/images/rails.png")) => %(), %(image_tag("mouse.png", :mouseover => "/images/mouse_over.png")) => %(), %(image_tag("mouse.png", :mouseover => image_path("mouse_over.png"))) => %() } + VideoPathToTag = { + %(video_path("xml")) => %(/videos/xml), + %(video_path("xml.ogg")) => %(/videos/xml.ogg), + %(video_path("dir/xml.ogg")) => %(/videos/dir/xml.ogg), + %(video_path("/dir/xml.ogg")) => %(/dir/xml.ogg) + } + + PathToVideoToTag = { + %(path_to_video("xml")) => %(/videos/xml), + %(path_to_video("xml.ogg")) => %(/videos/xml.ogg), + %(path_to_video("dir/xml.ogg")) => %(/videos/dir/xml.ogg), + %(path_to_video("/dir/xml.ogg")) => %(/dir/xml.ogg) + } + + VideoLinkToTag = { + %(video_tag("xml.ogg")) => %(), + %(video_tag("rss.m4v", :autoplay => true, :controls => true)) => %(), + %(video_tag("rss.m4v", :autobuffer => true)) => %(), + %(video_tag("gold.m4v", :size => "160x120")) => %(), + %(video_tag("gold.m4v", "size" => "320x240")) => %(), + %(video_tag("trailer.ogg", :poster => "screenshot.png")) => %(), + %(video_tag("error.avi", "size" => "100")) => %(), + %(video_tag("error.avi", "size" => "100 x 100")) => %(), + %(video_tag("error.avi", "size" => "x")) => %(), + %(video_tag("http://media.rubyonrails.org/video/rails_blog_2.mov")) => %(), + %(video_tag(["multiple.ogg", "multiple.avi"])) => %(), + %(video_tag(["multiple.ogg", "multiple.avi"], :size => "160x120", :controls => true)) => %() + } def test_auto_discovery_link_tag AutoDiscoveryToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } @@ -272,6 +299,18 @@ def test_image_tag_windows_behaviour end end + def test_video_path + VideoPathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } + end + + def test_path_to_video_alias_for_video_path + PathToVideoToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } + end + + def test_video_tag + VideoLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } + end + def test_timebased_asset_id expected_time = File.stat(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).mtime.to_i.to_s assert_equal %(), image_tag("rails.png") @@ -284,7 +323,7 @@ def test_timebased_asset_id_with_relative_url_root ensure ActionController::Base.relative_url_root = "" end - + def test_should_skip_asset_id_on_complete_url assert_equal %(), image_tag("http://www.example.com/rails.png") end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index f8215132e34473fcac6a5c2209b0dcbd43efedac..515f73c33983e5cd5cf2795d866f3ed57f6a0d1c 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -21,6 +21,9 @@ def author_attributes=(attributes); end attr_accessor :comments def comments_attributes=(attributes); end + + attr_accessor :tags + def tags_attributes=(attributes); end end class Comment @@ -33,6 +36,50 @@ def to_param; @id; end def name @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}" end + + attr_accessor :relevances + def relevances_attributes=(attributes); end + + end + + class Tag + attr_reader :id + attr_reader :post_id + def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end + def save; @id = 1; @post_id = 1 end + def new_record?; @id.nil? end + def to_param; @id; end + def value + @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}" + end + + attr_accessor :relevances + def relevances_attributes=(attributes); end + + end + + class CommentRelevance + attr_reader :id + attr_reader :comment_id + def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end + def save; @id = 1; @comment_id = 1 end + def new_record?; @id.nil? end + def to_param; @id; end + def value + @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}" + end + end + + class TagRelevance + attr_reader :id + attr_reader :tag_id + def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end + def save; @id = 1; @tag_id = 1 end + def new_record?; @id.nil? end + def to_param; @id; end + def value + @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}" + end end class Author < Comment @@ -383,7 +430,7 @@ def test_form_for_with_method expected = "' + + assert_dom_equal expected, output_buffer + end + def test_fields_for fields_for(:post, @post) do |f| concat f.text_field(:title) @@ -1092,7 +1184,7 @@ def test_form_for_with_record_url_option def test_form_for_with_existing_object form_for(@post) do |f| end - expected = "" + expected = "" assert_equal expected, output_buffer end @@ -1113,7 +1205,7 @@ def test_form_for_with_existing_object_in_list form_for([@post, @comment]) {} - expected = %() + expected = %() assert_dom_equal expected, output_buffer end @@ -1132,7 +1224,7 @@ def test_form_for_with_existing_object_and_namespace_in_list form_for([:admin, @post, @comment]) {} - expected = %() + expected = %() assert_dom_equal expected, output_buffer end @@ -1148,7 +1240,7 @@ def test_form_for_with_new_object_and_namespace_in_list def test_form_for_with_existing_object_and_custom_url form_for(@post, :url => "/super_posts") do |f| end - expected = "" + expected = "" assert_equal expected, output_buffer end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index f387123117ffd2306a474c514dfab202b45cb880..79004264fdfb4249fb93218e662d4ed4b22b96d1 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -40,13 +40,13 @@ def test_form_tag_multipart def test_form_tag_with_method_put actual = form_tag({}, { :method => :put }) - expected = %() + expected = %() assert_dom_equal expected, output_buffer end diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 02b1d137f5a0f896e9e75f1dfd3b2f15ca141132..a7a1bc99f30f893098e5188cd2fb61ac2eee32b7 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -136,7 +136,7 @@ def test_form_remote_tag end def test_form_remote_tag_with_method - assert_dom_equal %() + expected = %() assert_dom_equal expected, output_buffer end @@ -180,7 +180,7 @@ def test_remote_form_for_with_existing_object_in_list @article.save remote_form_for([@author, @article]) {} - expected = %() + expected = %() assert_dom_equal expected, output_buffer end diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb index a33586f77fc999a17d32e71d5a7718bf68335fc5..713ae1b67114405d38f4ec5a95db0fd028df0773 100644 --- a/activesupport/lib/active_support/duration.rb +++ b/activesupport/lib/active_support/duration.rb @@ -68,10 +68,12 @@ def ago(time = ::Time.current) def inspect #:nodoc: consolidated = parts.inject(::Hash.new(0)) { |h,part| h[part.first] += part.last; h } - [:years, :months, :days, :minutes, :seconds].map do |length| + parts = [:years, :months, :days, :minutes, :seconds].map do |length| n = consolidated[length] "#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero? - end.compact.to_sentence(:locale => :en) + end.compact + parts = ["0 seconds"] if parts.empty? + parts.to_sentence(:locale => :en) end protected diff --git a/activesupport/lib/active_support/new_callbacks.rb b/activesupport/lib/active_support/new_callbacks.rb index bc340fccec765ca824a54e96b1977152c721bd89..56b510d52eda7d00830b53e98377c3e2d4f8e6fe 100644 --- a/activesupport/lib/active_support/new_callbacks.rb +++ b/activesupport/lib/active_support/new_callbacks.rb @@ -202,7 +202,7 @@ def start(key = nil, options = {}) # end name = "_conditional_callback_#{@kind}_#{next_id}" - txt, line = <<-RUBY_EVAL, __LINE__ + txt, line = <<-RUBY_EVAL, __LINE__ + 1 def #{name}(halted) #{@compiled_options[0] || "if true"} && !halted #{@filter} do diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb index 8d1c0f51601e920553b5d68a18576dd0172c584d..4324e40cbb1ebf812b02a7d44fa56cb6875817d7 100644 --- a/activesupport/lib/active_support/ordered_hash.rb +++ b/activesupport/lib/active_support/ordered_hash.rb @@ -12,11 +12,25 @@ def initialize(*args, &block) def self.[](*args) ordered_hash = new - args.each_with_index { |val,ind| - # Only every second value is a key. - next if ind % 2 != 0 + + if (args.length == 1 && args.first.is_a?(Array)) + args.first.each do |key_value_pair| + next unless (key_value_pair.is_a?(Array)) + ordered_hash[key_value_pair[0]] = key_value_pair[1] + end + + return ordered_hash + end + + unless (args.size % 2 == 0) + raise ArgumentError.new("odd number of arguments for Hash") + end + + args.each_with_index do |val, ind| + next if (ind % 2 != 0) ordered_hash[val] = args[ind + 1] - } + end + ordered_hash end diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb index 090e0c5c89a171f5e4af2b2078b5bc2dfd0744cb..dd13abcd5d96a6b5c883fdd0b8388291d9ede11e 100644 --- a/activesupport/lib/active_support/testing/isolation.rb +++ b/activesupport/lib/active_support/testing/isolation.rb @@ -21,6 +21,11 @@ def self.forking_env? end def run(result) + unless defined?(@@ran_class_setup) + self.class.setup + @@ran_class_setup = true + end + yield(Test::Unit::TestCase::STARTED, name) @_result = result diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb index 6f16621ae5ee4addd544debad705a52e3f7d938f..42b4f10172accde187a6e3e46e130ca1da844fe1 100644 --- a/activesupport/test/core_ext/duration_test.rb +++ b/activesupport/test/core_ext/duration_test.rb @@ -3,6 +3,7 @@ class DurationTest < ActiveSupport::TestCase def test_inspect + assert_equal '0 seconds', 0.seconds.inspect assert_equal '1 month', 1.month.inspect assert_equal '1 month and 1 day', (1.month + 1.day).inspect assert_equal '6 months and -2 days', (6.months - 2.days).inspect diff --git a/activesupport/test/isolation_test.rb b/activesupport/test/isolation_test.rb index b844bbb673daa0812b510a5df0718a7803bd6c43..5a1f2854764f3986d63e8bac5dc017b2659a9198 100644 --- a/activesupport/test/isolation_test.rb +++ b/activesupport/test/isolation_test.rb @@ -5,6 +5,12 @@ class ChildIsolationTest < ActiveSupport::TestCase include ActiveSupport::Testing::Isolation + def self.setup + File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "a") do |f| + f.puts "hello" + end + end + def setup @instance = "HELLO" end @@ -64,6 +70,8 @@ def teardown else class ParentIsolationTest < ActiveSupport::TestCase + File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "w") {} + ENV["CHILD"] = "1" OUTPUT = `#{Gem.ruby} -I#{File.dirname(__FILE__)} #{File.expand_path(__FILE__)} -v` ENV.delete("CHILD") @@ -131,12 +139,17 @@ def assert_erroring(name) test "backtrace is printed for errors" do assert_equal 'Error', @backtraces["test_captures_errors"][:type] - assert_match %{isolation_test.rb:21:in `test_captures_errors'}, @backtraces["test_captures_errors"][:output] + assert_match %r{isolation_test.rb:\d+:in `test_captures_errors'}, @backtraces["test_captures_errors"][:output] end test "backtrace is printed for failures" do assert_equal 'Failure', @backtraces["test_captures_failures"][:type] - assert_match %{isolation_test.rb:25:in `test_captures_failures'}, @backtraces["test_captures_failures"][:output] + assert_match %r{isolation_test.rb:\d+:in `test_captures_failures'}, @backtraces["test_captures_failures"][:output] + end + + test "self.setup is run only once" do + text = File.read(File.join(File.dirname(__FILE__), "fixtures", "isolation_test")) + assert_equal "hello\n", text end end diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb index 647938dd87ae629d576901911db61343b68adf99..15bd57181f802bbe012d95ea83161e34d8364304 100644 --- a/activesupport/test/ordered_hash_test.rb +++ b/activesupport/test/ordered_hash_test.rb @@ -163,9 +163,32 @@ def test_inspect assert @ordered_hash.inspect.include?(@hash.inspect) end - def test_alternate_initialization + def test_alternate_initialization_with_splat alternate = ActiveSupport::OrderedHash[1,2,3,4] assert_kind_of ActiveSupport::OrderedHash, alternate assert_equal [1, 3], alternate.keys end + + def test_alternate_initialization_with_array + alternate = ActiveSupport::OrderedHash[ [ + [1, 2], + [3, 4], + "bad key value pair", + [ 'missing value' ] + ]] + + assert_kind_of ActiveSupport::OrderedHash, alternate + assert_equal [1, 3, 'missing value'], alternate.keys + assert_equal [2, 4, nil ], alternate.values + end + + def test_alternate_initialization_raises_exception_on_odd_length_args + begin + alternate = ActiveSupport::OrderedHash[1,2,3,4,5] + flunk "Hash::[] should have raised an exception on initialization " + + "with an odd number of parameters" + rescue + assert_equal "odd number of arguments for Hash", $!.message + end + end end diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb index cd23158e98767d7f3e23eba09879f1b8c12e7e95..560105670fd3d4ce4959e0c759162a1ce6211508 100644 --- a/railties/lib/initializer.rb +++ b/railties/lib/initializer.rb @@ -125,11 +125,8 @@ def self.run(initializer = nil, config = nil) if Rails.vendor_rails? begin; require "rubygems"; rescue LoadError; return; end - stubs = %w(rails activesupport activerecord actionpack actionmailer activeresource) - stubs.reject! { |s| Gem.loaded_specs.key?(s) } - - stubs.each do |stub| - Gem.loaded_specs[stub] = Gem::Specification.new do |s| + %w(rails activesupport activerecord actionpack actionmailer activeresource).each do |stub| + Gem.loaded_specs[stub] ||= Gem::Specification.new do |s| s.name = stub s.version = Rails::VERSION::STRING s.loaded_from = "" diff --git a/railties/lib/rails/gem_dependency.rb b/railties/lib/rails/gem_dependency.rb index 3cc75494e4bb7aed4bf1f1370d95d75bbba9618c..06d830ba24ae46c27cc638d3601c0ac172ac5822 100644 --- a/railties/lib/rails/gem_dependency.rb +++ b/railties/lib/rails/gem_dependency.rb @@ -122,10 +122,14 @@ def requirement def built? return false unless frozen? - specification.extensions.each do |ext| - makefile = File.join(unpacked_gem_directory, File.dirname(ext), 'Makefile') - return false unless File.exists?(makefile) + + if vendor_gem? + specification.extensions.each do |ext| + makefile = File.join(unpacked_gem_directory, File.dirname(ext), 'Makefile') + return false unless File.exists?(makefile) + end end + true end diff --git a/railties/test/gem_dependency_test.rb b/railties/test/gem_dependency_test.rb index 70f449668527ad8c42e16688ab25a8b624ad1006..92132be992096e4319f8fb1b33ac55271168a222 100644 --- a/railties/test/gem_dependency_test.rb +++ b/railties/test/gem_dependency_test.rb @@ -199,6 +199,15 @@ def test_gem_determines_build_status assert_equal true, Rails::GemDependency.new("dummy-gem-i").built? assert_equal false, Rails::GemDependency.new("dummy-gem-j").built? end + + def test_gem_determines_build_status_only_on_vendor_gems + framework_gem = Rails::GemDependency.new('dummy-framework-gem') + framework_gem.stubs(:framework_gem?).returns(true) # already loaded + framework_gem.stubs(:vendor_rails?).returns(false) # but not in vendor/rails + framework_gem.stubs(:vendor_gem?).returns(false) # and not in vendor/gems + framework_gem.add_load_paths # freeze framework gem early + assert framework_gem.built? + end def test_gem_build_passes_options_to_dependencies start_gem = Rails::GemDependency.new("dummy-gem-g") diff --git a/railties/test/initializer/check_ruby_version_test.rb b/railties/test/initializer/check_ruby_version_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..33de6539068d52d2c40bd5654568d27848a3b465 --- /dev/null +++ b/railties/test/initializer/check_ruby_version_test.rb @@ -0,0 +1,51 @@ +require "initializer/test_helper" + +module InitializerTests + class PathsTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + test "rails does not initialize with ruby version 1.8.1" do + assert_rails_does_not_boot "1.8.1" + end + + test "rails initializes with ruby version 1.8.2" do + assert_rails_boots "1.8.2" + end + + test "rails does not initialize with ruby version 1.8.3" do + assert_rails_does_not_boot "1.8.3" + end + + test "rails initializes with ruby version 1.8.4" do + assert_rails_boots "1.8.4" + end + + test "rails initializes with ruby version 1.8.5" do + assert_rails_boots "1.8.5" + end + + test "rails initializes with ruby version 1.8.6" do + assert_rails_boots "1.8.6" + end + + def set_ruby_version(version) + $-w = nil + Object.const_set(:RUBY_VERSION, version.freeze) + end + + def assert_rails_boots(version) + set_ruby_version(version) + assert_nothing_raised "It appears that rails does not boot" do + Rails::Initializer.run { |c| c.frameworks = [] } + end + end + + def assert_rails_does_not_boot(version) + set_ruby_version(version) + $stderr = File.open("/dev/null", "w") + assert_raises(SystemExit) do + Rails::Initializer.run { |c| c.frameworks = [] } + end + end + end +end diff --git a/railties/test/initializer/install_gem_spec_stubs_test.rb b/railties/test/initializer/install_gem_spec_stubs_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..2e94c9968fdc2b4791c7d7ded85d005094f192ea --- /dev/null +++ b/railties/test/initializer/install_gem_spec_stubs_test.rb @@ -0,0 +1,85 @@ +require "initializer/test_helper" + +module InitializerTests + class GemSpecStubsTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + def setup + $stderr = StringIO.new + end + + test "user has an old boot.rb (defined by having no Rails.vendor_rails?)" do + class << Rails + undef vendor_rails? + end + + assert_stderr(/outdated/) do + assert_raises(SystemExit) do + Rails::Initializer.run { |c| c.frameworks = [] } + end + end + end + + test "requires rubygems" do + Kernel.module_eval do + alias old_require require + def require(name) + $rubygems_required = true if name == "rubygems" + old_require(name) + end + end + + Rails.vendor_rails = true + Rails::Initializer.run { |c| c.frameworks = [] } + assert $rubygems_required + end + + test "does not fail if rubygems does not exist" do + Kernel.module_eval do + alias old_require require + def require(name) + raise LoadError if name == "rubygems" + old_require(name) + end + end + + assert_nothing_raised do + Rails::Initializer.run { |c| c.frameworks = [] } + end + end + + test "adds fake Rubygems stubs if a framework is not loaded in Rubygems and we've vendored" do + Rails.vendor_rails = true + + Rails::Initializer.run { |c| c.frameworks = [] } + + %w(rails activesupport activerecord actionpack actionmailer activeresource).each do |stub| + gem_spec = Gem.loaded_specs[stub] + assert_equal Gem::Version.new(Rails::VERSION::STRING), gem_spec.version + assert_equal stub, gem_spec.name + assert_equal "", gem_spec.loaded_from + end + end + + test "doesn't replace gem specs that are already loaded" do + Rails.vendor_rails = true + + Gem.loaded_specs["rails"] = Gem::Specification.new do |s| + s.name = "rails" + s.version = Rails::VERSION::STRING + s.loaded_from = "/foo/bar/baz" + end + + Rails::Initializer.run { |c| c.frameworks = [] } + + assert_equal "/foo/bar/baz", Gem.loaded_specs["rails"].loaded_from + + %w(activesupport activerecord actionpack actionmailer activeresource).each do |stub| + gem_spec = Gem.loaded_specs[stub] + assert_equal Gem::Version.new(Rails::VERSION::STRING), gem_spec.version + assert_equal stub, gem_spec.name + assert_equal "", gem_spec.loaded_from + end + end + end +end \ No newline at end of file diff --git a/railties/test/initializer/path_test.rb b/railties/test/initializer/path_test.rb index 8fbad24a739689736538c0fe6a43515bf3c569a6..26f796f93df94f183a837b5cbfc074f6e55599cf 100644 --- a/railties/test/initializer/path_test.rb +++ b/railties/test/initializer/path_test.rb @@ -1,21 +1,14 @@ -require 'abstract_unit' -require 'active_support/ruby/shim' -require 'initializer' - -RAILS_ROOT.replace File.join(File.dirname(__FILE__), "root") - -module Rails - def self.vendor_rails? ; false ; end -end - -# TODO: Can this be reset? -Rails::Initializer.run do |config| - config.frameworks = [:action_controller, :action_view, :action_mailer, :active_record] -end +require "initializer/test_helper" class PathsTest < ActiveSupport::TestCase include ActiveSupport::Testing::Isolation + def self.setup + Rails::Initializer.run do |config| + config.frameworks = [:action_controller, :action_view, :action_mailer, :active_record] + end + end + def setup @paths = Rails::Initializer.default.config.paths end diff --git a/railties/test/initializer/test_helper.rb b/railties/test/initializer/test_helper.rb new file mode 100644 index 0000000000000000000000000000000000000000..ddb03397abf900b61f2be337a2deca48376d04db --- /dev/null +++ b/railties/test/initializer/test_helper.rb @@ -0,0 +1,24 @@ +require 'abstract_unit' +require 'active_support/ruby/shim' +require 'initializer' + +RAILS_ROOT.replace File.join(File.dirname(__FILE__), "root") + +module Rails + class << self + attr_accessor :vendor_rails + def vendor_rails?() @vendor_rails end + end +end + +class ActiveSupport::TestCase + def assert_stderr(match) + $stderr = StringIO.new + yield + $stderr.rewind + err = $stderr.read + assert_match match, err + ensure + $stderr = STDERR + end +end \ No newline at end of file diff --git a/railties/test/initializer_test.rb b/railties/test/initializer_test.rb index 5caa5858a44f602e82d3ce1ff260f9e24ddab2ea..550cb7de7687fcea88dbf1a0e4afbcf332de3b7e 100644 --- a/railties/test/initializer_test.rb +++ b/railties/test/initializer_test.rb @@ -178,7 +178,7 @@ def assert_framework_path(path) end end -require File.dirname(__FILE__) + '/plugin_test_helper' +require 'plugin_test_helper' class InitializerPluginLoadingTests < Test::Unit::TestCase def setup diff --git a/railties/test/plugin_test_helper.rb b/railties/test/plugin_test_helper.rb index 55d1a1fa96a682bac24b8500af41f4a37a133417..893095fa662d38c08c73116a7f00583a811feb51 100644 --- a/railties/test/plugin_test_helper.rb +++ b/railties/test/plugin_test_helper.rb @@ -4,7 +4,7 @@ require 'test/unit' require 'active_support' require 'initializer' -require File.join(File.dirname(__FILE__), 'abstract_unit') +require 'abstract_unit' # We need to set RAILS_ROOT if it isn't already set RAILS_ROOT = '.' unless defined?(RAILS_ROOT)