@@ -112,6 +112,81 @@ def test_rand
112112 assert_send_type "(Range[Float]) -> Float" , Kernel , :rand , 0.0 ...10.0
113113 assert_send_type "(Range[Float]) -> nil" , Kernel , :rand , 0.0 ...0.0
114114 end
115+
116+ def test_trace_var
117+ tracer = BlankSlate . new
118+ def tracer . call ( new ) nil end
119+
120+ with_interned '$__TEST_TRACE_VAR' do |name |
121+ assert_send_type '(interned, String) -> nil' ,
122+ Kernel , :trace_var , name , '1'
123+ assert_send_type '(interned, ::Kernel::_Tracer) -> nil' ,
124+ Kernel , :trace_var , name , tracer
125+ assert_send_type '(interned) { (any) -> void } -> nil' ,
126+ Kernel , :trace_var , name do |x | 0 end
127+
128+ # `Kernel.trace_var` doesn't actually check the type of its second argument,
129+ # but instead defers until the global is actually assigned. To ensure that
130+ # our signatures are correct, we assign the global here (which, if our
131+ # signatures are incorrect, will raise an exception)
132+ $__TEST_TRACE_VAR = 1
133+
134+ # Acts the same as `untrace_var`, so this performs the untracing for us.
135+ assert_send_type '(interned, nil) -> Array[String | ::Kernel::_Tracer]' ,
136+ Kernel , :trace_var , name , nil
137+ end
138+ ensure
139+ # Just in case an exception stopped it, we don't want to continue tracing.
140+ # We do `defined?` as `untrace_var :$some_undefined_global` fails
141+ untrace_var :$__TEST_TRACE_VAR if defined? $__TEST_TRACE_VAR
142+ end
143+
144+ def test_untrace_var
145+ tracer = BlankSlate . new
146+ def tracer . call ( new ) nil end
147+
148+ with_interned '$__TEST_UNTRACE_VAR' do |name |
149+ # No argument yields all traces
150+ trace_var :$__TEST_UNTRACE_VAR , '"string"'
151+ trace_var :$__TEST_UNTRACE_VAR do "proc" end
152+ trace_var :$__TEST_UNTRACE_VAR , tracer
153+ assert_send_type '(interned) -> Array[String | ::Kernel::_Tracer]' ,
154+ Kernel , :untrace_var , name
155+
156+ # `nil` also yields all traces
157+ trace_var :$__TEST_UNTRACE_VAR , '"string"'
158+ trace_var :$__TEST_UNTRACE_VAR do "proc" end
159+ trace_var :$__TEST_UNTRACE_VAR , tracer
160+ assert_send_type '(interned, nil) -> Array[String | ::Kernel::_Tracer]' ,
161+ Kernel , :untrace_var , name , nil
162+
163+ # Passing a String in yields the string if they're the same, or `nil`
164+ string = '"string"'
165+ trace_var :$__TEST_UNTRACE_VAR , string
166+ assert_send_type '(interned, String) -> [String]' ,
167+ Kernel , :untrace_var , name , string
168+ assert_send_type '(interned, String) -> nil' ,
169+ Kernel , :untrace_var , name , 'not a trace'
170+
171+ # Passing a `tracer` yields the tracer if it's set, or `nil` otherwise
172+ trace_var :$__TEST_UNTRACE_VAR , tracer
173+ assert_send_type '[T < ::Kernel::_Tracer] (interned, T) -> [T]' ,
174+ Kernel , :untrace_var , name , tracer
175+ assert_send_type '[T < ::Kernel::_Tracer] (interned, T) -> nil' ,
176+ Kernel , :untrace_var , name , tracer
177+
178+ # Anything else is `nil`
179+ with_untyped do |trace |
180+ next if nil == trace
181+ assert_send_type '(interned, untyped) -> nil' ,
182+ Kernel , :untrace_var , name , trace
183+ end
184+ end
185+ ensure
186+ # Just in case an exception stopped it, we don't want to continue tracing.
187+ # We do `defined?` as `untrace_var :$some_undefined_global` fails
188+ untrace_var :$__TEST_UNTRACE_VAR if defined? $__TEST_UNTRACE_VAR
189+ end
115190end
116191
117192class KernelInstanceTest < Test ::Unit ::TestCase
0 commit comments