1module KernelSpecs
2  def self.Array_function(arg)
3    Array(arg)
4  end
5
6  def self.Array_method(arg)
7    Kernel.Array(arg)
8  end
9
10  def self.Hash_function(arg)
11    Hash(arg)
12  end
13
14  def self.Hash_method(arg)
15    Kernel.Hash(arg)
16  end
17
18  def self.Integer_function(arg)
19    Integer(arg)
20  end
21
22  def self.Integer_method(arg)
23    Kernel.Integer(arg)
24  end
25
26  def self.putc_function(arg)
27    putc arg
28  end
29
30  def self.putc_method(arg)
31    Kernel.putc arg
32  end
33
34  def self.has_private_method(name)
35    IO.popen([*ruby_exe, "-n", "-e", "print Kernel.private_method_defined?(#{name.inspect})"], "r+") do |io|
36      io.puts
37      io.close_write
38      io.read
39    end == "true"
40  end
41
42  def self.chop(str, method)
43    IO.popen([*ruby_exe, "-n", "-e", "$_ = #{str.inspect}; #{method}; print $_"], "r+") do |io|
44      io.puts
45      io.close_write
46      io.read
47    end
48  end
49
50  def self.chomp(str, method, sep="\n")
51    code = "$_ = #{str.inspect}; $/ = #{sep.inspect}; #{method}; print $_"
52    IO.popen([*ruby_exe, "-n", "-e", code], "r+") do |io|
53      io.puts
54      io.close_write
55      io.read
56    end
57  end
58
59  def self.run_with_dash_n(file)
60    IO.popen([*ruby_exe, "-n", file], "r+") do |io|
61      io.puts
62      io.close_write
63      io.read
64    end
65  end
66
67  # kind_of?, is_a?, instance_of?
68  module SomeOtherModule; end
69  module AncestorModule; end
70  module MyModule; end
71  module MyPrependedModule; end
72  module MyExtensionModule; end
73
74  class AncestorClass < String
75    include AncestorModule
76  end
77
78  class InstanceClass < AncestorClass
79    include MyModule
80  end
81
82  class KindaClass < AncestorClass
83    include MyModule
84    prepend MyPrependedModule
85
86    def initialize
87      self.extend MyExtensionModule
88    end
89  end
90
91  class Method
92    public :abort, :exit, :exit!, :fork, :system
93  end
94
95  class Methods
96
97    module MetaclassMethods
98      def peekaboo
99      end
100
101      protected
102
103      def nopeeking
104      end
105
106      private
107
108      def shoo
109      end
110    end
111
112    def self.ichi; end
113    def ni; end
114    class << self
115      def san; end
116    end
117
118    private
119
120    def self.shi; end
121    def juu_shi; end
122
123    class << self
124      def roku; end
125
126      private
127
128      def shichi; end
129    end
130
131    protected
132
133    def self.hachi; end
134    def ku; end
135
136    class << self
137      def juu; end
138
139      protected
140
141      def juu_ichi; end
142    end
143
144    public
145
146    def self.juu_ni; end
147    def juu_san; end
148  end
149
150  class PrivateSup
151    def public_in_sub
152    end
153
154    private :public_in_sub
155  end
156
157  class PublicSub < PrivateSup
158    def public_in_sub
159    end
160  end
161
162  class A
163    # There is Kernel#public_method, so we don't want this one to clash
164    def pub_method; :public_method; end
165
166    def undefed_method; :undefed_method; end
167    undef_method :undefed_method
168
169    protected
170    def protected_method; :protected_method; end
171
172    private
173    def private_method; :private_method; end
174
175    public
176    define_method(:defined_method) { :defined }
177  end
178
179  class B < A
180    alias aliased_pub_method pub_method
181  end
182
183  class VisibilityChange
184    class << self
185      private :new
186    end
187  end
188
189  class Binding
190    @@super_secret = "password"
191
192    def initialize(n)
193      @secret = n
194    end
195
196    def square(n)
197      n * n
198    end
199
200    def get_binding
201      a = true
202      @bind = binding
203
204      # Add/Change stuff
205      b = true
206      @secret += 1
207
208      @bind
209    end
210  end
211
212
213  module BlockGiven
214    def self.accept_block
215      block_given?
216    end
217
218    def self.accept_block_as_argument(&block)
219      block_given?
220    end
221
222    class << self
223      define_method(:defined_block) do
224        block_given?
225      end
226    end
227  end
228
229  module SelfBlockGiven
230    def self.accept_block
231      self.send(:block_given?)
232    end
233
234    def self.accept_block_as_argument(&block)
235      self.send(:block_given?)
236    end
237
238    class << self
239      define_method(:defined_block) do
240        self.send(:block_given?)
241      end
242    end
243  end
244
245  module KernelBlockGiven
246    def self.accept_block
247      Kernel.block_given?
248    end
249
250    def self.accept_block_as_argument(&block)
251      Kernel.block_given?
252    end
253
254    class << self
255      define_method(:defined_block) do
256        Kernel.block_given?
257      end
258    end
259  end
260
261  class EvalTest
262    def self.eval_yield_with_binding
263      eval("yield", binding)
264    end
265    def self.call_yield
266      yield
267    end
268  end
269
270  module DuplicateM
271    def repr
272      self.class.name.to_s
273    end
274  end
275
276  class Duplicate
277    attr_accessor :one, :two
278
279    def initialize(one, two)
280      @one = one
281      @two = two
282    end
283
284    def initialize_copy(other)
285      ScratchPad.record object_id
286    end
287  end
288
289  class Clone
290    def initialize_clone(other)
291      ScratchPad.record other.object_id
292    end
293  end
294
295  class Dup
296    def initialize_dup(other)
297      ScratchPad.record other.object_id
298    end
299  end
300
301  module ParentMixin
302    def parent_mixin_method; end
303  end
304
305  class Parent
306    include ParentMixin
307    def parent_method; end
308    def another_parent_method; end
309    def self.parent_class_method; :foo; end
310  end
311
312  class Child < Parent
313    undef_method :parent_method
314  end
315
316  class Grandchild < Child
317    undef_method :parent_mixin_method
318  end
319
320  # for testing lambda
321  class Lambda
322    def outer
323      inner
324    end
325
326    def mp(&b); b; end
327
328    def inner
329      b = mp { return :good }
330
331      pr = lambda { |x| x.call }
332
333      pr.call(b)
334
335      # We shouldn't be here, b should have unwinded through
336      return :bad
337    end
338  end
339
340  class RespondViaMissing
341    def respond_to_missing?(method, priv=false)
342      case method
343        when :handled_publicly
344          true
345        when :handled_privately
346          priv
347        when :not_handled
348          false
349        else
350          raise "Typo in method name"
351      end
352    end
353
354    def method_missing(method, *args)
355      "Done #{method}(#{args})"
356    end
357  end
358
359  class InstanceVariable
360    def initialize
361      @greeting = "hello"
362    end
363  end
364
365  class PrivateToAry
366    private
367
368    def to_ary
369      [1, 2]
370    end
371
372    def to_a
373      [3, 4]
374    end
375  end
376
377  class PrivateToA
378    private
379
380    def to_a
381      [3, 4]
382    end
383  end
384
385  module AutoloadMethod
386    def setup_autoload(file)
387      autoload :AutoloadFromIncludedModule, file
388    end
389  end
390
391  class AutoloadMethodIncluder
392    include AutoloadMethod
393  end
394
395  module AutoloadMethod2
396    def setup_autoload(file)
397      Kernel.autoload :AutoloadFromIncludedModule2, file
398    end
399  end
400
401  class AutoloadMethodIncluder2
402    include AutoloadMethod2
403  end
404
405  class WarnInNestedCall
406    def f4(s = "", n)
407      f3(s, n)
408    end
409
410    def f3(s, n)
411      f2(s, n)
412    end
413
414    def f2(s, n)
415      f1(s, n)
416    end
417
418    def f1(s, n)
419      warn(s, uplevel: n)
420    end
421
422    def warn_call_lineno; method(:f1).source_location[1] + 1; end
423    def f1_call_lineno; method(:f2).source_location[1] + 1; end
424    def f2_call_lineno; method(:f3).source_location[1] + 1; end
425    def f3_call_lineno; method(:f4).source_location[1] + 1; end
426  end
427end
428
429class EvalSpecs
430  class A
431    eval "class B; end"
432    def c
433      eval "class C; end"
434    end
435  end
436
437  class CoercedObject
438    def to_str
439      '2 + 3'
440    end
441
442    def hash
443      nil
444    end
445  end
446
447  def f
448    yield
449  end
450
451  def self.call_eval
452    f = __FILE__
453    eval "true", binding, "(eval)", 1
454    return f
455  end
456end
457
458# for Kernel#sleep to have Channel in it's specs
459# TODO: switch directly to queue for both Kernel#sleep and Thread specs?
460unless defined? Channel
461  require 'thread'
462  class Channel < Queue
463    alias receive shift
464  end
465end
466