diff options
-rw-r--r-- | Gemfile | 3 | ||||
-rw-r--r-- | actionpack/test/controller/routing_test.rb | 14 | ||||
-rwxr-xr-x | activerecord/lib/active_record/associations.rb | 10 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb | 14 | ||||
-rw-r--r-- | activerecord/test/cases/associations/habtm_join_table_test.rb | 16 | ||||
-rw-r--r-- | activerecord/test/fixtures/edges.yml | 3 | ||||
-rw-r--r-- | activerecord/test/schema/schema.rb | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/logger.rb | 4 | ||||
-rw-r--r-- | activesupport/lib/active_support/notifications.rb | 92 | ||||
-rw-r--r-- | activesupport/test/notifications_test.rb | 17 | ||||
-rw-r--r-- | railties/CHANGELOG | 2 | ||||
-rw-r--r-- | railties/lib/rails/generators.rb | 34 | ||||
-rw-r--r-- | railties/lib/rails/rack/debugger.rb | 2 | ||||
-rw-r--r-- | railties/test/fixtures/vendor/plugins/mspec/lib/rails_generators/mspec_generator.rb (renamed from railties/test/fixtures/vendor/plugins/mspec/lib/generators/mspec_generator.rb) | 0 | ||||
-rw-r--r-- | railties/test/generators_test.rb | 7 |
15 files changed, 118 insertions, 102 deletions
@@ -1,6 +1,3 @@ -clear_sources -source 'http://gemcutter.org' - gem "rake", ">= 0.8.7" gem "mocha", ">= 0.9.8" diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 6984ca9564..4eaf309c41 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -1419,15 +1419,13 @@ class RouteSetTest < ActiveSupport::TestCase :requirements => {:name => /(david|jamis)/i} end - pending do - url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'}) - assert_equal "/page/david", url - assert_raise ActionController::RoutingError do - url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'}) - end - url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'}) - assert_equal "/page/JAMIS", url + url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'}) + assert_equal "/page/david", url + assert_raise ActionController::RoutingError do + url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'}) end + url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'}) + assert_equal "/page/JAMIS", url end def test_route_requirement_recognize_with_extended_syntax diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index fc6f15206a..0fcd288fc5 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -61,6 +61,12 @@ module ActiveRecord end end + class HasAndBelongsToManyAssociationWithPrimaryKeyError < ActiveRecordError #:nodoc: + def initialize(reflection) + super("Primary key is not allowed in a has_and_belongs_to_many join table (#{reflection.options[:join_table]}).") + end + end + class HasAndBelongsToManyAssociationForeignKeyNeeded < ActiveRecordError #:nodoc: def initialize(reflection) super("Cannot create self referential has_and_belongs_to_many association on '#{reflection.class_name rescue nil}##{reflection.name rescue nil}'. :association_foreign_key cannot be the same as the :foreign_key.") @@ -1675,7 +1681,6 @@ module ActiveRecord def create_has_and_belongs_to_many_reflection(association_id, options, &extension) options.assert_valid_keys(valid_keys_for_has_and_belongs_to_many_association) - options[:extend] = create_extension_modules(association_id, extension, options[:extend]) reflection = create_reflection(:has_and_belongs_to_many, association_id, options, self) @@ -1685,6 +1690,9 @@ module ActiveRecord end reflection.options[:join_table] ||= join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(reflection.class_name)) + if connection.supports_primary_key? && (connection.primary_key(reflection.options[:join_table]) rescue false) + raise HasAndBelongsToManyAssociationWithPrimaryKeyError.new(reflection) + end reflection end diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index c646fe488b..b01faa5212 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -1,11 +1,6 @@ module ActiveRecord module Associations class HasAndBelongsToManyAssociation < AssociationCollection #:nodoc: - def initialize(owner, reflection) - super - @primary_key_list = {} - end - def create(attributes = {}) create_record(attributes) { |record| insert_record(record) } end @@ -23,9 +18,7 @@ module ActiveRecord end def has_primary_key? - return @has_primary_key unless @has_primary_key.nil? - @has_primary_key = (@owner.connection.supports_primary_key? && - @owner.connection.primary_key(@reflection.options[:join_table])) + @has_primary_key ||= @owner.connection.supports_primary_key? && @owner.connection.primary_key(@reflection.options[:join_table]) end protected @@ -40,11 +33,6 @@ module ActiveRecord end def insert_record(record, force = true, validate = true) - if has_primary_key? - raise ActiveRecord::ConfigurationError, - "Primary key is not allowed in a has_and_belongs_to_many join table (#{@reflection.options[:join_table]})." - end - if record.new_record? if force record.save! diff --git a/activerecord/test/cases/associations/habtm_join_table_test.rb b/activerecord/test/cases/associations/habtm_join_table_test.rb index bf3e04c3eb..745f169ad7 100644 --- a/activerecord/test/cases/associations/habtm_join_table_test.rb +++ b/activerecord/test/cases/associations/habtm_join_table_test.rb @@ -36,21 +36,9 @@ class HabtmJoinTableTest < ActiveRecord::TestCase uses_transaction :test_should_raise_exception_when_join_table_has_a_primary_key def test_should_raise_exception_when_join_table_has_a_primary_key if ActiveRecord::Base.connection.supports_primary_key? - assert_raise ActiveRecord::ConfigurationError do - jaime = MyReader.create(:name=>"Jaime") - jaime.my_books << MyBook.create(:name=>'Great Expectations') + assert_raise ActiveRecord::HasAndBelongsToManyAssociationWithPrimaryKeyError do + MyReader.has_and_belongs_to_many :my_books end end end - - uses_transaction :test_should_cache_result_of_primary_key_check - def test_should_cache_result_of_primary_key_check - if ActiveRecord::Base.connection.supports_primary_key? - ActiveRecord::Base.connection.stubs(:primary_key).with('my_books_my_readers').returns(false).once - weaz = MyReader.create(:name=>'Weaz') - - weaz.my_books << MyBook.create(:name=>'Great Expectations') - weaz.my_books << MyBook.create(:name=>'Greater Expectations') - end - end end diff --git a/activerecord/test/fixtures/edges.yml b/activerecord/test/fixtures/edges.yml index c16c70dd2f..b804f7b6a6 100644 --- a/activerecord/test/fixtures/edges.yml +++ b/activerecord/test/fixtures/edges.yml @@ -1,6 +1,5 @@ <% (1..4).each do |id| %> edge_<%= id %>: - id: <%= id %> source_id: <%= id %> sink_id: <%= id + 1 %> -<% end %>
\ No newline at end of file +<% end %> diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 15e5e12d03..0dd9da4c11 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -160,7 +160,7 @@ ActiveRecord::Schema.define do t.integer :access_level, :default => 1 end - create_table :edges, :force => true do |t| + create_table :edges, :force => true, :id => false do |t| t.column :source_id, :integer, :null => false t.column :sink_id, :integer, :null => false end diff --git a/activesupport/lib/active_support/core_ext/logger.rb b/activesupport/lib/active_support/core_ext/logger.rb index 22749229a3..e4df8fe338 100644 --- a/activesupport/lib/active_support/core_ext/logger.rb +++ b/activesupport/lib/active_support/core_ext/logger.rb @@ -137,10 +137,10 @@ class Logger attr_writer :formatter public :formatter= - alias old_format_datetime format_datetime + alias old_format_datetime format_datetime if method_defined?(:format_datetime) def format_datetime(datetime) datetime end - alias old_msg2str msg2str + alias old_msg2str msg2str if method_defined?(:msg2str) def msg2str(msg) msg end end end diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb index 7a9f76b26a..e2540cd598 100644 --- a/activesupport/lib/active_support/notifications.rb +++ b/activesupport/lib/active_support/notifications.rb @@ -41,7 +41,7 @@ module ActiveSupport # to subscribers in a thread. You can use any queue implementation you want. # module Notifications - mattr_accessor :queue + mattr_accessor :queue, :listener class << self delegate :instrument, :transaction_id, :transaction, :to => :instrumenter @@ -54,8 +54,13 @@ module ActiveSupport @publisher ||= Publisher.new(queue) end - def subscribe(pattern=nil, &block) - Subscriber.new(queue).bind(pattern).subscribe(&block) + def subscriber + @subscriber ||= Subscriber.new(queue) + end + + def subscribe(pattern=nil, options={}, &block) + with = options[:with] || listener + subscriber.bind(with, pattern).subscribe(&block) end end @@ -104,13 +109,14 @@ module ActiveSupport @queue = queue end - def bind(pattern) - @pattern = pattern + def bind(listener, pattern) + @listener = listener + @pattern = pattern self end def subscribe - @queue.subscribe(@pattern) do |*args| + @queue.subscribe(@listener, @pattern) do |*args| yield(*args) end end @@ -138,6 +144,48 @@ module ActiveSupport end end + class AsyncListener + def initialize(pattern, &block) + @pattern = pattern + @subscriber = block + @queue = Queue.new + Thread.new { consume } + end + + def publish(name, *args) + if !@pattern || @pattern === name.to_s + @queue << args.unshift(name) + end + end + + def consume + while args = @queue.shift + @subscriber.call(*args) + end + end + + def drained? + @queue.size.zero? + end + end + + class SyncListener + def initialize(pattern, &block) + @pattern = pattern + @subscriber = block + end + + def publish(name, *args) + if !@pattern || @pattern === name.to_s + @subscriber.call(*args.unshift(name)) + end + end + + def drained? + true + end + end + # This is a default queue implementation that ships with Notifications. It # consumes events in a thread and publish them to all registered subscribers. # @@ -150,40 +198,16 @@ module ActiveSupport @listeners.each { |l| l.publish(*args) } end - def subscribe(pattern=nil, &block) - @listeners << Listener.new(pattern, &block) + def subscribe(listener, pattern=nil, &block) + @listeners << listener.new(pattern, &block) end def drained? @listeners.all? &:drained? end - - class Listener - def initialize(pattern, &block) - @pattern = pattern - @subscriber = block - @queue = Queue.new - Thread.new { consume } - end - - def publish(name, *args) - if !@pattern || @pattern === name.to_s - @queue << args.unshift(name) - end - end - - def consume - while args = @queue.shift - @subscriber.call(*args) - end - end - - def drained? - @queue.size.zero? - end - end end end - Notifications.queue = Notifications::LittleFanout.new + Notifications.queue = Notifications::LittleFanout.new + Notifications.listener = Notifications::AsyncListener end diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb index 01106e83e9..35d44367cf 100644 --- a/activesupport/test/notifications_test.rb +++ b/activesupport/test/notifications_test.rb @@ -176,6 +176,21 @@ class NotificationsMainTest < Test::Unit::TestCase assert_equal 1, @another.first.result end + def test_subscriber_allows_sync_listeners + @another = [] + ActiveSupport::Notifications.subscribe(/cache/, :with => ActiveSupport::Notifications::SyncListener) do |*args| + @another << ActiveSupport::Notifications::Event.new(*args) + end + + Thread.expects(:new).never + ActiveSupport::Notifications.instrument(:something){ 0 } + ActiveSupport::Notifications.instrument(:cache){ 1 } + + assert_equal 1, @another.size + assert_equal :cache, @another.first.name + assert_equal 1, @another.first.result + end + def test_with_several_consumers_and_several_events @another = [] ActiveSupport::Notifications.subscribe do |*args| @@ -201,6 +216,6 @@ class NotificationsMainTest < Test::Unit::TestCase private def drain - sleep(0.1) until ActiveSupport::Notifications.queue.drained? + sleep(0.05) until ActiveSupport::Notifications.queue.drained? end end diff --git a/railties/CHANGELOG b/railties/CHANGELOG index d6311f77a0..66e0d5e9c5 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Fixed that the debugger wouldn't go into IRB mode because of left-over ARGVs [DHH] + * I18n support for plugins. #2325 [Antonio Tapiador, Sven Fuchs] * Ruby 1.9: use UTF-8 for default internal and external encodings. [Jeremy Kemper] diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index 19412c259e..85c2fd52a4 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -86,28 +86,16 @@ module Rails @options ||= DEFAULT_OPTIONS.dup end - # We have two scenarios here: when rubygems is loaded and when bundler is - # being used. If rubygems is loaded, we get all generators paths from loaded - # specs. Otherwise we just have to look into vendor/gems/gems. - # - def self.gems_generators_paths - paths = [] - - if defined?(Gem) && Gem.respond_to?(:loaded_specs) - Gem.loaded_specs.each do |name, spec| - generator_path = File.join(spec.full_gem_path, "lib/generators") - paths << generator_path if File.exist?(generator_path) - end + def self.gems_generators_paths #:nodoc: + return [] unless defined?(Gem) && Gem.respond_to?(:loaded_specs) + Gem.loaded_specs.inject([]) do |paths, (name, spec)| + paths += Dir[File.join(spec.full_gem_path, "lib/{generators,rails_generators}")] end - - paths end - # Load paths from plugin. - # - def self.plugins_generators_paths + def self.plugins_generators_paths #:nodoc: return [] unless Rails.root - Dir[File.join(Rails.root, "vendor", "plugins", "*", "lib", "generators")] + Dir[File.join(Rails.root, "vendor", "plugins", "*", "lib", "{generators,rails_generators}")] end # Hold configured generators fallbacks. If a plugin developer wants a @@ -147,8 +135,8 @@ module Rails def self.load_paths @load_paths ||= begin paths = [] - paths << File.join(Rails.root, "lib", "generators") if Rails.root - paths << File.join(Thor::Util.user_home, ".rails", "generators") + paths += Dir[File.join(Rails.root, "lib", "{generators,rails_generators}")] if Rails.root + paths += Dir[File.join(Thor::Util.user_home, ".rails", "{generators,rails_generators}")] paths += self.plugins_generators_paths paths += self.gems_generators_paths paths << File.expand_path(File.join(File.dirname(__FILE__), "generators")) @@ -210,7 +198,7 @@ module Rails return klass if klass end - invoke_fallbacks_for(name, base) + invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name) end # Receives a namespace, arguments and the behavior to invoke the generator. @@ -278,13 +266,13 @@ module Rails # By default, Rails strips the generator namespace to make invocations # easier. This method generaters the both possibilities names. - def self.generator_names(first, second) + def self.generator_names(first, second) #:nodoc: [ "#{first}:generators:#{second}", "#{first}:#{second}" ] end # Try callbacks for the given base. # - def self.invoke_fallbacks_for(name, base) + def self.invoke_fallbacks_for(name, base) #:nodoc: return nil unless base && fallbacks[base.to_sym] invoked_fallbacks = [] diff --git a/railties/lib/rails/rack/debugger.rb b/railties/lib/rails/rack/debugger.rb index aa2711c616..0a7b405553 100644 --- a/railties/lib/rails/rack/debugger.rb +++ b/railties/lib/rails/rack/debugger.rb @@ -4,6 +4,8 @@ module Rails def initialize(app) @app = app + ARGV.clear # clear ARGV so that script/server options aren't passed to IRB + require_library_or_gem 'ruby-debug' ::Debugger.start ::Debugger.settings[:autoeval] = true if ::Debugger.respond_to?(:settings) diff --git a/railties/test/fixtures/vendor/plugins/mspec/lib/generators/mspec_generator.rb b/railties/test/fixtures/vendor/plugins/mspec/lib/rails_generators/mspec_generator.rb index 191bdbf2fc..191bdbf2fc 100644 --- a/railties/test/fixtures/vendor/plugins/mspec/lib/generators/mspec_generator.rb +++ b/railties/test/fixtures/vendor/plugins/mspec/lib/rails_generators/mspec_generator.rb diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb index a8716d9992..4b7b80c7f5 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -150,6 +150,13 @@ class GeneratorsTest < GeneratorsTestCase assert_equal "test_unit:generators:plugin", klass.namespace end + def test_fallbacks_for_generators_on_find_by_namespace_with_context + Rails::Generators.fallbacks[:remarkable] = :test_unit + klass = Rails::Generators.find_by_namespace(:remarkable, :rails, :plugin) + assert klass + assert_equal "test_unit:generators:plugin", klass.namespace + end + def test_fallbacks_for_generators_on_invoke Rails::Generators.fallbacks[:shoulda] = :test_unit TestUnit::Generators::ModelGenerator.expects(:start).with(["Account"], {}) |