diff options
Diffstat (limited to 'test/ruby/test_defined.rb')
| -rw-r--r-- | test/ruby/test_defined.rb | 301 |
1 files changed, 298 insertions, 3 deletions
diff --git a/test/ruby/test_defined.rb b/test/ruby/test_defined.rb index 84f3388e29..db1fdc8e25 100644 --- a/test/ruby/test_defined.rb +++ b/test/ruby/test_defined.rb @@ -1,5 +1,5 @@ +# frozen_string_literal: false require 'test/unit' -require_relative 'envutil' class TestDefined < Test::Unit::TestCase class Foo @@ -23,40 +23,80 @@ class TestDefined < Test::Unit::TestCase return !defined?(yield) end - def test_defined + def test_defined_global_variable $x = nil assert(defined?($x)) # global variable assert_equal('global-variable', defined?($x))# returns description + end + def test_defined_local_variable assert_nil(defined?(foo)) # undefined foo=5 assert(defined?(foo)) # local variable + end + def test_defined_constant assert(defined?(Array)) # constant assert(defined?(::Array)) # toplevel constant assert(defined?(File::Constants)) # nested constant + end + + def test_defined_public_method assert(defined?(Object.new)) # method assert(defined?(Object::new)) # method + end + + def test_defined_private_method assert(!defined?(Object.print)) # private method + end + + def test_defined_operator assert(defined?(1 == 2)) # operator expression + end + def test_defined_protected_method f = Foo.new assert_nil(defined?(f.foo)) # protected method f.bar(f) { |v| assert(v) } + f.bar(Class.new(Foo).new) { |v| assert(v, "inherited protected method") } + end + + def test_defined_undefined_method + f = Foo.new assert_nil(defined?(f.quux)) # undefined method + end + + def test_defined_undefined_argument + f = Foo.new assert_nil(defined?(f.baz(x))) # undefined argument x = 0 assert(defined?(f.baz(x))) assert_nil(defined?(f.quux(x))) assert(defined?(print(x))) assert_nil(defined?(quux(x))) + end + + def test_defined_attrasgn + f = Foo.new assert(defined?(f.attr = 1)) f.attrasgn_test { |v| assert(v) } + end + + def test_defined_undef + x = Object.new + def x.foo; end + assert(defined?(x.foo)) + x.instance_eval {undef :foo} + assert(!defined?(x.foo), "undefed method should not be defined?") + end + def test_defined_yield assert(defined_test) # not iterator assert(!defined_test{}) # called as iterator + end + def test_defined_matchdata /a/ =~ '' assert_equal nil, defined?($&) assert_equal nil, defined?($`) @@ -85,13 +125,144 @@ class TestDefined < Test::Unit::TestCase assert_equal 'global-variable', defined?($+) assert_equal 'global-variable', defined?($1) assert_equal nil, defined?($2) + end + + def test_defined_assignment + assert_equal("assignment", defined?(a = 1)) + assert_equal("assignment", defined?(a += 1)) + assert_equal("assignment", defined?(a &&= 1)) + assert_equal("assignment", eval('defined?(A = 1)')) + assert_equal("assignment", eval('defined?(A += 1)')) + assert_equal("assignment", eval('defined?(A &&= 1)')) + assert_equal("assignment", eval('defined?(A::B = 1)')) + assert_equal("assignment", eval('defined?(A::B += 1)')) + assert_equal("assignment", eval('defined?(A::B &&= 1)')) + end + + def test_defined_splat + assert_nil(defined?([*a])) + assert_nil(defined?(itself(*a))) + assert_equal("expression", defined?([*itself])) + assert_equal("method", defined?(itself(*itself))) + end + + def test_defined_hash + assert_nil(defined?({a: a})) + assert_nil(defined?({a => 1})) + assert_nil(defined?({a => a})) + assert_nil(defined?({**a})) + assert_nil(defined?(itself(a: a))) + assert_nil(defined?(itself(a => 1))) + assert_nil(defined?(itself(a => a))) + assert_nil(defined?(itself(**a))) + assert_nil(defined?(itself({a: a}))) + assert_nil(defined?(itself({a => 1}))) + assert_nil(defined?(itself({a => a}))) + assert_nil(defined?(itself({**a}))) + assert_equal("expression", defined?({a: itself})) + assert_equal("expression", defined?({itself => 1})) + assert_equal("expression", defined?({itself => itself})) + assert_equal("expression", defined?({**itself})) + assert_equal("method", defined?(itself(a: itself))) + assert_equal("method", defined?(itself(itself => 1))) + assert_equal("method", defined?(itself(itself => itself))) + assert_equal("method", defined?(itself(**itself))) + assert_equal("method", defined?(itself({a: itself}))) + assert_equal("method", defined?(itself({itself => 1}))) + assert_equal("method", defined?(itself({itself => itself}))) + assert_equal("method", defined?(itself({**itself}))) + end + + def test_defined_literal assert_equal("nil", defined?(nil)) assert_equal("true", defined?(true)) assert_equal("false", defined?(false)) assert_equal("expression", defined?(1)) end + def test_defined_method + self_ = self + assert_equal("method", defined?(test_defined_method)) + assert_equal("method", defined?(self.test_defined_method)) + assert_equal("method", defined?(self_.test_defined_method)) + + assert_equal(nil, defined?(1.test_defined_method)) + assert_equal("method", defined?(1.to_i)) + assert_equal(nil, defined?(1.to_i.test_defined_method)) + assert_equal(nil, defined?(1.test_defined_method.to_i)) + + assert_equal("method", defined?("x".reverse)) + assert_equal("method", defined?("x".reverse(1))) + assert_equal("method", defined?("x".reverse.reverse)) + assert_equal(nil, defined?("x".reverse(1).reverse)) + + assert_equal("method", defined?(1.to_i(10))) + assert_equal("method", defined?(1.to_i("x"))) + assert_equal(nil, defined?(1.to_i("x").undefined)) + assert_equal(nil, defined?(1.to_i(undefined).to_i)) + assert_equal(nil, defined?(1.to_i("x").undefined.to_i)) + assert_equal(nil, defined?(1.to_i(undefined).to_i.to_i)) + end + + def test_defined_method_single_call + times_called = 0 + define_singleton_method(:t) do + times_called += 1 + self + end + assert_equal("method", defined?(t)) + assert_equal(0, times_called) + + assert_equal("method", defined?(t.t)) + assert_equal(1, times_called) + + times_called = 0 + assert_equal("method", defined?(t.t.t)) + assert_equal(2, times_called) + + times_called = 0 + assert_equal("method", defined?(t.t.t.t)) + assert_equal(3, times_called) + + times_called = 0 + assert_equal("method", defined?(t.t.t.t.t)) + assert_equal(4, times_called) + end + + def test_defined_empty_paren_expr + bug8224 = '[ruby-core:54024] [Bug #8224]' + (1..3).each do |level| + expr = "("*level+")"*level + assert_equal("nil", eval("defined? #{expr}"), "#{bug8224} defined? #{expr}") + assert_equal("nil", eval("defined?(#{expr})"), "#{bug8224} defined?(#{expr})") + end + end + + def test_defined_empty_paren_arg + assert_nil(defined?(p () + 1)) + end + + def test_defined_paren_void_stmts + assert_equal("expression", defined? (;x)) + assert_equal("expression", defined? (x;)) + assert_nil(defined? ( + + x + + )) + + x = 1 + + assert_equal("expression", defined? (;x)) + assert_equal("expression", defined? (x;)) + assert_equal("local-variable", defined? ( + + x + + )) + end + def test_defined_impl_specific feature7035 = '[ruby-core:47558]' # not spec assert_predicate(defined?(Foo), :frozen?, feature7035) @@ -196,10 +367,134 @@ class TestDefined < Test::Unit::TestCase o = c.new o.extend(m) - assert_equal("super", o.x) + assert_equal("super", o.x, bug8367) + end + + def test_super_in_basic_object + BasicObject.class_eval do + def a + defined?(super) + end + end + + assert_nil(a) + ensure + BasicObject.class_eval do + undef_method :a if defined?(a) + end end def test_super_toplevel assert_separately([], "assert_nil(defined?(super))") end + + def test_respond_to + obj = "#{self.class.name}##{__method__}" + class << obj + def respond_to?(mid) + true + end + end + assert_warn(/deprecated method signature.*\n.*respond_to\? is defined here/) do + Warning[:deprecated] = true + defined?(obj.foo) + end + assert_warn('') do + Warning[:deprecated] = false + defined?(obj.foo) + end + end + + class ExampleRespondToMissing + attr_reader :called + + def initialize + @called = false + end + + def respond_to_missing? *args + @called = true + false + end + + def existing_method + end + + def func_defined_existing_func + defined?(existing_method()) + end + + def func_defined_non_existing_func + defined?(non_existing_method()) + end + end + + def test_method_by_respond_to_missing + bug_11211 = '[Bug #11211]' + obj = ExampleRespondToMissing.new + assert_equal("method", defined?(obj.existing_method), bug_11211) + assert_equal(false, obj.called, bug_11211) + assert_equal(nil, defined?(obj.non_existing_method), bug_11211) + assert_equal(true, obj.called, bug_11211) + + bug_11212 = '[Bug #11212]' + obj = ExampleRespondToMissing.new + assert_equal("method", obj.func_defined_existing_func, bug_11212) + assert_equal(false, obj.called, bug_11212) + assert_equal(nil, obj.func_defined_non_existing_func, bug_11212) + assert_equal(true, obj.called, bug_11212) + end + + def test_top_level_constant_not_defined + assert_nil(defined?(TestDefined::Object)) + end + + class RefinedClass + end + + module RefiningModule + refine RefinedClass do + def pub + end + + private + + def priv + end + end + + def self.call_without_using(x = RefinedClass.new) + defined?(x.pub) + end + + def self.vcall_without_using(x = RefinedClass.new) + x.instance_eval {defined?(priv)} + end + + using self + + def self.call_with_using(x = RefinedClass.new) + defined?(x.pub) + end + + def self.vcall_with_using(x = RefinedClass.new) + x.instance_eval {defined?(priv)} + end + end + + def test_defined_refined_call_without_using + assert(!RefiningModule.call_without_using, "refined public method without using") + end + + def test_defined_refined_vcall_without_using + assert(!RefiningModule.vcall_without_using, "refined private method without using") + end + + def test_defined_refined_call_with_using + assert(RefiningModule.call_with_using, "refined public method with using") + end + + def test_defined_refined_vcall_with_using + assert(RefiningModule.vcall_with_using, "refined private method with using") + end end |
