rbs 3.3.2 → 3.4.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/comments.yml +2 -5
- data/.github/workflows/ruby.yml +7 -8
- data/.github/workflows/typecheck.yml +37 -0
- data/CHANGELOG.md +50 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +11 -11
- data/Steepfile +2 -2
- data/core/array.rbs +19 -49
- data/core/basic_object.rbs +2 -2
- data/core/comparable.rbs +17 -8
- data/core/complex.rbs +82 -43
- data/core/data.rbs +2 -4
- data/core/dir.rbs +635 -295
- data/core/enumerable.rbs +11 -18
- data/core/enumerator.rbs +37 -31
- data/core/errors.rbs +4 -0
- data/core/false_class.rbs +34 -15
- data/core/fiber.rbs +23 -0
- data/core/file.rbs +329 -120
- data/core/float.rbs +17 -32
- data/core/gc.rbs +17 -11
- data/core/hash.rbs +22 -44
- data/core/integer.rbs +82 -113
- data/core/io/buffer.rbs +90 -47
- data/core/io.rbs +39 -116
- data/core/kernel.rbs +442 -489
- data/core/match_data.rbs +55 -56
- data/core/module.rbs +45 -1
- data/core/nil_class.rbs +98 -35
- data/core/numeric.rbs +22 -32
- data/core/object_space/weak_key_map.rbs +102 -0
- data/core/process.rbs +1242 -655
- data/core/ractor.rbs +139 -120
- data/core/range.rbs +100 -4
- data/core/rational.rbs +0 -4
- data/core/rbs/unnamed/argf.rbs +16 -8
- data/core/rbs/unnamed/env_class.rbs +0 -24
- data/core/refinement.rbs +8 -0
- data/core/regexp.rbs +1149 -598
- data/core/ruby_vm.rbs +126 -12
- data/core/rubygems/platform.rbs +9 -0
- data/core/rubygems/rubygems.rbs +1 -1
- data/core/rubygems/version.rbs +5 -1
- data/core/set.rbs +20 -22
- data/core/signal.rbs +4 -4
- data/core/string.rbs +283 -230
- data/core/string_io.rbs +2 -14
- data/core/struct.rbs +404 -24
- data/core/symbol.rbs +1 -19
- data/core/thread.rbs +29 -12
- data/core/time.rbs +227 -104
- data/core/trace_point.rbs +2 -5
- data/core/true_class.rbs +54 -21
- data/core/warning.rbs +14 -11
- data/docs/data_and_struct.md +29 -0
- data/docs/syntax.md +3 -5
- data/docs/tools.md +1 -0
- data/ext/rbs_extension/lexer.c +643 -559
- data/ext/rbs_extension/lexer.re +5 -1
- data/ext/rbs_extension/parser.c +12 -3
- data/ext/rbs_extension/unescape.c +7 -47
- data/lib/rbs/cli/diff.rb +4 -1
- data/lib/rbs/cli/validate.rb +280 -0
- data/lib/rbs/cli.rb +2 -194
- data/lib/rbs/collection/config.rb +5 -6
- data/lib/rbs/collection/sources/git.rb +1 -1
- data/lib/rbs/collection.rb +1 -0
- data/lib/rbs/diff.rb +7 -4
- data/lib/rbs/errors.rb +11 -0
- data/lib/rbs/test/errors.rb +4 -1
- data/lib/rbs/test/guaranteed.rb +2 -3
- data/lib/rbs/test/type_check.rb +15 -10
- data/lib/rbs/test.rb +3 -3
- data/lib/rbs/types.rb +29 -0
- data/lib/rbs/unit_test/convertibles.rb +176 -0
- data/lib/rbs/unit_test/spy.rb +136 -0
- data/lib/rbs/unit_test/type_assertions.rb +341 -0
- data/lib/rbs/unit_test/with_aliases.rb +143 -0
- data/lib/rbs/unit_test.rb +6 -0
- data/lib/rbs/version.rb +1 -1
- data/sig/cli/validate.rbs +43 -0
- data/sig/diff.rbs +3 -1
- data/sig/errors.rbs +8 -0
- data/sig/rbs.rbs +1 -1
- data/sig/test/errors.rbs +52 -0
- data/sig/test/guranteed.rbs +9 -0
- data/sig/test/type_check.rbs +19 -0
- data/sig/test.rbs +82 -0
- data/sig/types.rbs +6 -1
- data/sig/unit_test/convertibles.rbs +154 -0
- data/sig/unit_test/spy.rbs +28 -0
- data/sig/unit_test/type_assertions.rbs +194 -0
- data/sig/unit_test/with_aliases.rbs +136 -0
- data/stdlib/base64/0/base64.rbs +307 -45
- data/stdlib/bigdecimal/0/big_decimal.rbs +35 -15
- data/stdlib/coverage/0/coverage.rbs +2 -2
- data/stdlib/csv/0/csv.rbs +25 -55
- data/stdlib/date/0/date.rbs +1 -43
- data/stdlib/date/0/date_time.rbs +1 -13
- data/stdlib/delegate/0/delegator.rbs +186 -0
- data/stdlib/delegate/0/kernel.rbs +47 -0
- data/stdlib/delegate/0/simple_delegator.rbs +98 -0
- data/stdlib/did_you_mean/0/did_you_mean.rbs +1 -1
- data/stdlib/erb/0/erb.rbs +2 -2
- data/stdlib/fileutils/0/fileutils.rbs +0 -19
- data/stdlib/io-console/0/io-console.rbs +12 -1
- data/stdlib/ipaddr/0/ipaddr.rbs +2 -1
- data/stdlib/json/0/json.rbs +320 -81
- data/stdlib/logger/0/logger.rbs +9 -5
- data/stdlib/monitor/0/monitor.rbs +78 -0
- data/stdlib/net-http/0/net-http.rbs +1880 -543
- data/stdlib/objspace/0/objspace.rbs +19 -13
- data/stdlib/openssl/0/openssl.rbs +508 -127
- data/stdlib/optparse/0/optparse.rbs +25 -11
- data/stdlib/pathname/0/pathname.rbs +1 -1
- data/stdlib/pp/0/pp.rbs +2 -5
- data/stdlib/prettyprint/0/prettyprint.rbs +2 -2
- data/stdlib/pstore/0/pstore.rbs +2 -4
- data/stdlib/rdoc/0/comment.rbs +1 -2
- data/stdlib/resolv/0/resolv.rbs +4 -2
- data/stdlib/socket/0/socket.rbs +2 -2
- data/stdlib/socket/0/unix_socket.rbs +2 -2
- data/stdlib/strscan/0/string_scanner.rbs +3 -2
- data/stdlib/tempfile/0/tempfile.rbs +1 -1
- data/stdlib/uri/0/common.rbs +245 -123
- metadata +23 -4
- data/lib/rbs/test/spy.rb +0 -6
data/lib/rbs/diff.rb
CHANGED
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
module RBS
|
4
4
|
class Diff
|
5
|
-
def initialize(type_name:, library_options:, after_path: [], before_path: [])
|
5
|
+
def initialize(type_name:, library_options:, after_path: [], before_path: [], detail: false)
|
6
6
|
@type_name = type_name
|
7
7
|
@library_options = library_options
|
8
8
|
@after_path = after_path
|
9
9
|
@before_path = before_path
|
10
|
+
@detail = detail
|
10
11
|
end
|
11
12
|
|
12
13
|
def each_diff(&block)
|
@@ -100,11 +101,12 @@ module RBS
|
|
100
101
|
if definition_method
|
101
102
|
prefix = kind == :instance ? "" : "self."
|
102
103
|
|
104
|
+
detail_to_s = @detail ? "[#{definition_method.defined_in} #{definition_method.accessibility}] " : ""
|
103
105
|
if definition_method.alias_of
|
104
106
|
first_def = definition_method.alias_of.defs.first #: Definition::Method::TypeDef
|
105
|
-
"alias #{prefix}#{key} #{prefix}#{first_def.member.name}"
|
107
|
+
"#{detail_to_s}alias #{prefix}#{key} #{prefix}#{first_def.member.name}"
|
106
108
|
else
|
107
|
-
"def #{prefix}#{key}: #{definition_method.method_types.join(" | ")}"
|
109
|
+
"#{detail_to_s}def #{prefix}#{key}: #{definition_method.method_types.join(" | ")}"
|
108
110
|
end
|
109
111
|
else
|
110
112
|
+"-"
|
@@ -113,7 +115,8 @@ module RBS
|
|
113
115
|
|
114
116
|
def constant_to_s(constant)
|
115
117
|
if constant
|
116
|
-
"#{constant.name.
|
118
|
+
detail_to_s = @detail ? "[#{constant.name.namespace.to_type_name.to_s}] " : ""
|
119
|
+
"#{detail_to_s}#{constant.name.name}: #{constant.type}"
|
117
120
|
else
|
118
121
|
+"-"
|
119
122
|
end
|
data/lib/rbs/errors.rb
CHANGED
@@ -557,4 +557,15 @@ module RBS
|
|
557
557
|
@alias_entry.decl.location
|
558
558
|
end
|
559
559
|
end
|
560
|
+
|
561
|
+
class WillSyntaxError < DefinitionError
|
562
|
+
include DetailedMessageable
|
563
|
+
|
564
|
+
attr_reader :location
|
565
|
+
|
566
|
+
def initialize(message, location:)
|
567
|
+
super "#{Location.to_string(location)}: #{message}"
|
568
|
+
@location = location
|
569
|
+
end
|
570
|
+
end
|
560
571
|
end
|
data/lib/rbs/test/errors.rb
CHANGED
@@ -29,8 +29,11 @@ module RBS
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
RESPOND_TO = ::Kernel.instance_method :respond_to?
|
33
|
+
private_constant :RESPOND_TO
|
34
|
+
|
32
35
|
def self.inspect_(obj)
|
33
|
-
if
|
36
|
+
if RESPOND_TO.bind_call(obj, :inspect)
|
34
37
|
obj.inspect
|
35
38
|
else
|
36
39
|
Test::INSPECT.bind(obj).call # For the case inspect is not defined (like BasicObject)
|
data/lib/rbs/test/guaranteed.rb
CHANGED
@@ -10,8 +10,7 @@ module RBS
|
|
10
10
|
|
11
11
|
module_function def guaranteed_inspect(obj)
|
12
12
|
obj.inspect
|
13
|
-
rescue NoMethodError
|
14
|
-
raise unless err.name == :inspect && EQUAL.bind_call(obj, err.receiver)
|
13
|
+
rescue NoMethodError
|
15
14
|
INSPECT.bind_call(obj)
|
16
15
|
end
|
17
16
|
|
@@ -20,7 +19,7 @@ module RBS
|
|
20
19
|
|
21
20
|
instance_variables.each_with_index do |variable, index|
|
22
21
|
string.concat ', ' unless index.zero?
|
23
|
-
string.concat "#{variable}: #{guaranteed_inspect(variable)}"
|
22
|
+
string.concat "#{variable}: #{guaranteed_inspect(instance_variable_get(variable))}"
|
24
23
|
end
|
25
24
|
|
26
25
|
string.concat '>'
|
data/lib/rbs/test/type_check.rb
CHANGED
@@ -10,8 +10,6 @@ module RBS
|
|
10
10
|
attr_reader :instance_class
|
11
11
|
attr_reader :class_class
|
12
12
|
|
13
|
-
attr_reader :const_cache
|
14
|
-
|
15
13
|
DEFAULT_SAMPLE_SIZE = 100
|
16
14
|
|
17
15
|
def initialize(self_class:, builder:, sample_size:, unchecked_classes:, instance_class: Object, class_class: Module)
|
@@ -21,7 +19,6 @@ module RBS
|
|
21
19
|
@builder = builder
|
22
20
|
@sample_size = sample_size
|
23
21
|
@unchecked_classes = unchecked_classes.uniq
|
24
|
-
@const_cache = {}
|
25
22
|
end
|
26
23
|
|
27
24
|
def overloaded_call(method, method_name, call, errors:)
|
@@ -38,6 +35,17 @@ module RBS
|
|
38
35
|
if es.size == 1
|
39
36
|
errors.push(*es[0])
|
40
37
|
else
|
38
|
+
RBS.logger.warn do
|
39
|
+
message = +"[#{self_class}#{method_name}] UnresolvedOverloadingError "
|
40
|
+
message << method.method_types.zip(es).map do |method_type, es|
|
41
|
+
msg = +"method_type=`#{method_type}`"
|
42
|
+
details = es.map do |e|
|
43
|
+
"\"#{Errors.to_string(e).sub("[#{e.klass.name}#{e.method_name}] ", "") }\""
|
44
|
+
end.join(', ')
|
45
|
+
msg << " details=[#{details}]"
|
46
|
+
end.join(', ')
|
47
|
+
message
|
48
|
+
end
|
41
49
|
errors << Errors::UnresolvedOverloadingError.new(
|
42
50
|
klass: self_class,
|
43
51
|
method_name: method_name,
|
@@ -208,11 +216,9 @@ module RBS
|
|
208
216
|
end
|
209
217
|
|
210
218
|
def get_class(type_name)
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
nil
|
215
|
-
end
|
219
|
+
Object.const_get(type_name.to_s)
|
220
|
+
rescue NameError
|
221
|
+
nil
|
216
222
|
end
|
217
223
|
|
218
224
|
def is_double?(value)
|
@@ -301,10 +307,9 @@ module RBS
|
|
301
307
|
end
|
302
308
|
val.is_a?(singleton_class)
|
303
309
|
when Types::Interface
|
304
|
-
methods = Set.new(Test.call(val, METHODS))
|
305
310
|
if (definition = builder.build_interface(type.name.absolute!))
|
306
311
|
definition.methods.each_key.all? do |method_name|
|
307
|
-
|
312
|
+
Test.call(val, RESPOND_TOP, method_name)
|
308
313
|
end
|
309
314
|
end
|
310
315
|
when Types::Variable
|
data/lib/rbs/test.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
require "securerandom"
|
4
4
|
require "rbs/test/guaranteed"
|
5
5
|
require "rbs/test/observer"
|
6
|
-
require "rbs/test/spy"
|
7
6
|
require "rbs/test/errors"
|
8
7
|
require "rbs/test/type_check"
|
9
8
|
require "rbs/test/tester"
|
@@ -22,6 +21,7 @@ module RBS
|
|
22
21
|
PP = Kernel.instance_method(:pp)
|
23
22
|
INSPECT = Kernel.instance_method(:inspect)
|
24
23
|
METHODS = Kernel.instance_method(:methods)
|
24
|
+
RESPOND_TOP = Kernel.instance_method(:respond_to?)
|
25
25
|
|
26
26
|
class ArgumentsReturn
|
27
27
|
include Guaranteed::Inspect
|
@@ -85,11 +85,11 @@ module RBS
|
|
85
85
|
|
86
86
|
if ::UnboundMethod.instance_methods.include?(:bind_call)
|
87
87
|
def self.call(receiver, method, *args, &block)
|
88
|
-
method.bind_call(receiver, *args, &block)
|
88
|
+
__skip__ = method.bind_call(receiver, *args, &block)
|
89
89
|
end
|
90
90
|
else
|
91
91
|
def self.call(receiver, method, *args, &block)
|
92
|
-
method.bind(receiver).call(*args, &block)
|
92
|
+
__skip__ = method.bind(receiver).call(*args, &block)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
data/lib/rbs/types.rb
CHANGED
@@ -1399,6 +1399,35 @@ module RBS
|
|
1399
1399
|
def with_nonreturn_void?
|
1400
1400
|
false
|
1401
1401
|
end
|
1402
|
+
|
1403
|
+
TABLE = {
|
1404
|
+
"\\a" => "\a",
|
1405
|
+
"\\b" => "\b",
|
1406
|
+
"\\e" => "\033",
|
1407
|
+
"\\f" => "\f",
|
1408
|
+
"\\n" => "\n",
|
1409
|
+
"\\r" => "\r",
|
1410
|
+
"\\s" => " ",
|
1411
|
+
"\\t" => "\t",
|
1412
|
+
"\\v" => "\v",
|
1413
|
+
"\\\"" => "\"",
|
1414
|
+
"\\\'" => "'",
|
1415
|
+
"\\\\" => "\\",
|
1416
|
+
"\\" => ""
|
1417
|
+
}
|
1418
|
+
|
1419
|
+
def self.unescape_string(string, is_double_quote)
|
1420
|
+
if is_double_quote
|
1421
|
+
string.gsub!(/\\([0-9]{1,3})/) { ($1 || "").to_i(8).chr }
|
1422
|
+
string.gsub!(/\\x([0-9a-f]{1,2})/) { ($1 || "").to_i(16).chr }
|
1423
|
+
string.gsub!(/\\u([0-9a-fA-F]{4})/) { ($1 || "").to_i(16).chr(Encoding::UTF_8) }
|
1424
|
+
string.gsub!(/\\[abefnrstv"'\\]?/, TABLE)
|
1425
|
+
string
|
1426
|
+
else
|
1427
|
+
string.gsub!(/\\['\\]/, TABLE)
|
1428
|
+
string
|
1429
|
+
end
|
1430
|
+
end
|
1402
1431
|
end
|
1403
1432
|
end
|
1404
1433
|
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBS
|
4
|
+
module UnitTest
|
5
|
+
module Convertibles
|
6
|
+
class BlankSlate < BasicObject
|
7
|
+
instance_methods.each do |im|
|
8
|
+
next if im == :__send__
|
9
|
+
undef_method im
|
10
|
+
end
|
11
|
+
|
12
|
+
def __with_object_methods(*methods)
|
13
|
+
methods.each do |method|
|
14
|
+
singleton_class = ::Object.instance_method(:singleton_class).bind_call(self) #: Class
|
15
|
+
singleton_class.instance_eval do
|
16
|
+
define_method method, ::Object.instance_method(method)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class ToIO < BlankSlate
|
24
|
+
def initialize(io = $stdout)
|
25
|
+
@io = io
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_io
|
29
|
+
@io
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class ToI < BlankSlate
|
34
|
+
def initialize(value = 3)
|
35
|
+
@value = value
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_i
|
39
|
+
@value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class ToInt < BlankSlate
|
44
|
+
def initialize(value = 3)
|
45
|
+
@value = value
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_int
|
49
|
+
@value
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class ToF < BlankSlate
|
54
|
+
def initialize(value = 0.1)
|
55
|
+
@value = value
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_f
|
59
|
+
@value
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class ToR < BlankSlate
|
64
|
+
def initialize(value = 1r)
|
65
|
+
@value = value
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_r
|
69
|
+
@value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class ToC < BlankSlate
|
74
|
+
def initialize(value = 1i)
|
75
|
+
@value = value
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_c
|
79
|
+
@value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class ToStr < BlankSlate
|
84
|
+
def initialize(value = "")
|
85
|
+
@value = value
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_str
|
89
|
+
@value
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class ToS < BlankSlate
|
94
|
+
def initialize(value = "")
|
95
|
+
@value = value
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_s
|
99
|
+
@value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class ToSym < BlankSlate
|
104
|
+
def initialize(value = :&)
|
105
|
+
@value = value
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_sym
|
109
|
+
@value
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class ToA < BlankSlate
|
114
|
+
def initialize(*args)
|
115
|
+
@args = args
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_a
|
119
|
+
@args
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class ToArray < BlankSlate
|
124
|
+
def initialize(*args)
|
125
|
+
@args = args
|
126
|
+
end
|
127
|
+
|
128
|
+
def to_ary
|
129
|
+
@args
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class ToHash < BlankSlate
|
134
|
+
def initialize(hash = { 'hello' => 'world' })
|
135
|
+
@hash = hash
|
136
|
+
end
|
137
|
+
|
138
|
+
def to_hash
|
139
|
+
@hash
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class ToPath < BlankSlate
|
144
|
+
def initialize(value = "")
|
145
|
+
@value = value
|
146
|
+
end
|
147
|
+
|
148
|
+
def to_path
|
149
|
+
@value
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
class CustomRange < BlankSlate
|
154
|
+
attr_reader :begin, :end
|
155
|
+
|
156
|
+
def initialize(begin_, end_, exclude_end = false)
|
157
|
+
@begin = begin_
|
158
|
+
@end = end_
|
159
|
+
@exclude_end = exclude_end
|
160
|
+
end
|
161
|
+
|
162
|
+
def exclude_end? = @exclude_end
|
163
|
+
end
|
164
|
+
|
165
|
+
class Each < BlankSlate
|
166
|
+
def initialize(*args)
|
167
|
+
@args = args
|
168
|
+
end
|
169
|
+
|
170
|
+
def each(&block)
|
171
|
+
@args.each(&block)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBS
|
4
|
+
module UnitTest
|
5
|
+
module Spy
|
6
|
+
def self.wrap(object, method_name)
|
7
|
+
spy = WrapSpy.new(object: object, method_name: method_name)
|
8
|
+
|
9
|
+
if block_given?
|
10
|
+
begin
|
11
|
+
yield spy, spy.wrapped_object
|
12
|
+
end
|
13
|
+
else
|
14
|
+
spy
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class WrapSpy
|
19
|
+
attr_accessor :callback
|
20
|
+
attr_reader :object
|
21
|
+
attr_reader :method_name
|
22
|
+
|
23
|
+
def initialize(object:, method_name:)
|
24
|
+
@callback = -> (_) { }
|
25
|
+
@object = object
|
26
|
+
@method_name = method_name
|
27
|
+
end
|
28
|
+
|
29
|
+
def wrapped_object
|
30
|
+
spy = self #: WrapSpy[untyped]
|
31
|
+
|
32
|
+
Class.new(BasicObject) do
|
33
|
+
# @type self: Class
|
34
|
+
|
35
|
+
define_method(:method_missing) do |name, *args, &block|
|
36
|
+
spy.object.__send__(name, *args, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
define_method(
|
40
|
+
spy.method_name,
|
41
|
+
_ = -> (*args, &block) do
|
42
|
+
return_value = nil
|
43
|
+
exception = nil
|
44
|
+
block_calls = [] #: Array[Test::ArgumentsReturn]
|
45
|
+
|
46
|
+
spy_block = if block
|
47
|
+
Object.new.instance_eval do |fresh|
|
48
|
+
proc = -> (*block_args) do
|
49
|
+
block_exn = nil
|
50
|
+
block_return = nil
|
51
|
+
|
52
|
+
begin
|
53
|
+
block_return = if self.equal?(fresh)
|
54
|
+
# no instance eval
|
55
|
+
block.call(*block_args)
|
56
|
+
else
|
57
|
+
self.instance_exec(*block_args, &block)
|
58
|
+
end
|
59
|
+
rescue Exception => exn
|
60
|
+
block_exn = exn
|
61
|
+
end
|
62
|
+
|
63
|
+
if block_exn
|
64
|
+
block_calls << Test::ArgumentsReturn.exception(
|
65
|
+
arguments: block_args,
|
66
|
+
exception: block_exn
|
67
|
+
)
|
68
|
+
else
|
69
|
+
block_calls << Test::ArgumentsReturn.return(
|
70
|
+
arguments: block_args,
|
71
|
+
value: block_return
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
if block_exn
|
76
|
+
raise block_exn
|
77
|
+
else
|
78
|
+
block_return
|
79
|
+
end
|
80
|
+
end #: Proc
|
81
|
+
|
82
|
+
proc.ruby2_keywords
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
begin
|
87
|
+
if spy_block
|
88
|
+
return_value = spy.object.__send__(spy.method_name, *args) do |*a, **k, &b|
|
89
|
+
spy_block.call(*a, **k, &b)
|
90
|
+
end
|
91
|
+
else
|
92
|
+
return_value = spy.object.__send__(spy.method_name, *args, &spy_block)
|
93
|
+
end
|
94
|
+
rescue ::Exception => exn
|
95
|
+
exception = exn
|
96
|
+
end
|
97
|
+
|
98
|
+
return_value
|
99
|
+
|
100
|
+
ensure
|
101
|
+
call =
|
102
|
+
case
|
103
|
+
when exception
|
104
|
+
Test::ArgumentsReturn.exception(
|
105
|
+
arguments: args,
|
106
|
+
exception: exception
|
107
|
+
)
|
108
|
+
when return_value
|
109
|
+
Test::ArgumentsReturn.return(
|
110
|
+
arguments: args,
|
111
|
+
value: return_value
|
112
|
+
)
|
113
|
+
else
|
114
|
+
# break
|
115
|
+
Test::ArgumentsReturn.break(arguments: args)
|
116
|
+
end
|
117
|
+
trace = RBS::Test::CallTrace.new(
|
118
|
+
method_name: spy.method_name,
|
119
|
+
method_call: call,
|
120
|
+
block_calls: block_calls,
|
121
|
+
block_given: block != nil
|
122
|
+
)
|
123
|
+
|
124
|
+
spy.callback.call(trace)
|
125
|
+
|
126
|
+
if exception
|
127
|
+
spy.object.__send__(:raise, exception)
|
128
|
+
end
|
129
|
+
end.ruby2_keywords
|
130
|
+
)
|
131
|
+
end.new()
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|