minitest 5.14.0 → 5.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,7 +22,7 @@ module Minitest::Expectations
22
22
  ##
23
23
  # See Minitest::Assertions#assert_empty.
24
24
  #
25
- # collection.must_be_empty
25
+ # _(collection).must_be_empty
26
26
  #
27
27
  # :method: must_be_empty
28
28
 
@@ -31,7 +31,7 @@ module Minitest::Expectations
31
31
  ##
32
32
  # See Minitest::Assertions#assert_equal
33
33
  #
34
- # a.must_equal b
34
+ # _(a).must_equal b
35
35
  #
36
36
  # :method: must_equal
37
37
 
@@ -40,7 +40,7 @@ module Minitest::Expectations
40
40
  ##
41
41
  # See Minitest::Assertions#assert_in_delta
42
42
  #
43
- # n.must_be_close_to m [, delta]
43
+ # _(n).must_be_close_to m [, delta]
44
44
  #
45
45
  # :method: must_be_close_to
46
46
 
@@ -51,7 +51,7 @@ module Minitest::Expectations
51
51
  ##
52
52
  # See Minitest::Assertions#assert_in_epsilon
53
53
  #
54
- # n.must_be_within_epsilon m [, epsilon]
54
+ # _(n).must_be_within_epsilon m [, epsilon]
55
55
  #
56
56
  # :method: must_be_within_epsilon
57
57
 
@@ -60,7 +60,7 @@ module Minitest::Expectations
60
60
  ##
61
61
  # See Minitest::Assertions#assert_includes
62
62
  #
63
- # collection.must_include obj
63
+ # _(collection).must_include obj
64
64
  #
65
65
  # :method: must_include
66
66
 
@@ -69,7 +69,7 @@ module Minitest::Expectations
69
69
  ##
70
70
  # See Minitest::Assertions#assert_instance_of
71
71
  #
72
- # obj.must_be_instance_of klass
72
+ # _(obj).must_be_instance_of klass
73
73
  #
74
74
  # :method: must_be_instance_of
75
75
 
@@ -78,7 +78,7 @@ module Minitest::Expectations
78
78
  ##
79
79
  # See Minitest::Assertions#assert_kind_of
80
80
  #
81
- # obj.must_be_kind_of mod
81
+ # _(obj).must_be_kind_of mod
82
82
  #
83
83
  # :method: must_be_kind_of
84
84
 
@@ -87,7 +87,7 @@ module Minitest::Expectations
87
87
  ##
88
88
  # See Minitest::Assertions#assert_match
89
89
  #
90
- # a.must_match b
90
+ # _(a).must_match b
91
91
  #
92
92
  # :method: must_match
93
93
 
@@ -96,7 +96,7 @@ module Minitest::Expectations
96
96
  ##
97
97
  # See Minitest::Assertions#assert_nil
98
98
  #
99
- # obj.must_be_nil
99
+ # _(obj).must_be_nil
100
100
  #
101
101
  # :method: must_be_nil
102
102
 
@@ -105,11 +105,11 @@ module Minitest::Expectations
105
105
  ##
106
106
  # See Minitest::Assertions#assert_operator
107
107
  #
108
- # n.must_be :<=, 42
108
+ # _(n).must_be :<=, 42
109
109
  #
110
110
  # This can also do predicates:
111
111
  #
112
- # str.must_be :empty?
112
+ # _(str).must_be :empty?
113
113
  #
114
114
  # :method: must_be
115
115
 
@@ -118,7 +118,7 @@ module Minitest::Expectations
118
118
  ##
119
119
  # See Minitest::Assertions#assert_output
120
120
  #
121
- # proc { ... }.must_output out_or_nil [, err]
121
+ # _ { ... }.must_output out_or_nil [, err]
122
122
  #
123
123
  # :method: must_output
124
124
 
@@ -127,7 +127,7 @@ module Minitest::Expectations
127
127
  ##
128
128
  # See Minitest::Assertions#assert_raises
129
129
  #
130
- # proc { ... }.must_raise exception
130
+ # _ { ... }.must_raise exception
131
131
  #
132
132
  # :method: must_raise
133
133
 
@@ -136,7 +136,7 @@ module Minitest::Expectations
136
136
  ##
137
137
  # See Minitest::Assertions#assert_respond_to
138
138
  #
139
- # obj.must_respond_to msg
139
+ # _(obj).must_respond_to msg
140
140
  #
141
141
  # :method: must_respond_to
142
142
 
@@ -145,7 +145,7 @@ module Minitest::Expectations
145
145
  ##
146
146
  # See Minitest::Assertions#assert_same
147
147
  #
148
- # a.must_be_same_as b
148
+ # _(a).must_be_same_as b
149
149
  #
150
150
  # :method: must_be_same_as
151
151
 
@@ -154,7 +154,7 @@ module Minitest::Expectations
154
154
  ##
155
155
  # See Minitest::Assertions#assert_silent
156
156
  #
157
- # proc { ... }.must_be_silent
157
+ # _ { ... }.must_be_silent
158
158
  #
159
159
  # :method: must_be_silent
160
160
 
@@ -163,7 +163,7 @@ module Minitest::Expectations
163
163
  ##
164
164
  # See Minitest::Assertions#assert_throws
165
165
  #
166
- # proc { ... }.must_throw sym
166
+ # _ { ... }.must_throw sym
167
167
  #
168
168
  # :method: must_throw
169
169
 
@@ -190,7 +190,7 @@ module Minitest::Expectations
190
190
  ##
191
191
  # See Minitest::Assertions#refute_empty
192
192
  #
193
- # collection.wont_be_empty
193
+ # _(collection).wont_be_empty
194
194
  #
195
195
  # :method: wont_be_empty
196
196
 
@@ -199,7 +199,7 @@ module Minitest::Expectations
199
199
  ##
200
200
  # See Minitest::Assertions#refute_equal
201
201
  #
202
- # a.wont_equal b
202
+ # _(a).wont_equal b
203
203
  #
204
204
  # :method: wont_equal
205
205
 
@@ -208,7 +208,7 @@ module Minitest::Expectations
208
208
  ##
209
209
  # See Minitest::Assertions#refute_in_delta
210
210
  #
211
- # n.wont_be_close_to m [, delta]
211
+ # _(n).wont_be_close_to m [, delta]
212
212
  #
213
213
  # :method: wont_be_close_to
214
214
 
@@ -219,7 +219,7 @@ module Minitest::Expectations
219
219
  ##
220
220
  # See Minitest::Assertions#refute_in_epsilon
221
221
  #
222
- # n.wont_be_within_epsilon m [, epsilon]
222
+ # _(n).wont_be_within_epsilon m [, epsilon]
223
223
  #
224
224
  # :method: wont_be_within_epsilon
225
225
 
@@ -228,7 +228,7 @@ module Minitest::Expectations
228
228
  ##
229
229
  # See Minitest::Assertions#refute_includes
230
230
  #
231
- # collection.wont_include obj
231
+ # _(collection).wont_include obj
232
232
  #
233
233
  # :method: wont_include
234
234
 
@@ -237,7 +237,7 @@ module Minitest::Expectations
237
237
  ##
238
238
  # See Minitest::Assertions#refute_instance_of
239
239
  #
240
- # obj.wont_be_instance_of klass
240
+ # _(obj).wont_be_instance_of klass
241
241
  #
242
242
  # :method: wont_be_instance_of
243
243
 
@@ -246,7 +246,7 @@ module Minitest::Expectations
246
246
  ##
247
247
  # See Minitest::Assertions#refute_kind_of
248
248
  #
249
- # obj.wont_be_kind_of mod
249
+ # _(obj).wont_be_kind_of mod
250
250
  #
251
251
  # :method: wont_be_kind_of
252
252
 
@@ -255,7 +255,7 @@ module Minitest::Expectations
255
255
  ##
256
256
  # See Minitest::Assertions#refute_match
257
257
  #
258
- # a.wont_match b
258
+ # _(a).wont_match b
259
259
  #
260
260
  # :method: wont_match
261
261
 
@@ -264,7 +264,7 @@ module Minitest::Expectations
264
264
  ##
265
265
  # See Minitest::Assertions#refute_nil
266
266
  #
267
- # obj.wont_be_nil
267
+ # _(obj).wont_be_nil
268
268
  #
269
269
  # :method: wont_be_nil
270
270
 
@@ -273,7 +273,7 @@ module Minitest::Expectations
273
273
  ##
274
274
  # See Minitest::Assertions#refute_operator
275
275
  #
276
- # n.wont_be :<=, 42
276
+ # _(n).wont_be :<=, 42
277
277
  #
278
278
  # This can also do predicates:
279
279
  #
@@ -286,7 +286,7 @@ module Minitest::Expectations
286
286
  ##
287
287
  # See Minitest::Assertions#refute_respond_to
288
288
  #
289
- # obj.wont_respond_to msg
289
+ # _(obj).wont_respond_to msg
290
290
  #
291
291
  # :method: wont_respond_to
292
292
 
@@ -295,7 +295,7 @@ module Minitest::Expectations
295
295
  ##
296
296
  # See Minitest::Assertions#refute_same
297
297
  #
298
- # a.wont_be_same_as b
298
+ # _(a).wont_be_same_as b
299
299
  #
300
300
  # :method: wont_be_same_as
301
301
 
data/lib/minitest/mock.rb CHANGED
@@ -28,11 +28,19 @@ module Minitest # :nodoc:
28
28
  end
29
29
 
30
30
  overridden_methods.map(&:to_sym).each do |method_id|
31
- define_method method_id do |*args, &b|
31
+ define_method method_id do |*args, **kwargs, &b|
32
32
  if @expected_calls.key? method_id then
33
- method_missing(method_id, *args, &b)
33
+ if kwargs.empty? then # FIX: drop this after 2.7 dead
34
+ method_missing(method_id, *args, &b)
35
+ else
36
+ method_missing(method_id, *args, **kwargs, &b)
37
+ end
34
38
  else
35
- super(*args, &b)
39
+ if kwargs.empty? then # FIX: drop this after 2.7 dead
40
+ super(*args, &b)
41
+ else
42
+ super(*args, **kwargs, &b)
43
+ end
36
44
  end
37
45
  end
38
46
  end
@@ -43,9 +51,11 @@ module Minitest # :nodoc:
43
51
  @actual_calls = Hash.new { |calls, name| calls[name] = [] }
44
52
  end
45
53
 
54
+ @@KW_WARNED = false # :nodoc:
55
+
46
56
  ##
47
- # Expect that method +name+ is called, optionally with +args+ or a
48
- # +blk+, and returns +retval+.
57
+ # Expect that method +name+ is called, optionally with +args+ (and
58
+ # +kwargs+ or a +blk+, and returns +retval+.
49
59
  #
50
60
  # @mock.expect(:meaning_of_life, 42)
51
61
  # @mock.meaning_of_life # => 42
@@ -78,15 +88,31 @@ module Minitest # :nodoc:
78
88
  # @mock.ordinal_increment # => raises MockExpectationError "No more expects available for :ordinal_increment"
79
89
  #
80
90
 
81
- def expect name, retval, args = [], &blk
91
+ def expect name, retval, args = [], **kwargs, &blk
82
92
  name = name.to_sym
83
93
 
84
94
  if block_given?
85
95
  raise ArgumentError, "args ignored when block given" unless args.empty?
96
+ raise ArgumentError, "kwargs ignored when block given" unless kwargs.empty?
86
97
  @expected_calls[name] << { :retval => retval, :block => blk }
87
98
  else
88
99
  raise ArgumentError, "args must be an array" unless Array === args
89
- @expected_calls[name] << { :retval => retval, :args => args }
100
+
101
+ if ENV["MT_KWARGS_HAC\K"] && (Hash === args.last ||
102
+ Hash == args.last) then
103
+ if kwargs.empty? then
104
+ kwargs = args.pop
105
+ else
106
+ unless @@KW_WARNED then
107
+ from = caller.first
108
+ warn "Using MT_KWARGS_HAC\K yet passing kwargs. From #{from}"
109
+ @@KW_WARNED = true
110
+ end
111
+ end
112
+ end
113
+
114
+ @expected_calls[name] <<
115
+ { :retval => retval, :args => args, :kwargs => kwargs }
90
116
  end
91
117
  self
92
118
  end
@@ -94,7 +120,13 @@ module Minitest # :nodoc:
94
120
  def __call name, data # :nodoc:
95
121
  case data
96
122
  when Hash then
97
- "#{name}(#{data[:args].inspect[1..-2]}) => #{data[:retval].inspect}"
123
+ args = data[:args].inspect[1..-2]
124
+ kwargs = data[:kwargs]
125
+ if kwargs && !kwargs.empty? then
126
+ args << ", " unless args.empty?
127
+ args << kwargs.inspect[1..-2]
128
+ end
129
+ "#{name}(#{args}) => #{data[:retval].inspect}"
98
130
  else
99
131
  data.map { |d| __call name, d }.join ", "
100
132
  end
@@ -115,10 +147,14 @@ module Minitest # :nodoc:
115
147
  true
116
148
  end
117
149
 
118
- def method_missing sym, *args, &block # :nodoc:
150
+ def method_missing sym, *args, **kwargs, &block # :nodoc:
119
151
  unless @expected_calls.key?(sym) then
120
152
  if @delegator && @delegator.respond_to?(sym)
121
- return @delegator.public_send(sym, *args, &block)
153
+ if kwargs.empty? then # FIX: drop this after 2.7 dead
154
+ return @delegator.public_send(sym, *args, &block)
155
+ else
156
+ return @delegator.public_send(sym, *args, **kwargs, &block)
157
+ end
122
158
  else
123
159
  raise NoMethodError, "unmocked method %p, expected one of %p" %
124
160
  [sym, @expected_calls.keys.sort_by(&:to_s)]
@@ -129,26 +165,34 @@ module Minitest # :nodoc:
129
165
  expected_call = @expected_calls[sym][index]
130
166
 
131
167
  unless expected_call then
132
- raise MockExpectationError, "No more expects available for %p: %p" %
133
- [sym, args]
168
+ raise MockExpectationError, "No more expects available for %p: %p %p" %
169
+ [sym, args, kwargs]
134
170
  end
135
171
 
136
- expected_args, retval, val_block =
137
- expected_call.values_at(:args, :retval, :block)
172
+ expected_args, expected_kwargs, retval, val_block =
173
+ expected_call.values_at(:args, :kwargs, :retval, :block)
174
+
175
+ expected_kwargs = kwargs.map { |ak, av| [ak, Object] }.to_h if
176
+ Hash == expected_kwargs
138
177
 
139
178
  if val_block then
140
179
  # keep "verify" happy
141
180
  @actual_calls[sym] << expected_call
142
181
 
143
- raise MockExpectationError, "mocked method %p failed block w/ %p" %
144
- [sym, args] unless val_block.call(*args, &block)
182
+ raise MockExpectationError, "mocked method %p failed block w/ %p %p" %
183
+ [sym, args, kwargs] unless val_block.call(*args, **kwargs, &block)
145
184
 
146
185
  return retval
147
186
  end
148
187
 
149
188
  if expected_args.size != args.size then
150
- raise ArgumentError, "mocked method %p expects %d arguments, got %d" %
151
- [sym, expected_args.size, args.size]
189
+ raise ArgumentError, "mocked method %p expects %d arguments, got %p" %
190
+ [sym, expected_args.size, args]
191
+ end
192
+
193
+ if expected_kwargs.size != kwargs.size then
194
+ raise ArgumentError, "mocked method %p expects %d keyword arguments, got %p" %
195
+ [sym, expected_kwargs.size, kwargs]
152
196
  end
153
197
 
154
198
  zipped_args = expected_args.zip(args)
@@ -157,13 +201,33 @@ module Minitest # :nodoc:
157
201
  }
158
202
 
159
203
  unless fully_matched then
160
- raise MockExpectationError, "mocked method %p called with unexpected arguments %p" %
161
- [sym, args]
204
+ fmt = "mocked method %p called with unexpected arguments %p"
205
+ raise MockExpectationError, fmt % [sym, args]
206
+ end
207
+
208
+ unless expected_kwargs.keys.sort == kwargs.keys.sort then
209
+ fmt = "mocked method %p called with unexpected keywords %p vs %p"
210
+ raise MockExpectationError, fmt % [sym, expected_kwargs.keys, kwargs.keys]
211
+ end
212
+
213
+ zipped_kwargs = expected_kwargs.map { |ek, ev|
214
+ av = kwargs[ek]
215
+ [ek, [ev, av]]
216
+ }.to_h
217
+
218
+ fully_matched = zipped_kwargs.all? { |ek, (ev, av)|
219
+ ev === av or ev == av
220
+ }
221
+
222
+ unless fully_matched then
223
+ fmt = "mocked method %p called with unexpected keyword arguments %p vs %p"
224
+ raise MockExpectationError, fmt % [sym, expected_kwargs, kwargs]
162
225
  end
163
226
 
164
227
  @actual_calls[sym] << {
165
228
  :retval => retval,
166
- :args => zipped_args.map! { |mod, a| mod === a ? mod : a },
229
+ :args => zipped_args.map { |e, a| e === a ? e : a },
230
+ :kwargs => zipped_kwargs.map { |k, (e, a)| [k, e === a ? e : a] }.to_h,
167
231
  }
168
232
 
169
233
  retval
@@ -207,31 +271,54 @@ class Object
207
271
  # assert obj_under_test.stale?
208
272
  # end
209
273
  # end
210
- #
274
+ #--
275
+ # NOTE: keyword args in callables are NOT checked for correctness
276
+ # against the existing method. Too many edge cases to be worth it.
211
277
 
212
- def stub name, val_or_callable, *block_args
278
+ def stub name, val_or_callable, *block_args, **block_kwargs, &block
213
279
  new_name = "__minitest_stub__#{name}"
214
280
 
215
281
  metaclass = class << self; self; end
216
282
 
217
283
  if respond_to? name and not methods.map(&:to_s).include? name.to_s then
218
- metaclass.send :define_method, name do |*args|
219
- super(*args)
284
+ metaclass.send :define_method, name do |*args, **kwargs|
285
+ super(*args, **kwargs)
220
286
  end
221
287
  end
222
288
 
223
289
  metaclass.send :alias_method, new_name, name
224
290
 
225
- metaclass.send :define_method, name do |*args, &blk|
226
- if val_or_callable.respond_to? :call then
227
- val_or_callable.call(*args, &blk)
228
- else
229
- blk.call(*block_args) if blk
230
- val_or_callable
291
+ if ENV["MT_KWARGS_HAC\K"] then
292
+ metaclass.send :define_method, name do |*args, &blk|
293
+ if val_or_callable.respond_to? :call then
294
+ val_or_callable.call(*args, &blk)
295
+ else
296
+ blk.call(*block_args, **block_kwargs) if blk
297
+ val_or_callable
298
+ end
299
+ end
300
+ else
301
+ metaclass.send :define_method, name do |*args, **kwargs, &blk|
302
+ if val_or_callable.respond_to? :call then
303
+ if kwargs.empty? then # FIX: drop this after 2.7 dead
304
+ val_or_callable.call(*args, &blk)
305
+ else
306
+ val_or_callable.call(*args, **kwargs, &blk)
307
+ end
308
+ else
309
+ if blk then
310
+ if block_kwargs.empty? then # FIX: drop this after 2.7 dead
311
+ blk.call(*block_args)
312
+ else
313
+ blk.call(*block_args, **block_kwargs)
314
+ end
315
+ end
316
+ val_or_callable
317
+ end
231
318
  end
232
319
  end
233
320
 
234
- yield self
321
+ block[self]
235
322
  ensure
236
323
  metaclass.send :undef_method, name
237
324
  metaclass.send :alias_method, name, new_name
@@ -48,7 +48,7 @@ module Minitest
48
48
  def initialize io # :nodoc:
49
49
  @io = io
50
50
  # stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm
51
- # also reference http://en.wikipedia.org/wiki/ANSI_escape_code
51
+ # also reference https://en.wikipedia.org/wiki/ANSI_escape_code
52
52
  @colors ||= (31..36).to_a
53
53
  @size = @colors.size
54
54
  @index = 0
data/lib/minitest/spec.rb CHANGED
@@ -4,15 +4,21 @@ class Module # :nodoc:
4
4
  def infect_an_assertion meth, new_name, dont_flip = false # :nodoc:
5
5
  block = dont_flip == :block
6
6
  dont_flip = false if block
7
+ target_obj = block ? '_{obj.method}' : '_(obj)'
8
+
9
+ # https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html
10
+ # Drop this when we can drop ruby 2.6 (aka after rails 6.1 EOL, ~2024-06)
11
+ kw_extra = "ruby2_keywords %p" % [new_name] if respond_to?(:ruby2_keywords, true)
7
12
 
8
13
  # warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
9
14
  self.class_eval <<-EOM, __FILE__, __LINE__ + 1
10
15
  def #{new_name} *args
11
16
  where = Minitest.filter_backtrace(caller).first
12
17
  where = where.split(/:in /, 2).first # clean up noise
13
- warn "DEPRECATED: global use of #{new_name} from #\{where}. Use _(obj).#{new_name} instead. This will fail in Minitest 6."
18
+ Kernel.warn "DEPRECATED: global use of #{new_name} from #\{where}. Use #{target_obj}.#{new_name} instead. This will fail in Minitest 6."
14
19
  Minitest::Expectation.new(self, Minitest::Spec.current).#{new_name}(*args)
15
20
  end
21
+ #{kw_extra}
16
22
  EOM
17
23
 
18
24
  Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
@@ -27,6 +33,7 @@ class Module # :nodoc:
27
33
  ctx.#{meth}(args.first, target, *args[1..-1])
28
34
  end
29
35
  end
36
+ #{kw_extra}
30
37
  EOM
31
38
  end
32
39
  end
@@ -65,7 +72,7 @@ module Kernel
65
72
  #
66
73
  # For some suggestions on how to improve your specs, try:
67
74
  #
68
- # http://betterspecs.org
75
+ # https://betterspecs.org
69
76
  #
70
77
  # but do note that several items there are debatable or specific to
71
78
  # rspec.
data/lib/minitest/test.rb CHANGED
@@ -18,6 +18,10 @@ module Minitest
18
18
 
19
19
  PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, SystemExit] # :nodoc:
20
20
 
21
+ SETUP_METHODS = %w[ before_setup setup after_setup ] # :nodoc:
22
+
23
+ TEARDOWN_METHODS = %w[ before_teardown teardown after_teardown ] # :nodoc:
24
+
21
25
  # :stopdoc:
22
26
  class << self; attr_accessor :io_lock; end
23
27
  self.io_lock = Mutex.new
@@ -67,8 +71,8 @@ module Minitest
67
71
 
68
72
  case self.test_order
69
73
  when :random, :parallel then
70
- max = methods.size
71
- methods.sort.sort_by { rand max }
74
+ srand Minitest.seed
75
+ methods.sort.shuffle
72
76
  when :alpha, :sorted then
73
77
  methods.sort
74
78
  else
@@ -84,8 +88,6 @@ module Minitest
84
88
  :random
85
89
  end
86
90
 
87
- TEARDOWN_METHODS = %w[ before_teardown teardown after_teardown ] # :nodoc:
88
-
89
91
  ##
90
92
  # Runs a single test with setup/teardown hooks.
91
93
 
@@ -93,7 +95,9 @@ module Minitest
93
95
  with_info_handler do
94
96
  time_it do
95
97
  capture_exceptions do
96
- before_setup; setup; after_setup
98
+ SETUP_METHODS.each do |hook|
99
+ self.send hook
100
+ end
97
101
 
98
102
  self.send self.name
99
103
  end
@@ -198,7 +202,39 @@ module Minitest
198
202
  rescue Assertion => e
199
203
  self.failures << e
200
204
  rescue Exception => e
201
- self.failures << UnexpectedError.new(e)
205
+ self.failures << UnexpectedError.new(sanitize_exception e)
206
+ end
207
+
208
+ def sanitize_exception e # :nodoc:
209
+ Marshal.dump e
210
+ e # good: use as-is
211
+ rescue
212
+ neuter_exception e
213
+ end
214
+
215
+ def neuter_exception e # :nodoc:
216
+ bt = e.backtrace
217
+ msg = e.message.dup
218
+
219
+ new_exception e.class, msg, bt # e.class can be a problem...
220
+ rescue
221
+ msg.prepend "Neutered Exception #{e.class}: "
222
+
223
+ new_exception RuntimeError, msg, bt, true # but if this raises, we die
224
+ end
225
+
226
+ def new_exception klass, msg, bt, kill = false # :nodoc:
227
+ ne = klass.new msg
228
+ ne.set_backtrace bt
229
+
230
+ if kill then
231
+ ne.instance_variables.each do |v|
232
+ ne.remove_instance_variable v
233
+ end
234
+ end
235
+
236
+ Marshal.dump ne # can raise TypeError
237
+ ne
202
238
  end
203
239
 
204
240
  def with_info_handler &block # :nodoc: