1##
2# Proc ISO Test
3
4assert('Proc', '15.2.17') do
5  assert_equal Class, Proc.class
6end
7
8assert('Proc.new', '15.2.17.3.1') do
9  assert_raise ArgumentError do
10    Proc.new
11  end
12
13  assert_equal (Proc.new {}).class, Proc
14
15  assert_raise LocalJumpError do
16    Proc.new{ break }.call
17  end
18end
19
20assert('Proc#[]', '15.2.17.4.1') do
21  a = 0
22  b = Proc.new { a += 1 }
23  b.[]
24
25  a2 = 0
26  b2 = Proc.new { |i| a2 += i }
27  b2.[](5)
28
29  assert_equal 1, a
30  assert_equal 5, a2
31end
32
33assert('Proc#arity', '15.2.17.4.2') do
34  a = Proc.new {|x, y|}.arity
35  b = Proc.new {|x, *y, z|}.arity
36  c = Proc.new {|x=0, y|}.arity
37  d = Proc.new {|(x, y), z=0|}.arity
38
39  assert_equal  2, a
40  assert_equal(-3, b)
41  assert_equal  1, c
42  assert_equal  1, d
43
44  e = ->(x=0, y){}.arity
45  f = ->((x, y), z=0){}.arity
46  g = ->(x=0){}.arity
47
48  assert_equal(-2, e)
49  assert_equal(-2, f)
50  assert_equal(-1, g)
51end
52
53assert('Proc#call', '15.2.17.4.3') do
54  a = 0
55  b = Proc.new { a += 1 }
56  b.call
57
58  a2 = 0
59  b2 = Proc.new { |i| a2 += i }
60  b2.call(5)
61
62  assert_equal 1, a
63  assert_equal 5, a2
64end
65
66assert('Proc#call proc args pos block') do
67  pr = Proc.new {|a,b,&c|
68    [a, b, c.class, c&&c.call(:x)]
69  }
70  assert_equal [nil, nil, Proc, :proc], (pr.call(){ :proc })
71  assert_equal [1, nil, Proc, :proc], (pr.call(1){ :proc })
72  assert_equal [1, 2, Proc, :proc], (pr.call(1, 2){ :proc })
73  assert_equal [1, 2, Proc, :proc], (pr.call(1, 2, 3){ :proc })
74  assert_equal [1, 2, Proc, :proc], (pr.call(1, 2, 3, 4){ :proc })
75
76  assert_equal [nil, nil, Proc, :x], (pr.call(){|x| x})
77  assert_equal [1, nil, Proc, :x], (pr.call(1){|x| x})
78  assert_equal [1, 2, Proc, :x], (pr.call(1, 2){|x| x})
79  assert_equal [1, 2, Proc, :x], (pr.call(1, 2, 3){|x| x})
80  assert_equal [1, 2, Proc, :x], (pr.call(1, 2, 3, 4){|x| x})
81end
82
83assert('Proc#call proc args pos rest post') do
84  pr = Proc.new {|a,b,*c,d,e|
85    [a,b,c,d,e]
86  }
87  assert_equal [nil, nil, [], nil, nil], pr.call()
88  assert_equal [1, nil, [], nil, nil], pr.call(1)
89  assert_equal [1, 2, [], nil, nil], pr.call(1,2)
90  assert_equal [1, 2, [], 3, nil], pr.call(1,2,3)
91  assert_equal [1, 2, [], 3, 4], pr.call(1,2,3,4)
92  assert_equal [1, 2, [3], 4, 5], pr.call(1,2,3,4,5)
93  assert_equal [1, 2, [3, 4], 5, 6], pr.call(1,2,3,4,5,6)
94  assert_equal [1, 2, [3, 4, 5], 6,7], pr.call(1,2,3,4,5,6,7)
95
96  assert_equal [nil, nil, [], nil, nil], pr.call([])
97  assert_equal [1, nil, [], nil, nil], pr.call([1])
98  assert_equal [1, 2, [], nil, nil], pr.call([1,2])
99  assert_equal [1, 2, [], 3, nil], pr.call([1,2,3])
100  assert_equal [1, 2, [], 3, 4], pr.call([1,2,3,4])
101  assert_equal [1, 2, [3], 4, 5], pr.call([1,2,3,4,5])
102  assert_equal [1, 2, [3, 4], 5, 6], pr.call([1,2,3,4,5,6])
103  assert_equal [1, 2, [3, 4, 5], 6,7], pr.call([1,2,3,4,5,6,7])
104end
105
106assert('Proc#return_does_not_break_self') do
107  class TestClass
108    attr_accessor :block
109    def initialize
110    end
111    def return_array
112      @block = Proc.new { self }
113      return []
114    end
115    def return_instance_variable
116      @block = Proc.new { self }
117      return @block
118    end
119    def return_const_fixnum
120      @block = Proc.new { self }
121      return 123
122    end
123    def return_nil
124      @block = Proc.new { self }
125      return nil
126    end
127  end
128
129  c = TestClass.new
130  assert_equal [], c.return_array
131  assert_equal c, c.block.call
132
133  c.return_instance_variable
134  assert_equal c, c.block.call
135
136  assert_equal 123, c.return_const_fixnum
137  assert_equal c, c.block.call
138
139  assert_equal nil, c.return_nil
140  assert_equal c, c.block.call
141end
142
143assert('call Proc#initialize if defined') do
144  a = []
145  c = Class.new(Proc) do
146    define_method(:initialize) do
147      a << :ok
148    end
149  end
150
151  assert_kind_of c, c.new{}
152  assert_equal [:ok], a
153end
154
155assert('&obj call to_proc if defined') do
156  pr = Proc.new{}
157  def mock(&b)
158    b
159  end
160  assert_same pr, mock(&pr)
161  assert_equal pr, mock(&pr)
162
163  obj = Object.new
164  def obj.to_proc
165    Proc.new{ :from_to_proc }
166  end
167  assert_equal :from_to_proc, mock(&obj).call
168
169  assert_raise(TypeError){ mock(&(Object.new)) }
170end
171
172assert('Creation of a proc through the block of a method') do
173  def m(&b) b end
174
175  assert_equal m{}.class, Proc
176
177  assert_raise LocalJumpError do
178    m{ break }.call
179  end
180end
181