test-unit-ruby-core 1.0.13 → 1.0.15

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/core_assertions.rb +37 -12
  3. data/lib/envutil.rb +16 -5
  4. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29365462eba565b84ef3473c3ac7a3bf2411c0b537a292eaf28a33329e69d746
4
- data.tar.gz: ffa994c78613ee85efc4b35e8c3b418b5fe8e9258204d57f787068fade7ec7b8
3
+ metadata.gz: a1eb02b12f2087ce0b57f694b7c870b1008fe839c062414a97f4dc3c03b81ef5
4
+ data.tar.gz: 3240de73b9ba06bdd61c06176dbf7d8f4018307361bcecf1adc2cbd2869b0fc9
5
5
  SHA512:
6
- metadata.gz: cc85ccee8dfefe70ea01e6167d8e73b4d4ef0dced1239e5d066812052f9f468a451fedc3cf26ae1289d147d96cd4e2c57c536c8b0661bbf915863882758a953e
7
- data.tar.gz: 83f4fb10dd0c64bae14aafc5f700f36fce22d39ea6cc152a8dec15fa8b673a6704863dd607cc103175f0ec8bf41ef6e16b28ba6351886c2a7cd5131345109ae3
6
+ metadata.gz: 2bd171029578123c653b6e85391cbade78f9d1670a5ff74e0b828432a738b6805ebcee6ffa34a9dee8cc20e5dbcd72cabdbc54078136a32340cafce88b157050
7
+ data.tar.gz: 196878eefb77c3982c1911ee3a06d731a15de99a07050d77892daa54f4beb47c6c6fa870e524bb4bfe8a72ed177efa20a9083e84aa8d077b23c642ef109b425c
@@ -303,9 +303,34 @@ module Test
303
303
 
304
304
  def separated_runner(token, out = nil)
305
305
  include(*Test::Unit::TestCase.ancestors.select {|c| !c.is_a?(Class) })
306
+
306
307
  out = out ? IO.new(out, 'w') : STDOUT
308
+
309
+ # avoid method redefinitions
310
+ out_write = out.method(:write)
311
+ integer_to_s = Integer.instance_method(:to_s)
312
+ array_pack = Array.instance_method(:pack)
313
+ marshal_dump = Marshal.method(:dump)
314
+ assertions_ivar_set = Test::Unit::Assertions.method(:instance_variable_set)
315
+ assertions_ivar_get = Test::Unit::Assertions.method(:instance_variable_get)
316
+ Test::Unit::Assertions.module_eval do
317
+ @_assertions = 0
318
+
319
+ undef _assertions=
320
+ define_method(:_assertions=, ->(n) {assertions_ivar_set.call(:@_assertions, n)})
321
+
322
+ undef _assertions
323
+ define_method(:_assertions, -> {assertions_ivar_get.call(:@_assertions)})
324
+ end
325
+ # assume Method#call and UnboundMethod#bind_call need to work as the original
326
+
307
327
  at_exit {
308
- out.puts "#{token}<error>", [Marshal.dump($!)].pack('m'), "#{token}</error>", "#{token}assertions=#{self._assertions}"
328
+ assertions = assertions_ivar_get.call(:@_assertions)
329
+ out_write.call <<~OUT
330
+ <error id="#{token}" assertions=#{integer_to_s.bind_call(assertions)}>
331
+ #{array_pack.bind_call([marshal_dump.call($!)], 'm0')}
332
+ </error id="#{token}">
333
+ OUT
309
334
  }
310
335
  if defined?(Test::Unit::Runner)
311
336
  Test::Unit::Runner.class_variable_set(:@@stop_auto_run, true)
@@ -339,8 +364,6 @@ eom
339
364
  args = args.dup
340
365
  args.insert((Hash === args.first ? 1 : 0), "-w", "--disable=gems", *$:.map {|l| "-I#{l}"})
341
366
  args << "--debug" if RUBY_ENGINE == 'jruby' # warning: tracing (e.g. set_trace_func) will not capture all events without --debug flag
342
- # power_assert 3 requires ruby 3.1 or later
343
- args << "-W:no-experimental" if RUBY_VERSION < "3.1."
344
367
  stdout, stderr, status = EnvUtil.invoke_ruby(args, src, capture_stdout, true, **opt)
345
368
 
346
369
  if sanitizers&.lsan_enabled?
@@ -359,15 +382,16 @@ eom
359
382
  end
360
383
  raise if $!
361
384
  abort = status.coredump? || (status.signaled? && ABORT_SIGNALS.include?(status.termsig))
385
+ marshal_error = nil
362
386
  assert(!abort, FailDesc[status, nil, stderr])
363
- self._assertions += res[/^#{token_re}assertions=(\d+)/, 1].to_i
364
- begin
365
- res = Marshal.load(res[/^#{token_re}<error>\n\K.*\n(?=#{token_re}<\/error>$)/m].unpack1("m"))
387
+ res.scan(/^<error id="#{token_re}" assertions=(\d+)>\n(.*?)\n(?=<\/error id="#{token_re}">$)/m) do
388
+ self._assertions += $1.to_i
389
+ res = Marshal.load($2.unpack1("m")) or next
366
390
  rescue => marshal_error
367
391
  ignore_stderr = nil
368
392
  res = nil
369
- end
370
- if res and !(SystemExit === res)
393
+ else
394
+ next if SystemExit === res
371
395
  if bt = res.backtrace
372
396
  bt.each do |l|
373
397
  l.sub!(/\A-:(\d+)/){"#{file}:#{line + $1.to_i}"}
@@ -379,7 +403,7 @@ eom
379
403
  raise res
380
404
  end
381
405
 
382
- # really is it succeed?
406
+ # really did it succeed?
383
407
  unless ignore_stderr
384
408
  # the body of assert_separately must not output anything to detect error
385
409
  assert(stderr.empty?, FailDesc[status, "assert_separately failed with error message", stderr])
@@ -390,7 +414,7 @@ eom
390
414
 
391
415
  # Run Ractor-related test without influencing the main test suite
392
416
  def assert_ractor(src, args: [], require: nil, require_relative: nil, file: nil, line: nil, ignore_stderr: nil, **opt)
393
- return unless defined?(Ractor)
417
+ omit unless defined?(Ractor)
394
418
 
395
419
  # https://bugs.ruby-lang.org/issues/21262
396
420
  shim_value = "class Ractor; alias value take; end" unless Ractor.method_defined?(:value)
@@ -885,10 +909,11 @@ eom
885
909
 
886
910
  first = seq.first
887
911
  *arg = pre.call(first)
888
- times = (0..(rehearsal || (2 * first))).map do
912
+ raw_times = (0..(rehearsal || (2 * first))).map do
889
913
  measure[arg, "rehearsal"].nonzero?
890
914
  end
891
- times.compact!
915
+ times = raw_times.compact
916
+ raise "all measurements are zero: #{raw_times.inspect}" if times.empty?
892
917
  tmin, tmax = times.minmax
893
918
 
894
919
  # safe_factor * tmax * rehearsal_time_variance_factor(equals to 1 when variance is small)
data/lib/envutil.rb CHANGED
@@ -63,6 +63,14 @@ module EnvUtil
63
63
  end
64
64
  end
65
65
 
66
+ if RUBY_ENGINE == "truffleruby"
67
+ # Tests relying on timeout have high variance on TruffleRuby due to the highly-optimizing JIT, deoptimization, profiling interpreter, different GC, etc.
68
+ # Setting a default timeout scale helps avoid transient failures for tests relying on timeouts.
69
+ # We choose 10 because it is the same number used in CRuby CI on macOS:
70
+ # https://github.com/ruby/ruby/blob/9d46b0c735877f152a0b4b16b8153c6f395dee28/.github/workflows/macos.yml#L133
71
+ self.timeout_scale = 10
72
+ end
73
+
66
74
  def apply_timeout_scale(t)
67
75
  if scale = EnvUtil.timeout_scale
68
76
  t * scale
@@ -122,7 +130,7 @@ module EnvUtil
122
130
 
123
131
  register("gdb") do
124
132
  class << self
125
- def usable?; system(*%w[gdb --batch --quiet --nx -ex exit]); end
133
+ def usable?; system(*%w[gdb --batch --quiet --nx -ex exit], out: IO::NULL, err: IO::NULL); end
126
134
  def start(pid, *args, **opts)
127
135
  spawn(*%W[gdb --batch --quiet --pid #{pid}], *args, **opts)
128
136
  end
@@ -132,7 +140,7 @@ module EnvUtil
132
140
 
133
141
  register("lldb") do
134
142
  class << self
135
- def usable?; system(*%w[lldb -Q --no-lldbinit -o exit]); end
143
+ def usable?; system(*%w[lldb -Q --no-lldbinit -o exit], out: IO::NULL, err: IO::NULL); end
136
144
  def start(pid, *args, **opts)
137
145
  spawn(*%W[lldb --batch -Q --attach-pid #{pid}], *args, **opts)
138
146
  end
@@ -141,7 +149,10 @@ module EnvUtil
141
149
  end
142
150
 
143
151
  def self.search
144
- @debugger ||= @list.find(&:usable?)
152
+ # Cache the result even when no debugger is available, not to probe
153
+ # unusable debuggers repeatedly.
154
+ return @debugger if defined?(@debugger)
155
+ @debugger = @list.find(&:usable?)
145
156
  end
146
157
  end
147
158
 
@@ -228,7 +239,7 @@ module EnvUtil
228
239
  args = [args] if args.kind_of?(String)
229
240
  # use the same parser as current ruby
230
241
  if (args.none? { |arg| arg.start_with?("--parser=") } and
231
- /^ +--parser=/ =~ IO.popen([rubybin, "--help"], &:read))
242
+ /^ +--parser=/ =~ IO.popen([{"PAGER"=>nil, "RUBY_PAGER"=>nil}, rubybin, "--help", err: %i[child out]], &:read))
232
243
  args = ["--parser=#{current_parser}"] + args
233
244
  end
234
245
  pid = spawn(child_env, *precommand, rubybin, *args, opt)
@@ -279,7 +290,7 @@ module EnvUtil
279
290
  module_function :invoke_ruby
280
291
 
281
292
  def current_parser
282
- features = RUBY_DESCRIPTION[%r{\)\K [-+*/%._0-9a-zA-Z ]*(?=\[[-+*/%._0-9a-zA-Z]+\]\z)}]
293
+ features = RUBY_DESCRIPTION[%r{\)\K [-+*/%._0-9a-zA-Z\[\] ]*(?=\[[-+*/%._0-9a-zA-Z]+\]\z)}]
283
294
  features&.split&.include?("+PRISM") ? "prism" : "parse.y"
284
295
  end
285
296
  module_function :current_parser
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test-unit-ruby-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.13
4
+ version: 1.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi SHIBATA
8
8
  - Nobu Nakada
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-11-12 00:00:00.000000000 Z
11
+ date: 2026-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 3.7.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 3.7.2
27
27
  description: Additional test assertions for Ruby standard libraries.
28
28
  email:
29
29
  - hsbt@ruby-lang.org