1require 'test/unit' 2require_relative 'envutil' 3 4class TestSuper < Test::Unit::TestCase 5 class Base 6 def single(a) a end 7 def double(a, b) [a,b] end 8 def array(*a) a end 9 def optional(a = 0) a end 10 def keyword(**a) a end 11 end 12 class Single1 < Base 13 def single(*) super end 14 end 15 class Single2 < Base 16 def single(a,*) super end 17 end 18 class Double1 < Base 19 def double(*) super end 20 end 21 class Double2 < Base 22 def double(a,*) super end 23 end 24 class Double3 < Base 25 def double(a,b,*) super end 26 end 27 class Array1 < Base 28 def array(*) super end 29 end 30 class Array2 < Base 31 def array(a,*) super end 32 end 33 class Array3 < Base 34 def array(a,b,*) super end 35 end 36 class Array4 < Base 37 def array(a,b,c,*) super end 38 end 39 class Optional1 < Base 40 def optional(a = 1) super end 41 end 42 class Optional2 < Base 43 def optional(a, b = 1) super end 44 end 45 class Optional3 < Base 46 def single(a = 1) super end 47 end 48 class Optional4 < Base 49 def array(a = 1, *) super end 50 end 51 class Optional5 < Base 52 def array(a = 1, b = 2, *) super end 53 end 54 class Keyword1 < Base 55 def keyword(foo: "keyword1") super end 56 end 57 class Keyword2 < Base 58 def keyword(foo: "keyword2") 59 foo = "changed1" 60 x = super 61 foo = "changed2" 62 y = super 63 [x, y] 64 end 65 end 66 67 def test_single1 68 assert_equal(1, Single1.new.single(1)) 69 end 70 def test_single2 71 assert_equal(1, Single2.new.single(1)) 72 end 73 def test_double1 74 assert_equal([1, 2], Double1.new.double(1, 2)) 75 end 76 def test_double2 77 assert_equal([1, 2], Double2.new.double(1, 2)) 78 end 79 def test_double3 80 assert_equal([1, 2], Double3.new.double(1, 2)) 81 end 82 def test_array1 83 assert_equal([], Array1.new.array()) 84 assert_equal([1], Array1.new.array(1)) 85 end 86 def test_array2 87 assert_equal([1], Array2.new.array(1)) 88 assert_equal([1,2], Array2.new.array(1, 2)) 89 end 90 def test_array3 91 assert_equal([1,2], Array3.new.array(1, 2)) 92 assert_equal([1,2,3], Array3.new.array(1, 2, 3)) 93 end 94 def test_array4 95 assert_equal([1,2,3], Array4.new.array(1, 2, 3)) 96 assert_equal([1,2,3,4], Array4.new.array(1, 2, 3, 4)) 97 end 98 def test_optional1 99 assert_equal(9, Optional1.new.optional(9)) 100 assert_equal(1, Optional1.new.optional) 101 end 102 def test_optional2 103 assert_raise(ArgumentError) do 104 # call Base#optional with 2 arguments; the 2nd arg is supplied 105 assert_equal(9, Optional2.new.optional(9)) 106 end 107 assert_raise(ArgumentError) do 108 # call Base#optional with 2 arguments 109 assert_equal(9, Optional2.new.optional(9, 2)) 110 end 111 end 112 def test_optional3 113 assert_equal(9, Optional3.new.single(9)) 114 # call Base#single with 1 argument; the arg is supplied 115 assert_equal(1, Optional3.new.single) 116 end 117 def test_optional4 118 assert_equal([1], Optional4.new.array) 119 assert_equal([9], Optional4.new.array(9)) 120 assert_equal([9, 8], Optional4.new.array(9, 8)) 121 end 122 def test_optional5 123 assert_equal([1, 2], Optional5.new.array) 124 assert_equal([9, 2], Optional5.new.array(9)) 125 assert_equal([9, 8], Optional5.new.array(9, 8)) 126 assert_equal([9, 8, 7], Optional5.new.array(9, 8, 7)) 127 end 128 def test_keyword1 129 assert_equal({foo: "keyword1"}, Keyword1.new.keyword) 130 bug8008 = '[ruby-core:53114] [Bug #8008]' 131 assert_equal({foo: bug8008}, Keyword1.new.keyword(foo: bug8008)) 132 end 133 def test_keyword2 134 assert_equal([{foo: "changed1"}, {foo: "changed2"}], Keyword2.new.keyword) 135 end 136 137 class A 138 def tt(aa) 139 "A#tt" 140 end 141 142 def uu(a) 143 class << self 144 define_method(:tt) do |sym| 145 super(sym) 146 end 147 end 148 end 149 end 150 151 def test_define_method 152 a = A.new 153 a.uu(12) 154 assert_equal("A#tt", a.tt(12), "[ruby-core:3856]") 155 e = assert_raise(RuntimeError, "[ruby-core:24244]") { 156 lambda { 157 Class.new { 158 define_method(:a) {super} 159 }.new.a 160 }.call 161 } 162 assert_match(/implicit argument passing of super from method defined by define_method/, e.message) 163 end 164 165 class SubSeq 166 def initialize 167 @first=11 168 @first or fail 169 end 170 171 def subseq 172 @first or fail 173 end 174 end 175 176 class Indexed 177 def subseq 178 SubSeq.new 179 end 180 end 181 182 Overlaid = proc do 183 class << self 184 def subseq 185 super.instance_eval(& Overlaid) 186 end 187 end 188 end 189 190 def test_overlaid 191 assert_nothing_raised('[ruby-dev:40959]') do 192 overlaid = proc do |obj| 193 def obj.reverse 194 super 195 end 196 end 197 overlaid.call(str = "123") 198 overlaid.call(ary = [1,2,3]) 199 str.reverse 200 end 201 202 assert_nothing_raised('[ruby-core:27230]') do 203 mid=Indexed.new 204 mid.instance_eval(&Overlaid) 205 mid.subseq 206 mid.subseq 207 end 208 end 209 210 module DoubleInclude 211 class Base 212 def foo 213 [:Base] 214 end 215 end 216 217 module Override 218 def foo 219 super << :Override 220 end 221 end 222 223 class A < Base 224 end 225 226 class B < A 227 end 228 229 B.send(:include, Override) 230 A.send(:include, Override) 231 end 232 233 # [Bug #3351] 234 def test_double_include 235 assert_equal([:Base, :Override], DoubleInclude::B.new.foo) 236 # should be changed as follows? 237 # assert_equal([:Base, :Override, :Override], DoubleInclude::B.new.foo) 238 end 239 240 module DoubleInclude2 241 class Base 242 def foo 243 [:Base] 244 end 245 end 246 247 module Override 248 def foo 249 super << :Override 250 end 251 end 252 253 class A < Base 254 def foo 255 super << :A 256 end 257 end 258 259 class B < A 260 def foo 261 super << :B 262 end 263 end 264 265 B.send(:include, Override) 266 A.send(:include, Override) 267 end 268 269 def test_double_include2 270 assert_equal([:Base, :Override, :A, :Override, :B], 271 DoubleInclude2::B.new.foo) 272 end 273 274 def test_super_in_instance_eval 275 super_class = Class.new { 276 def foo 277 return [:super, self] 278 end 279 } 280 sub_class = Class.new(super_class) { 281 def foo 282 x = Object.new 283 x.instance_eval do 284 super() 285 end 286 end 287 } 288 obj = sub_class.new 289 assert_raise(TypeError) do 290 obj.foo 291 end 292 end 293 294 def test_super_in_instance_eval_with_define_method 295 super_class = Class.new { 296 def foo 297 return [:super, self] 298 end 299 } 300 sub_class = Class.new(super_class) { 301 define_method(:foo) do 302 x = Object.new 303 x.instance_eval do 304 super() 305 end 306 end 307 } 308 obj = sub_class.new 309 assert_raise(TypeError) do 310 obj.foo 311 end 312 end 313 314 def test_super_in_orphan_block 315 super_class = Class.new { 316 def foo 317 return [:super, self] 318 end 319 } 320 sub_class = Class.new(super_class) { 321 def foo 322 x = Object.new 323 lambda { super() } 324 end 325 } 326 obj = sub_class.new 327 assert_equal([:super, obj], obj.foo.call) 328 end 329 330 def test_super_in_orphan_block_with_instance_eval 331 super_class = Class.new { 332 def foo 333 return [:super, self] 334 end 335 } 336 sub_class = Class.new(super_class) { 337 def foo 338 x = Object.new 339 x.instance_eval do 340 lambda { super() } 341 end 342 end 343 } 344 obj = sub_class.new 345 assert_raise(TypeError) do 346 obj.foo.call 347 end 348 end 349 350 def test_yielding_super 351 a = Class.new { def yielder; yield; end } 352 x = Class.new { define_singleton_method(:hello) { 'hi' } } 353 y = Class.new(x) { 354 define_singleton_method(:hello) { 355 m = a.new 356 m.yielder { super() } 357 } 358 } 359 assert_equal 'hi', y.hello 360 end 361 362 def test_super_in_thread 363 hoge = Class.new { 364 def bar; 'hoge'; end 365 } 366 foo = Class.new(hoge) { 367 def bar; Thread.new { super }.join.value; end 368 } 369 370 assert_equal 'hoge', foo.new.bar 371 end 372 373 def assert_super_in_block(type) 374 bug7064 = '[ruby-core:47680]' 375 assert_normal_exit "#{type} {super}", bug7064 376 end 377 378 def test_super_in_at_exit 379 assert_super_in_block("at_exit") 380 end 381 def test_super_in_END 382 assert_super_in_block("END") 383 end 384 385 def test_super_in_BEGIN 386 assert_super_in_block("BEGIN") 387 end 388 389 class X 390 def foo(*args) 391 args 392 end 393 end 394 395 class Y < X 396 define_method(:foo) do |*args| 397 super(*args) 398 end 399 end 400 401 def test_super_splat 402 # [ruby-list:49575] 403 y = Y.new 404 assert_equal([1, 2], y.foo(1, 2)) 405 assert_equal([1, false], y.foo(1, false)) 406 assert_equal([1, 2, 3, 4, 5], y.foo(1, 2, 3, 4, 5)) 407 assert_equal([false, true], y.foo(false, true)) 408 assert_equal([false, false], y.foo(false, false)) 409 assert_equal([1, 2, 3, false, 5], y.foo(1, 2, 3, false, 5)) 410 end 411 412 def test_missing_super_in_method_module 413 bug9315 = '[ruby-core:59358] [Bug #9315]' 414 a = Module.new do 415 def foo 416 super 417 end 418 end 419 b = Class.new do 420 include a 421 end 422 assert_raise(NoMethodError, bug9315) do 423 b.new.method(:foo).call 424 end 425 end 426 427 def test_module_super_in_method_module 428 bug9315 = '[ruby-core:59589] [Bug #9315]' 429 a = Module.new do 430 def foo 431 super 432 end 433 end 434 c = Class.new do 435 def foo 436 :ok 437 end 438 end 439 o = c.new.extend(a) 440 assert_nothing_raised(NoMethodError, bug9315) do 441 assert_equal(:ok, o.method(:foo).call, bug9315) 442 end 443 end 444 445 def test_missing_super_in_module_unbound_method 446 bug9377 = '[ruby-core:59619] [Bug #9377]' 447 448 a = Module.new do 449 def foo; super end 450 end 451 452 m = a.instance_method(:foo).bind(Object.new.extend(a)) 453 assert_raise(NoMethodError, bug9377) do 454 m.call 455 end 456 end 457end 458