diff options
Diffstat (limited to 'activesupport/test/core_ext/module_test.rb')
-rw-r--r-- | activesupport/test/core_ext/module_test.rb | 419 |
1 files changed, 151 insertions, 268 deletions
diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb index ae4aed0554..e918823074 100644 --- a/activesupport/test/core_ext/module_test.rb +++ b/activesupport/test/core_ext/module_test.rb @@ -1,74 +1,63 @@ -require 'abstract_unit' -require 'active_support/core_ext/module' +# frozen_string_literal: true -module One - Constant1 = "Hello World" - Constant2 = "What's up?" -end - -class Ab - include One - Constant1 = "Hello World" # Will have different object id than One::Constant1 - Constant3 = "Goodbye World" -end - -module Yz - module Zy - class Cd - include One - end - end -end +require "abstract_unit" +require "active_support/core_ext/module" Somewhere = Struct.new(:street, :city) do attr_accessor :name end -class Someone < Struct.new(:name, :place) - delegate :street, :city, :to_f, :to => :place - delegate :name=, :to => :place, :prefix => true - delegate :upcase, :to => "place.city" - delegate :table_name, :to => :class - delegate :table_name, :to => :class, :prefix => true +Someone = Struct.new(:name, :place) do + delegate :street, :city, :to_f, to: :place + delegate :name=, to: :place, prefix: true + delegate :upcase, to: "place.city" + delegate :table_name, to: :class + delegate :table_name, to: :class, prefix: true def self.table_name - 'some_table' + "some_table" end - FAILED_DELEGATE_LINE = __LINE__ + 1 - delegate :foo, :to => :place + self::FAILED_DELEGATE_LINE = __LINE__ + 1 + delegate :foo, to: :place - FAILED_DELEGATE_LINE_2 = __LINE__ + 1 - delegate :bar, :to => :place, :allow_nil => true + self::FAILED_DELEGATE_LINE_2 = __LINE__ + 1 + delegate :bar, to: :place, allow_nil: true + + private + + def private_name + "Private" + end end -Invoice = Struct.new(:client) do - delegate :street, :city, :name, :to => :client, :prefix => true - delegate :street, :city, :name, :to => :client, :prefix => :customer +Invoice = Struct.new(:client) do + delegate :street, :city, :name, to: :client, prefix: true + delegate :street, :city, :name, to: :client, prefix: :customer end -Project = Struct.new(:description, :person) do - delegate :name, :to => :person, :allow_nil => true - delegate :to_f, :to => :description, :allow_nil => true +Project = Struct.new(:description, :person) do + delegate :name, to: :person, allow_nil: true + delegate :to_f, to: :description, allow_nil: true end Developer = Struct.new(:client) do - delegate :name, :to => :client, :prefix => nil + delegate :name, to: :client, prefix: nil end Event = Struct.new(:case) do - delegate :foo, :to => :case + delegate :foo, to: :case end Tester = Struct.new(:client) do - delegate :name, :to => :client, :prefix => false + delegate :name, to: :client, prefix: false def foo; 1; end end Product = Struct.new(:name) do - delegate :name, :to => :manufacturer, :prefix => true - delegate :name, :to => :type, :prefix => true + delegate :name, to: :manufacturer, prefix: true + delegate :name, to: :type, prefix: true def manufacturer @manufacturer ||= begin @@ -83,6 +72,36 @@ Product = Struct.new(:name) do end end +module ExtraMissing + def method_missing(sym, *args) + if sym == :extra_missing + 42 + else + super + end + end + + def respond_to_missing?(sym, priv = false) + sym == :extra_missing || super + end +end + +DecoratedTester = Struct.new(:client) do + include ExtraMissing + + delegate_missing_to :client +end + +class DecoratedReserved + delegate_missing_to :case + + attr_reader :case + + def initialize(kase) + @case = kase + end +end + class Block def hello? true @@ -94,15 +113,15 @@ HasBlock = Struct.new(:block) do end class ParameterSet - delegate :[], :[]=, :to => :@params + delegate :[], :[]=, to: :@params def initialize - @params = {:foo => "bar"} + @params = { foo: "bar" } end end class Name - delegate :upcase, :to => :@full_name + delegate :upcase, to: :@full_name def initialize(first, last) @full_name = "#{first} #{last}" @@ -112,8 +131,8 @@ end class SideEffect attr_reader :ints - delegate :to_i, :to => :shift, :allow_nil => true - delegate :to_s, :to => :shift + delegate :to_i, to: :shift, allow_nil: true + delegate :to_s, to: :shift def initialize @ints = [1, 2, 3] @@ -160,8 +179,8 @@ class ModuleTest < ActiveSupport::TestCase end def test_delegation_to_class_method - assert_equal 'some_table', @david.table_name - assert_equal 'some_table', @david.class_table_name + assert_equal "some_table", @david.table_name + assert_equal "some_table", @david.class_table_name end def test_missing_delegation_target @@ -169,27 +188,42 @@ class ModuleTest < ActiveSupport::TestCase Name.send :delegate, :nowhere end assert_raise(ArgumentError) do - Name.send :delegate, :noplace, :tos => :hollywood + Name.send :delegate, :noplace, tos: :hollywood + end + end + + def test_delegation_target_when_prefix_is_true + assert_nothing_raised do + Name.send :delegate, :go, to: :you, prefix: true + end + assert_nothing_raised do + Name.send :delegate, :go, to: :_you, prefix: true + end + assert_raise(ArgumentError) do + Name.send :delegate, :go, to: :You, prefix: true + end + assert_raise(ArgumentError) do + Name.send :delegate, :go, to: :@you, prefix: true end end def test_delegation_prefix invoice = Invoice.new(@david) - assert_equal invoice.client_name, "David" - assert_equal invoice.client_street, "Paulina" - assert_equal invoice.client_city, "Chicago" + assert_equal "David", invoice.client_name + assert_equal "Paulina", invoice.client_street + assert_equal "Chicago", invoice.client_city end def test_delegation_custom_prefix invoice = Invoice.new(@david) - assert_equal invoice.customer_name, "David" - assert_equal invoice.customer_street, "Paulina" - assert_equal invoice.customer_city, "Chicago" + assert_equal "David", invoice.customer_name + assert_equal "Paulina", invoice.customer_street + assert_equal "Chicago", invoice.customer_city end def test_delegation_prefix_with_nil_or_false - assert_equal Developer.new(@david).name, "David" - assert_equal Tester.new(@david).name, "David" + assert_equal "David", Developer.new(@david).name + assert_equal "David", Tester.new(@david).name end def test_delegation_prefix_with_instance_variable @@ -198,14 +232,14 @@ class ModuleTest < ActiveSupport::TestCase def initialize(client) @client = client end - delegate :name, :address, :to => :@client, :prefix => true + delegate :name, :address, to: :@client, prefix: true end end end def test_delegation_with_allow_nil rails = Project.new("Rails", Someone.new("David")) - assert_equal rails.name, "David" + assert_equal "David", rails.name end def test_delegation_with_allow_nil_and_nil_value @@ -226,7 +260,7 @@ class ModuleTest < ActiveSupport::TestCase def test_delegation_with_allow_nil_and_nil_value_and_prefix Project.class_eval do - delegate :name, :to => :person, :allow_nil => true, :prefix => true + delegate :name, to: :person, allow_nil: true, prefix: true end rails = Project.new("Rails") assert_nil rails.person_name @@ -255,7 +289,7 @@ class ModuleTest < ActiveSupport::TestCase assert_nothing_raised do Class.new(parent) do class << self - delegate :parent_method, :to => :superclass + delegate :parent_method, to: :superclass end end end @@ -277,7 +311,7 @@ class ModuleTest < ActiveSupport::TestCase rescue NoMethodError => e file_and_line = "#{__FILE__}:#{Someone::FAILED_DELEGATE_LINE}" # We can't simply check the first line of the backtrace, because JRuby reports the call to __send__ in the backtrace. - assert e.backtrace.any?{|a| a.include?(file_and_line)}, + assert e.backtrace.any? { |a| a.include?(file_and_line) }, "[#{e.backtrace.inspect}] did not include [#{file_and_line}]" end @@ -287,7 +321,7 @@ class ModuleTest < ActiveSupport::TestCase rescue NoMethodError => e file_and_line = "#{__FILE__}:#{Someone::FAILED_DELEGATE_LINE_2}" # We can't simply check the first line of the backtrace, because JRuby reports the call to __send__ in the backtrace. - assert e.backtrace.any?{|a| a.include?(file_and_line)}, + assert e.backtrace.any? { |a| a.include?(file_and_line) }, "[#{e.backtrace.inspect}] did not include [#{file_and_line}]" end @@ -297,12 +331,12 @@ class ModuleTest < ActiveSupport::TestCase assert_equal 1, se.to_i assert_equal [2, 3], se.ints - assert_equal '2', se.to_s + assert_equal "2", se.to_s assert_equal [3], se.ints end def test_delegation_doesnt_mask_nested_no_method_error_on_nil_receiver - product = Product.new('Widget') + product = Product.new("Widget") # Nested NoMethodError is a different name from the delegation assert_raise(NoMethodError) { product.manufacturer_name } @@ -316,245 +350,94 @@ class ModuleTest < ActiveSupport::TestCase assert has_block.hello? end - def test_parent - assert_equal Yz::Zy, Yz::Zy::Cd.parent - assert_equal Yz, Yz::Zy.parent - assert_equal Object, Yz.parent + def test_delegate_missing_to_with_method + assert_equal "David", DecoratedTester.new(@david).name end - def test_parents - assert_equal [Yz::Zy, Yz, Object], Yz::Zy::Cd.parents - assert_equal [Yz, Object], Yz::Zy.parents + def test_delegate_missing_to_with_reserved_methods + assert_equal "David", DecoratedReserved.new(@david).name end - def test_local_constants - ActiveSupport::Deprecation.silence do - assert_equal %w(Constant1 Constant3), Ab.local_constants.sort.map(&:to_s) + def test_delegate_missing_to_does_not_delegate_to_private_methods + e = assert_raises(NoMethodError) do + DecoratedReserved.new(@david).private_name end - end - def test_local_constants_is_deprecated - assert_deprecated { Ab.local_constants.sort.map(&:to_s) } + assert_match(/undefined method `private_name' for/, e.message) end -end -module BarMethodAliaser - def self.included(foo_class) - foo_class.class_eval do - include BarMethods - alias_method_chain :bar, :baz + def test_delegate_missing_to_does_not_delegate_to_fake_methods + e = assert_raises(NoMethodError) do + DecoratedReserved.new(@david).my_fake_method end - end -end - -module BarMethods - def bar_with_baz - bar_without_baz << '_with_baz' - end - - def quux_with_baz! - quux_without_baz! << '_with_baz' - end - - def quux_with_baz? - false - end - - def quux_with_baz=(v) - send(:quux_without_baz=, v) << '_with_baz' - end - - def duck_with_orange - duck_without_orange << '_with_orange' - end -end - -class MethodAliasingTest < ActiveSupport::TestCase - def setup - Object.const_set :FooClassWithBarMethod, Class.new { def bar() 'bar' end } - @instance = FooClassWithBarMethod.new - end - def teardown - Object.instance_eval { remove_const :FooClassWithBarMethod } + assert_match(/undefined method `my_fake_method' for/, e.message) end - def test_alias_method_chain_deprecated - assert_deprecated(/alias_method_chain/) do - Module.new do - def base - end - - def base_with_deprecated - end - - alias_method_chain :base, :deprecated - end + def test_delegate_missing_to_raises_delegation_error_if_target_nil + e = assert_raises(Module::DelegationError) do + DecoratedTester.new(nil).name end - end - - def test_alias_method_chain - assert_deprecated(/alias_method_chain/) do - assert @instance.respond_to?(:bar) - feature_aliases = [:bar_with_baz, :bar_without_baz] - - feature_aliases.each do |method| - assert !@instance.respond_to?(method) - end - - assert_equal 'bar', @instance.bar - - FooClassWithBarMethod.class_eval { include BarMethodAliaser } - - feature_aliases.each do |method| - assert_respond_to @instance, method - end - assert_equal 'bar_with_baz', @instance.bar - assert_equal 'bar', @instance.bar_without_baz - end + assert_equal "name delegated to client, but client is nil", e.message end - def test_alias_method_chain_with_punctuation_method - assert_deprecated(/alias_method_chain/) do - FooClassWithBarMethod.class_eval do - def quux!; 'quux' end - end + def test_delegate_missing_to_affects_respond_to + assert DecoratedTester.new(@david).respond_to?(:name) + assert_not DecoratedTester.new(@david).respond_to?(:private_name) + assert_not DecoratedTester.new(@david).respond_to?(:my_fake_method) - assert !@instance.respond_to?(:quux_with_baz!) - FooClassWithBarMethod.class_eval do - include BarMethodAliaser - alias_method_chain :quux!, :baz - end - assert_respond_to @instance, :quux_with_baz! - - assert_equal 'quux_with_baz', @instance.quux! - assert_equal 'quux', @instance.quux_without_baz! - end + assert DecoratedTester.new(@david).respond_to?(:name, true) + assert_not DecoratedTester.new(@david).respond_to?(:private_name, true) + assert_not DecoratedTester.new(@david).respond_to?(:my_fake_method, true) end - def test_alias_method_chain_with_same_names_between_predicates_and_bang_methods - assert_deprecated(/alias_method_chain/) do - FooClassWithBarMethod.class_eval do - def quux!; 'quux!' end - def quux?; true end - def quux=(v); 'quux=' end - end + def test_delegate_missing_to_respects_superclass_missing + assert_equal 42, DecoratedTester.new(@david).extra_missing - assert !@instance.respond_to?(:quux_with_baz!) - assert !@instance.respond_to?(:quux_with_baz?) - assert !@instance.respond_to?(:quux_with_baz=) - - FooClassWithBarMethod.class_eval { include BarMethodAliaser } - assert_respond_to @instance, :quux_with_baz! - assert_respond_to @instance, :quux_with_baz? - assert_respond_to @instance, :quux_with_baz= - - - FooClassWithBarMethod.alias_method_chain :quux!, :baz - assert_equal 'quux!_with_baz', @instance.quux! - assert_equal 'quux!', @instance.quux_without_baz! - - FooClassWithBarMethod.alias_method_chain :quux?, :baz - assert_equal false, @instance.quux? - assert_equal true, @instance.quux_without_baz? - - FooClassWithBarMethod.alias_method_chain :quux=, :baz - assert_equal 'quux=_with_baz', @instance.send(:quux=, 1234) - assert_equal 'quux=', @instance.send(:quux_without_baz=, 1234) - end + assert_respond_to DecoratedTester.new(@david), :extra_missing end - def test_alias_method_chain_with_feature_punctuation - assert_deprecated(/alias_method_chain/) do - FooClassWithBarMethod.class_eval do - def quux; 'quux' end - def quux?; 'quux?' end - include BarMethodAliaser - alias_method_chain :quux, :baz! - end - - assert_nothing_raised do - assert_equal 'quux_with_baz', @instance.quux_with_baz! - end - - assert_raise(NameError) do - FooClassWithBarMethod.alias_method_chain :quux?, :baz! - end - end + def test_delegate_with_case + event = Event.new(Tester.new) + assert_equal 1, event.foo end - def test_alias_method_chain_yields_target_and_punctuation - assert_deprecated(/alias_method_chain/) do - args = nil - - FooClassWithBarMethod.class_eval do - def quux?; end - include BarMethods - - FooClassWithBarMethod.alias_method_chain :quux?, :baz do |target, punctuation| - args = [target, punctuation] - end + def test_private_delegate + location = Class.new do + def initialize(place) + @place = place end - assert_not_nil args - assert_equal 'quux', args[0] - assert_equal '?', args[1] + private(*delegate(:street, :city, to: :@place)) end - end - def test_alias_method_chain_preserves_private_method_status - assert_deprecated(/alias_method_chain/) do - FooClassWithBarMethod.class_eval do - def duck; 'duck' end - include BarMethodAliaser - private :duck - alias_method_chain :duck, :orange - end + place = location.new(Somewhere.new("Such street", "Sad city")) - assert_raise NoMethodError do - @instance.duck - end + assert_not place.respond_to?(:street) + assert_not place.respond_to?(:city) - assert_equal 'duck_with_orange', @instance.instance_eval { duck } - assert FooClassWithBarMethod.private_method_defined?(:duck) - end + assert place.respond_to?(:street, true) # Asking for private method + assert place.respond_to?(:city, true) end - def test_alias_method_chain_preserves_protected_method_status - assert_deprecated(/alias_method_chain/) do - FooClassWithBarMethod.class_eval do - def duck; 'duck' end - include BarMethodAliaser - protected :duck - alias_method_chain :duck, :orange + def test_private_delegate_prefixed + location = Class.new do + def initialize(place) + @place = place end - assert_raise NoMethodError do - @instance.duck - end - - assert_equal 'duck_with_orange', @instance.instance_eval { duck } - assert FooClassWithBarMethod.protected_method_defined?(:duck) + private(*delegate(:street, :city, to: :@place, prefix: :the)) end - end - def test_alias_method_chain_preserves_public_method_status - assert_deprecated(/alias_method_chain/) do - FooClassWithBarMethod.class_eval do - def duck; 'duck' end - include BarMethodAliaser - public :duck - alias_method_chain :duck, :orange - end + place = location.new(Somewhere.new("Such street", "Sad city")) - assert_equal 'duck_with_orange', @instance.duck - assert FooClassWithBarMethod.public_method_defined?(:duck) - end - end + assert_not place.respond_to?(:street) + assert_not place.respond_to?(:city) - def test_delegate_with_case - event = Event.new(Tester.new) - assert_equal 1, event.foo + assert_not place.respond_to?(:the_street) + assert place.respond_to?(:the_street, true) + assert_not place.respond_to?(:the_city) + assert place.respond_to?(:the_city, true) end end |