From 56edb86bc7119251619550fcf621d0ed81a97d05 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Wed, 6 Nov 2024 22:00:32 +0100 Subject: [PATCH 1/4] Update to ruby/mspec@6499325 --- spec/mspec/lib/mspec/guards/platform.rb | 24 ++++++++++-- spec/mspec/lib/mspec/helpers/numeric.rb | 26 +++++++++++-- .../lib/mspec/runner/actions/leakchecker.rb | 6 +-- spec/mspec/spec/guards/platform_spec.rb | 38 +++++++++---------- 4 files changed, 65 insertions(+), 29 deletions(-) diff --git a/spec/mspec/lib/mspec/guards/platform.rb b/spec/mspec/lib/mspec/guards/platform.rb index e87b08a4c131..fadd8d75efb8 100644 --- a/spec/mspec/lib/mspec/guards/platform.rb +++ b/spec/mspec/lib/mspec/guards/platform.rb @@ -53,16 +53,27 @@ def self.wsl? end end + # In bits WORD_SIZE = 1.size * 8 + deprecate_constant :WORD_SIZE + # In bits POINTER_SIZE = begin require 'rbconfig/sizeof' RbConfig::SIZEOF["void*"] * 8 rescue LoadError - WORD_SIZE + [0].pack('j').size * 8 + end + + # In bits + C_LONG_SIZE = if defined?(RbConfig::SIZEOF[]) + RbConfig::SIZEOF["long"] * 8 + else + [0].pack('l!').size * 8 end def self.wordsize?(size) + warn "#wordsize? is deprecated, use #c_long_size?" size == WORD_SIZE end @@ -70,6 +81,10 @@ def self.pointer_size?(size) size == POINTER_SIZE end + def self.c_long_size?(size) + size == C_LONG_SIZE + end + def initialize(*args) if args.last.is_a?(Hash) @options, @platforms = args.last, args[0..-2] @@ -85,10 +100,13 @@ def match? case key when :os match &&= PlatformGuard.os?(*value) - when :wordsize - match &&= PlatformGuard.wordsize? value when :pointer_size match &&= PlatformGuard.pointer_size? value + when :wordsize + warn ":wordsize is deprecated, use :c_long_size" + match &&= PlatformGuard.wordsize? value + when :c_long_size + match &&= PlatformGuard::c_long_size? value end end match diff --git a/spec/mspec/lib/mspec/helpers/numeric.rb b/spec/mspec/lib/mspec/helpers/numeric.rb index c1ed81a2332d..0b47855cd294 100644 --- a/spec/mspec/lib/mspec/helpers/numeric.rb +++ b/spec/mspec/lib/mspec/helpers/numeric.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require 'mspec/guards/platform' def nan_value @@ -15,11 +16,11 @@ def bignum_value(plus = 0) end def max_long - 2**(0.size * 8 - 1) - 1 + 2**(PlatformGuard::C_LONG_SIZE - 1) - 1 end def min_long - -(2**(0.size * 8 - 1)) + -(2**(PlatformGuard::C_LONG_SIZE - 1)) end # This is a bit hairy, but we need to be able to write specs that cover the @@ -28,7 +29,24 @@ def min_long # specs based on the relationship between values rather than specific # values. if PlatformGuard.standard? or PlatformGuard.implementation? :topaz - if PlatformGuard.wordsize? 32 + limits_available = begin + require 'rbconfig/sizeof' + defined?(RbConfig::LIMITS.[]) && ['FIXNUM_MAX', 'FIXNUM_MIN'].all? do |key| + Integer === RbConfig::LIMITS[key] + end + rescue LoadError + false + end + + if limits_available + def fixnum_max + RbConfig::LIMITS['FIXNUM_MAX'] + end + + def fixnum_min + RbConfig::LIMITS['FIXNUM_MIN'] + end + elsif PlatformGuard.c_long_size? 32 def fixnum_max (2**30) - 1 end @@ -36,7 +54,7 @@ def fixnum_max def fixnum_min -(2**30) end - elsif PlatformGuard.wordsize? 64 + elsif PlatformGuard.c_long_size? 64 def fixnum_max (2**62) - 1 end diff --git a/spec/mspec/lib/mspec/runner/actions/leakchecker.rb b/spec/mspec/lib/mspec/runner/actions/leakchecker.rb index 71797b9815cb..0a8c9c325213 100644 --- a/spec/mspec/lib/mspec/runner/actions/leakchecker.rb +++ b/spec/mspec/lib/mspec/runner/actions/leakchecker.rb @@ -132,14 +132,14 @@ class << self attr_accessor :count end - def new(data) + def new(...) LeakChecker::TempfileCounter.count += 1 - super(data) + super end } LeakChecker.const_set(:TempfileCounter, m) - class << Tempfile::Remover + class << Tempfile prepend LeakChecker::TempfileCounter end end diff --git a/spec/mspec/spec/guards/platform_spec.rb b/spec/mspec/spec/guards/platform_spec.rb index 88a7ad86f230..bd3743280045 100644 --- a/spec/mspec/spec/guards/platform_spec.rb +++ b/spec/mspec/spec/guards/platform_spec.rb @@ -81,44 +81,44 @@ end end -RSpec.describe Object, "#platform_is :wordsize => SIZE_SPEC" do +RSpec.describe Object, "#platform_is :c_long_size => SIZE_SPEC" do before :each do - @guard = PlatformGuard.new :darwin, :wordsize => 32 + @guard = PlatformGuard.new :darwin, :c_long_size => 32 allow(PlatformGuard).to receive(:os?).and_return(true) allow(PlatformGuard).to receive(:new).and_return(@guard) ScratchPad.clear end - it "yields when #wordsize? returns true" do - allow(PlatformGuard).to receive(:wordsize?).and_return(true) - platform_is(:wordsize => 32) { ScratchPad.record :yield } + it "yields when #c_long_size? returns true" do + allow(PlatformGuard).to receive(:c_long_size?).and_return(true) + platform_is(:c_long_size => 32) { ScratchPad.record :yield } expect(ScratchPad.recorded).to eq(:yield) end - it "doesn not yield when #wordsize? returns false" do - allow(PlatformGuard).to receive(:wordsize?).and_return(false) - platform_is(:wordsize => 32) { ScratchPad.record :yield } + it "doesn not yield when #c_long_size? returns false" do + allow(PlatformGuard).to receive(:c_long_size?).and_return(false) + platform_is(:c_long_size => 32) { ScratchPad.record :yield } expect(ScratchPad.recorded).not_to eq(:yield) end end -RSpec.describe Object, "#platform_is_not :wordsize => SIZE_SPEC" do +RSpec.describe Object, "#platform_is_not :c_long_size => SIZE_SPEC" do before :each do - @guard = PlatformGuard.new :darwin, :wordsize => 32 + @guard = PlatformGuard.new :darwin, :c_long_size => 32 allow(PlatformGuard).to receive(:os?).and_return(true) allow(PlatformGuard).to receive(:new).and_return(@guard) ScratchPad.clear end - it "yields when #wordsize? returns false" do - allow(PlatformGuard).to receive(:wordsize?).and_return(false) - platform_is_not(:wordsize => 32) { ScratchPad.record :yield } + it "yields when #c_long_size? returns false" do + allow(PlatformGuard).to receive(:c_long_size?).and_return(false) + platform_is_not(:c_long_size => 32) { ScratchPad.record :yield } expect(ScratchPad.recorded).to eq(:yield) end - it "doesn not yield when #wordsize? returns true" do - allow(PlatformGuard).to receive(:wordsize?).and_return(true) - platform_is_not(:wordsize => 32) { ScratchPad.record :yield } + it "doesn not yield when #c_long_size? returns true" do + allow(PlatformGuard).to receive(:c_long_size?).and_return(true) + platform_is_not(:c_long_size => 32) { ScratchPad.record :yield } expect(ScratchPad.recorded).not_to eq(:yield) end end @@ -184,13 +184,13 @@ end end -RSpec.describe PlatformGuard, ".wordsize?" do +RSpec.describe PlatformGuard, ".c_long_size?" do it "returns true when arg is 32 and 1.size is 4" do - expect(PlatformGuard.wordsize?(32)).to eq(1.size == 4) + expect(PlatformGuard.c_long_size?(32)).to eq(1.size == 4) end it "returns true when arg is 64 and 1.size is 8" do - expect(PlatformGuard.wordsize?(64)).to eq(1.size == 8) + expect(PlatformGuard.c_long_size?(64)).to eq(1.size == 8) end end From 41c86903e643010f22037ec67da2e2a844e3e4e4 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Wed, 6 Nov 2024 22:00:35 +0100 Subject: [PATCH 2/4] Update to ruby/spec@54c391e --- spec/ruby/.mspec.constants | 1 + spec/ruby/.rubocop.yml | 18 + spec/ruby/.rubocop_todo.yml | 44 +-- spec/ruby/CONTRIBUTING.md | 6 +- spec/ruby/bin/rubocop | 12 + spec/ruby/command_line/fixtures/debug_info.rb | 1 - spec/ruby/command_line/frozen_strings_spec.rb | 13 +- spec/ruby/command_line/rubyopt_spec.rb | 6 +- spec/ruby/core/array/fetch_values_spec.rb | 48 +++ spec/ruby/core/array/pack/l_spec.rb | 16 +- spec/ruby/core/array/pack/shared/integer.rb | 4 +- .../core/basicobject/instance_exec_spec.rb | 20 +- .../builtin_constants_spec.rb | 28 ++ spec/ruby/core/complex/equal_value_spec.rb | 2 +- spec/ruby/core/data/to_h_spec.rb | 65 ++++ spec/ruby/core/encoding/compatible_spec.rb | 66 ++-- .../core/enumerator/each_with_index_spec.rb | 6 +- spec/ruby/core/enumerator/with_index_spec.rb | 17 + spec/ruby/core/fiber/raise_spec.rb | 2 +- spec/ruby/core/file/chown_spec.rb | 16 +- spec/ruby/core/file/shared/update_time.rb | 2 +- spec/ruby/core/float/ceil_spec.rb | 5 + spec/ruby/core/float/comparison_spec.rb | 2 +- spec/ruby/core/float/floor_spec.rb | 5 + spec/ruby/core/hash/element_reference_spec.rb | 2 +- spec/ruby/core/hash/hash_spec.rb | 2 +- spec/ruby/core/hash/new_spec.rb | 20 +- spec/ruby/core/hash/shared/to_s.rb | 46 ++- spec/ruby/core/integer/ceil_spec.rb | 5 + spec/ruby/core/integer/floor_spec.rb | 12 +- spec/ruby/core/integer/pow_spec.rb | 8 +- spec/ruby/core/integer/remainder_spec.rb | 4 +- spec/ruby/core/integer/round_spec.rb | 6 +- .../integer/shared/integer_ceil_precision.rb | 43 +++ .../integer/shared/integer_floor_precision.rb | 43 +++ spec/ruby/core/integer/size_spec.rb | 4 +- spec/ruby/core/io/dup_spec.rb | 30 +- spec/ruby/core/io/puts_spec.rb | 2 +- spec/ruby/core/io/read_spec.rb | 22 +- spec/ruby/core/kernel/format_spec.rb | 32 ++ spec/ruby/core/kernel/select_spec.rb | 4 +- spec/ruby/core/kernel/sleep_spec.rb | 14 + spec/ruby/core/marshal/dump_spec.rb | 2 +- .../core/marshal/fixtures/marshal_data.rb | 14 +- .../fixtures/marshal_multibyte_data.rb | 12 + spec/ruby/core/marshal/shared/load.rb | 2 +- spec/ruby/core/module/name_spec.rb | 4 +- spec/ruby/core/module/new_spec.rb | 4 + spec/ruby/core/module/refine_spec.rb | 2 +- .../core/objectspace/add_finalizer_spec.rb | 5 - .../core/objectspace/call_finalizer_spec.rb | 5 - .../core/objectspace/define_finalizer_spec.rb | 25 ++ spec/ruby/core/objectspace/finalizers_spec.rb | 5 - .../core/objectspace/remove_finalizer_spec.rb | 5 - .../objectspace/undefine_finalizer_spec.rb | 30 +- spec/ruby/core/proc/curry_spec.rb | 9 +- spec/ruby/core/process/constants_spec.rb | 116 +++--- spec/ruby/core/process/daemon_spec.rb | 3 + spec/ruby/core/queue/freeze_spec.rb | 6 + spec/ruby/core/range/step_spec.rb | 333 ++++++++++++++---- spec/ruby/core/regexp/shared/new.rb | 4 + spec/ruby/core/regexp/shared/quote.rb | 4 +- spec/ruby/core/sizedqueue/freeze_spec.rb | 6 + spec/ruby/core/string/append_as_bytes_spec.rb | 46 +++ spec/ruby/core/string/byteslice_spec.rb | 2 +- spec/ruby/core/string/modulo_spec.rb | 6 +- spec/ruby/core/string/unpack/l_spec.rb | 16 +- spec/ruby/core/thread/group_spec.rb | 15 +- .../core/thread/thread_variable_get_spec.rb | 13 +- .../core/thread/thread_variable_set_spec.rb | 2 +- spec/ruby/core/thread/thread_variable_spec.rb | 13 +- spec/ruby/core/time/iso8601_spec.rb | 6 + spec/ruby/core/time/new_spec.rb | 10 +- spec/ruby/core/time/shared/xmlschema.rb | 31 ++ spec/ruby/core/time/xmlschema_spec.rb | 6 + spec/ruby/core/tracepoint/inspect_spec.rb | 2 +- spec/ruby/fixtures/constants.rb | 2 +- spec/ruby/language/fixtures/private.rb | 26 +- spec/ruby/language/fixtures/send.rb | 6 +- spec/ruby/language/pattern_matching_spec.rb | 3 +- spec/ruby/language/precedence_spec.rb | 16 +- spec/ruby/language/regexp_spec.rb | 2 +- spec/ruby/language/super_spec.rb | 2 +- spec/ruby/library/bigdecimal/fix_spec.rb | 28 +- spec/ruby/library/bigdecimal/sqrt_spec.rb | 2 +- spec/ruby/library/date/mon_spec.rb | 3 +- spec/ruby/library/date/month_spec.rb | 6 +- spec/ruby/library/date/shared/month.rb | 6 + spec/ruby/library/erb/new_spec.rb | 2 +- spec/ruby/library/logger/logger/new_spec.rb | 26 +- spec/ruby/library/net-http/http/post_spec.rb | 2 +- .../net-http/http/send_request_spec.rb | 2 +- .../library/objectspace/memsize_of_spec.rb | 2 +- spec/ruby/library/pathname/glob_spec.rb | 8 + spec/ruby/library/pp/pp_spec.rb | 2 +- spec/ruby/library/set/hash_spec.rb | 5 + spec/ruby/library/set/merge_spec.rb | 12 + .../socket/addrinfo/initialize_spec.rb | 2 +- .../library/socket/basicsocket/send_spec.rb | 38 +- .../library/socket/socket/connect_spec.rb | 14 + .../ruby/library/stringio/fixtures/classes.rb | 4 +- spec/ruby/library/stringio/shared/sysread.rb | 2 +- spec/ruby/library/stringio/sysread_spec.rb | 5 + .../library/stringscanner/check_until_spec.rb | 10 +- spec/ruby/library/stringscanner/exist_spec.rb | 10 +- .../library/stringscanner/scan_until_spec.rb | 10 +- .../library/stringscanner/search_full_spec.rb | 10 +- .../library/stringscanner/skip_until_spec.rb | 10 +- spec/ruby/library/time/iso8601_spec.rb | 2 +- spec/ruby/library/time/shared/rfc2822.rb | 24 +- spec/ruby/library/time/shared/xmlschema.rb | 52 +-- spec/ruby/library/time/xmlschema_spec.rb | 2 +- spec/ruby/library/uri/shared/parse.rb | 13 +- spec/ruby/optional/capi/bignum_spec.rb | 26 +- spec/ruby/optional/capi/debug_spec.rb | 7 +- spec/ruby/optional/capi/ext/io_spec.c | 20 +- spec/ruby/optional/capi/fixnum_spec.rb | 4 +- spec/ruby/optional/capi/io_spec.rb | 12 +- spec/ruby/optional/capi/numeric_spec.rb | 8 +- spec/ruby/optional/capi/string_spec.rb | 18 +- spec/ruby/optional/capi/util_spec.rb | 2 +- spec/ruby/security/cve_2020_10663_spec.rb | 9 +- spec/ruby/shared/queue/freeze.rb | 18 + spec/ruby/shared/string/times.rb | 4 +- 124 files changed, 1408 insertions(+), 559 deletions(-) create mode 100755 spec/ruby/bin/rubocop create mode 100644 spec/ruby/core/array/fetch_values_spec.rb create mode 100644 spec/ruby/core/data/to_h_spec.rb create mode 100644 spec/ruby/core/integer/shared/integer_ceil_precision.rb create mode 100644 spec/ruby/core/integer/shared/integer_floor_precision.rb create mode 100644 spec/ruby/core/marshal/fixtures/marshal_multibyte_data.rb delete mode 100644 spec/ruby/core/objectspace/add_finalizer_spec.rb delete mode 100644 spec/ruby/core/objectspace/call_finalizer_spec.rb delete mode 100644 spec/ruby/core/objectspace/finalizers_spec.rb delete mode 100644 spec/ruby/core/objectspace/remove_finalizer_spec.rb create mode 100644 spec/ruby/core/queue/freeze_spec.rb create mode 100644 spec/ruby/core/sizedqueue/freeze_spec.rb create mode 100644 spec/ruby/core/string/append_as_bytes_spec.rb create mode 100644 spec/ruby/core/time/iso8601_spec.rb create mode 100644 spec/ruby/core/time/shared/xmlschema.rb create mode 100644 spec/ruby/core/time/xmlschema_spec.rb create mode 100644 spec/ruby/library/date/shared/month.rb create mode 100644 spec/ruby/shared/queue/freeze.rb diff --git a/spec/ruby/.mspec.constants b/spec/ruby/.mspec.constants index 6e09a44362df..4da36337152b 100644 --- a/spec/ruby/.mspec.constants +++ b/spec/ruby/.mspec.constants @@ -146,6 +146,7 @@ Prime Private ProcFromMethod Psych +RactorLocalSingleton REXML RUBY_SIGNALS RbReadline diff --git a/spec/ruby/.rubocop.yml b/spec/ruby/.rubocop.yml index 5a902e0f0159..a385b5e79c6f 100644 --- a/spec/ruby/.rubocop.yml +++ b/spec/ruby/.rubocop.yml @@ -5,9 +5,13 @@ AllCops: DisplayCopNames: true Exclude: - command_line/fixtures/bad_syntax.rb + - core/exception/fixtures/syntax_error.rb DisabledByDefault: true NewCops: disable +Layout/IndentationConsistency: + Enabled: true + Layout/TrailingWhitespace: Enabled: true @@ -43,9 +47,23 @@ Lint/InterpolationCheck: Lint/LiteralAsCondition: Enabled: false +# Required to support Ruby 3.0 +Lint/RedundantRequireStatement: + Exclude: + - core/fiber/**/*.rb + - library/fiber/**/*.rb + - optional/capi/fiber_spec.rb + +Lint/RedundantSafeNavigation: + Exclude: + - language/safe_navigator_spec.rb + Lint/RedundantSplatExpansion: Enabled: false +Lint/RescueException: + Enabled: false + Lint/UnifiedInteger: Enabled: false diff --git a/spec/ruby/.rubocop_todo.yml b/spec/ruby/.rubocop_todo.yml index 3ebb23a8bb7f..6b43db9b9a4d 100644 --- a/spec/ruby/.rubocop_todo.yml +++ b/spec/ruby/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2019-12-12 22:16:26 +0900 using RuboCop version 0.77.0. +# on 2024-10-12 16:01:45 UTC using RuboCop version 1.66.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -21,6 +21,7 @@ Lint/DuplicateMethods: - 'fixtures/class.rb' # Offense count: 8 +# This cop supports safe autocorrection (--autocorrect). Lint/EnsureReturn: Exclude: - 'language/fixtures/ensure.rb' @@ -39,6 +40,7 @@ Lint/FloatOutOfRange: - 'core/string/modulo_spec.rb' # Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). Lint/ImplicitStringConcatenation: Exclude: - 'language/string_spec.rb' @@ -50,8 +52,8 @@ Lint/IneffectiveAccessModifier: - 'core/module/fixtures/classes.rb' - 'language/fixtures/private.rb' -# Offense count: 72 -# Cop supports --auto-correct. +# Offense count: 71 +# This cop supports safe autocorrection (--autocorrect). Lint/LiteralInInterpolation: Exclude: - 'core/module/refine_spec.rb' @@ -65,47 +67,28 @@ Lint/LiteralInInterpolation: - 'language/undef_spec.rb' # Offense count: 8 -# Cop supports --auto-correct. +# This cop supports safe autocorrection (--autocorrect). Lint/MultipleComparison: Exclude: - 'language/precedence_spec.rb' # Offense count: 9 +# This cop supports safe autocorrection (--autocorrect). Lint/ParenthesesAsGroupedExpression: Exclude: - - 'core/string/fixtures/freeze_magic_comment.rb' - 'language/block_spec.rb' - - 'language/fixtures/send.rb' - 'language/method_spec.rb' # Offense count: 2 -# Cop supports --auto-correct. +# This cop supports safe autocorrection (--autocorrect). Lint/RedundantStringCoercion: Exclude: - 'core/io/print_spec.rb' # Offense count: 1 -# Cop supports --auto-correct. -Lint/RedundantWithIndex: - Exclude: - - 'core/enumerator/with_index_spec.rb' - -# Offense count: 22 -Lint/RescueException: +Lint/SelfAssignment: Exclude: - - 'command_line/fixtures/debug_info.rb' - - 'core/dir/fileno_spec.rb' - - 'core/exception/cause_spec.rb' - - 'core/exception/no_method_error_spec.rb' - - 'core/fiber/kill_spec.rb' - - 'core/kernel/fixtures/autoload_frozen.rb' - - 'core/kernel/raise_spec.rb' - - 'core/module/autoload_spec.rb' - - 'core/mutex/sleep_spec.rb' - - 'core/thread/abort_on_exception_spec.rb' - - 'core/thread/shared/exit.rb' - - 'language/rescue_spec.rb' - - 'library/erb/filename_spec.rb' + - 'core/gc/auto_compact_spec.rb' # Offense count: 4 # Configuration parameters: IgnoreImplicitReferences. @@ -113,8 +96,8 @@ Lint/ShadowedArgument: Exclude: - 'language/fixtures/super.rb' -# Offense count: 39 -# Configuration parameters: AllowComments. +# Offense count: 45 +# Configuration parameters: AllowComments, AllowNil. Lint/SuppressedException: Enabled: false @@ -127,7 +110,8 @@ Lint/UnderscorePrefixedVariableName: - 'language/block_spec.rb' # Offense count: 7 -# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AutoCorrect, ContextCreatingMethods, MethodCreatingMethods. Lint/UselessAccessModifier: Exclude: - 'core/module/define_method_spec.rb' diff --git a/spec/ruby/CONTRIBUTING.md b/spec/ruby/CONTRIBUTING.md index 73fba01de2ef..5c3256948b87 100644 --- a/spec/ruby/CONTRIBUTING.md +++ b/spec/ruby/CONTRIBUTING.md @@ -164,7 +164,7 @@ end platform_is_not :linux, :darwin do # Not Linux and not Darwin end -platform_is wordsize: 64 do +platform_is pointer_size: 64 do # 64-bit platform end @@ -179,7 +179,9 @@ In case there is a bug in MRI and the fix will be backported to previous version If it is not backported or not likely, use `ruby_version_is` instead. First, file a bug at https://bugs.ruby-lang.org/. The problem is `ruby_bug` would make non-MRI implementations fail this spec while MRI itself does not pass it, so it should only be used if the bug is/will be fixed and backported. -Otherwise, non-MRI implementations would have to choose between being incompatible with the latest release of MRI to pass the spec or fail the spec, both which make no sense. +Otherwise, non-MRI implementations would have to choose between being incompatible with the latest release of MRI (which has the bug) to pass the spec, or behave the same as the latest release of MRI (which has the bug) and fail the spec, both which make no sense. + +IOW, `ruby_bug '#NN', ''...'X.Y' do` is equivalent to `guard_not { RUBY_ENGINE == "ruby" && ruby_version_is ''...'X.Y' } do`. So it skips tests on MRI on specified versions (where a bug is present) and runs tests on alternative implementations only. ```ruby ruby_bug '#13669', ''...'3.2' do diff --git a/spec/ruby/bin/rubocop b/spec/ruby/bin/rubocop new file mode 100755 index 000000000000..38254f13e487 --- /dev/null +++ b/spec/ruby/bin/rubocop @@ -0,0 +1,12 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'bundler/inline' + +gemfile do + source 'https://rubygems.org' + + gem 'rubocop', '1.66.1' +end + +exec(Gem.bin_path('rubocop', 'rubocop'), *ARGV) diff --git a/spec/ruby/command_line/fixtures/debug_info.rb b/spec/ruby/command_line/fixtures/debug_info.rb index ee607910c0d8..f02b0419208c 100644 --- a/spec/ruby/command_line/fixtures/debug_info.rb +++ b/spec/ruby/command_line/fixtures/debug_info.rb @@ -1,4 +1,3 @@ -# frozen_string_literal: true a = 'string' b = a c = b diff --git a/spec/ruby/command_line/frozen_strings_spec.rb b/spec/ruby/command_line/frozen_strings_spec.rb index 06889755d254..014153e0b4af 100644 --- a/spec/ruby/command_line/frozen_strings_spec.rb +++ b/spec/ruby/command_line/frozen_strings_spec.rb @@ -57,9 +57,18 @@ describe "The --debug flag produces" do it "debugging info on attempted frozen string modification" do - error_str = ruby_exe(fixture(__FILE__, 'debug_info.rb'), options: '--debug', args: "2>&1") + error_str = ruby_exe(fixture(__FILE__, 'debug_info.rb'), options: '--enable-frozen-string-literal --debug', args: "2>&1") error_str.should include("can't modify frozen String") error_str.should include("created at") - error_str.should include("command_line/fixtures/debug_info.rb:2") + error_str.should include("command_line/fixtures/debug_info.rb:1") + end + + guard -> { ruby_version_is "3.4" and !"test".frozen? } do + it "debugging info on mutating chilled string" do + error_str = ruby_exe(fixture(__FILE__, 'debug_info.rb'), options: '-w --debug', args: "2>&1") + error_str.should include("literal string will be frozen in the future") + error_str.should include("the string was created here") + error_str.should include("command_line/fixtures/debug_info.rb:1") + end end end diff --git a/spec/ruby/command_line/rubyopt_spec.rb b/spec/ruby/command_line/rubyopt_spec.rb index 18a5959b18cd..38e29c0d2145 100644 --- a/spec/ruby/command_line/rubyopt_spec.rb +++ b/spec/ruby/command_line/rubyopt_spec.rb @@ -22,15 +22,15 @@ result.should =~ /value of \$DEBUG is true/ end - guard -> { not CROSS_COMPILING } do + guard -> { RbConfig::CONFIG["CROSS_COMPILING"] != "yes" } do it "prints the version number for '-v'" do ENV["RUBYOPT"] = '-v' - ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "") + ruby_exe("").sub("+PRISM ", "")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "") end it "ignores whitespace around the option" do ENV["RUBYOPT"] = ' -v ' - ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "") + ruby_exe("").sub("+PRISM ", "")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "") end end diff --git a/spec/ruby/core/array/fetch_values_spec.rb b/spec/ruby/core/array/fetch_values_spec.rb new file mode 100644 index 000000000000..559b6c2b2fc9 --- /dev/null +++ b/spec/ruby/core/array/fetch_values_spec.rb @@ -0,0 +1,48 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Array#fetch_values" do + before :each do + @array = [:a, :b, :c] + end + + ruby_version_is "3.4" do + describe "with matched indexes" do + it "returns the values for indexes" do + @array.fetch_values(0).should == [:a] + @array.fetch_values(0, 2).should == [:a, :c] + end + + it "returns the values for indexes ordered in the order of the requested indexes" do + @array.fetch_values(2, 0).should == [:c, :a] + end + end + + describe "with unmatched indexes" do + it "raises a index error if no block is provided" do + -> { @array.fetch_values(0, 1, 44) }.should raise_error(IndexError) + end + + it "returns the default value from block" do + @array.fetch_values(44) { |index| "`#{index}' is not found" }.should == ["`44' is not found"] + @array.fetch_values(0, 44) { |index| "`#{index}' is not found" }.should == [:a, "`44' is not found"] + end + end + + describe "without keys" do + it "returns an empty Array" do + @array.fetch_values.should == [] + end + end + + it "tries to convert the passed argument to an Integer using #to_int" do + obj = mock('to_int') + obj.should_receive(:to_int).and_return(2) + @array.fetch_values(obj).should == [:c] + end + + it "raises a TypeError when the passed argument can't be coerced to Integer" do + -> { [].fetch_values("cat") }.should raise_error(TypeError) + end + end +end diff --git a/spec/ruby/core/array/pack/l_spec.rb b/spec/ruby/core/array/pack/l_spec.rb index b446a7a36a8a..f6dfb1da83b1 100644 --- a/spec/ruby/core/array/pack/l_spec.rb +++ b/spec/ruby/core/array/pack/l_spec.rb @@ -29,7 +29,7 @@ it_behaves_like :array_pack_32bit_be, 'L>' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "with modifier '<' and '_'" do it_behaves_like :array_pack_32bit_le, 'L<_' it_behaves_like :array_pack_32bit_le, 'L_<' @@ -51,7 +51,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "with modifier '<' and '_'" do it_behaves_like :array_pack_64bit_le, 'L<_' it_behaves_like :array_pack_64bit_le, 'L_<' @@ -83,7 +83,7 @@ it_behaves_like :array_pack_32bit_be, 'l>' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "with modifier '<' and '_'" do it_behaves_like :array_pack_32bit_le, 'l<_' it_behaves_like :array_pack_32bit_le, 'l_<' @@ -105,7 +105,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "with modifier '<' and '_'" do it_behaves_like :array_pack_64bit_le, 'l<_' it_behaves_like :array_pack_64bit_le, 'l_<' @@ -137,7 +137,7 @@ it_behaves_like :array_pack_32bit_le, 'l' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "Array#pack with format 'L' with modifier '_'" do it_behaves_like :array_pack_32bit_le, 'L_' end @@ -155,7 +155,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "Array#pack with format 'L' with modifier '_'" do it_behaves_like :array_pack_64bit_le, 'L_' end @@ -183,7 +183,7 @@ it_behaves_like :array_pack_32bit_be, 'l' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "Array#pack with format 'L' with modifier '_'" do it_behaves_like :array_pack_32bit_be, 'L_' end @@ -201,7 +201,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "Array#pack with format 'L' with modifier '_'" do it_behaves_like :array_pack_64bit_be, 'L_' end diff --git a/spec/ruby/core/array/pack/shared/integer.rb b/spec/ruby/core/array/pack/shared/integer.rb index fd21b25b19f2..a89b5b733bf0 100644 --- a/spec/ruby/core/array/pack/shared/integer.rb +++ b/spec/ruby/core/array/pack/shared/integer.rb @@ -273,7 +273,7 @@ str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde\x21\x43\x65\x78" end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "encodes the least significant 32 bits of a number that is greater than 32 bits" do [ [[0xff_7865_4321], "\x21\x43\x65\x78"], [[-0xff_7865_4321], "\xdf\xbc\x9a\x87"] @@ -299,7 +299,7 @@ str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd\x78\x65\x43\x21" end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "encodes the least significant 32 bits of a number that is greater than 32 bits" do [ [[0xff_7865_4321], "\x78\x65\x43\x21"], [[-0xff_7865_4321], "\x87\x9a\xbc\xdf"] diff --git a/spec/ruby/core/basicobject/instance_exec_spec.rb b/spec/ruby/core/basicobject/instance_exec_spec.rb index 289fdd889b5d..370f03d33c6b 100644 --- a/spec/ruby/core/basicobject/instance_exec_spec.rb +++ b/spec/ruby/core/basicobject/instance_exec_spec.rb @@ -84,17 +84,17 @@ def foo end.should raise_error(TypeError) end -quarantine! do # Not clean, leaves cvars lying around to break other specs - it "scopes class var accesses in the caller when called on an Integer" do - # Integer can take instance vars - Integer.class_eval "@@__tmp_instance_exec_spec = 1" - (defined? @@__tmp_instance_exec_spec).should == nil - - @@__tmp_instance_exec_spec = 2 - 1.instance_exec { @@__tmp_instance_exec_spec }.should == 2 - Integer.__send__(:remove_class_variable, :@@__tmp_instance_exec_spec) + quarantine! do # Not clean, leaves cvars lying around to break other specs + it "scopes class var accesses in the caller when called on an Integer" do + # Integer can take instance vars + Integer.class_eval "@@__tmp_instance_exec_spec = 1" + (defined? @@__tmp_instance_exec_spec).should == nil + + @@__tmp_instance_exec_spec = 2 + 1.instance_exec { @@__tmp_instance_exec_spec }.should == 2 + Integer.__send__(:remove_class_variable, :@@__tmp_instance_exec_spec) + end end -end it "raises a TypeError when defining methods on numerics" do -> do diff --git a/spec/ruby/core/builtin_constants/builtin_constants_spec.rb b/spec/ruby/core/builtin_constants/builtin_constants_spec.rb index 1960f5721f90..eaf311783a4a 100644 --- a/spec/ruby/core/builtin_constants/builtin_constants_spec.rb +++ b/spec/ruby/core/builtin_constants/builtin_constants_spec.rb @@ -4,6 +4,10 @@ it "is a String" do RUBY_VERSION.should be_kind_of(String) end + + it "is frozen" do + RUBY_VERSION.should.frozen? + end end describe "RUBY_PATCHLEVEL" do @@ -16,34 +20,58 @@ it "is a String" do RUBY_COPYRIGHT.should be_kind_of(String) end + + it "is frozen" do + RUBY_COPYRIGHT.should.frozen? + end end describe "RUBY_DESCRIPTION" do it "is a String" do RUBY_DESCRIPTION.should be_kind_of(String) end + + it "is frozen" do + RUBY_DESCRIPTION.should.frozen? + end end describe "RUBY_ENGINE" do it "is a String" do RUBY_ENGINE.should be_kind_of(String) end + + it "is frozen" do + RUBY_ENGINE.should.frozen? + end end describe "RUBY_PLATFORM" do it "is a String" do RUBY_PLATFORM.should be_kind_of(String) end + + it "is frozen" do + RUBY_PLATFORM.should.frozen? + end end describe "RUBY_RELEASE_DATE" do it "is a String" do RUBY_RELEASE_DATE.should be_kind_of(String) end + + it "is frozen" do + RUBY_RELEASE_DATE.should.frozen? + end end describe "RUBY_REVISION" do it "is a String" do RUBY_REVISION.should be_kind_of(String) end + + it "is frozen" do + RUBY_REVISION.should.frozen? + end end diff --git a/spec/ruby/core/complex/equal_value_spec.rb b/spec/ruby/core/complex/equal_value_spec.rb index ad7236b1bd5d..97c486d82044 100644 --- a/spec/ruby/core/complex/equal_value_spec.rb +++ b/spec/ruby/core/complex/equal_value_spec.rb @@ -76,7 +76,7 @@ (Complex(real, 0) == @other).should be_true end - it "returns false when when the imaginary part is not zero" do + it "returns false when the imaginary part is not zero" do (Complex(3, 1) == @other).should be_false end end diff --git a/spec/ruby/core/data/to_h_spec.rb b/spec/ruby/core/data/to_h_spec.rb new file mode 100644 index 000000000000..41d6960c97a3 --- /dev/null +++ b/spec/ruby/core/data/to_h_spec.rb @@ -0,0 +1,65 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is "3.2" do + describe "Data#to_h" do + it "transforms the data object into a hash" do + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + data.to_h.should == { amount: 42, unit: 'km' } + end + + context "with block" do + it "transforms [key, value] pairs returned by the block into a hash" do + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + data.to_h { |key, value| [value, key] }.should == { 42 => :amount, 'km' => :unit } + end + + it "passes to a block each pair's key and value as separate arguments" do + ScratchPad.record [] + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + data.to_h { |k, v| ScratchPad << [k, v]; [k, v] } + ScratchPad.recorded.sort.should == [[:amount, 42], [:unit, 'km']] + + ScratchPad.record [] + data.to_h { |*args| ScratchPad << args; [args[0], args[1]] } + ScratchPad.recorded.sort.should == [[:amount, 42], [:unit, 'km']] + end + + it "raises ArgumentError if block returns longer or shorter array" do + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + -> do + data.to_h { |k, v| [k.to_s, v*v, 1] } + end.should raise_error(ArgumentError, /element has wrong array length/) + + -> do + data.to_h { |k, v| [k] } + end.should raise_error(ArgumentError, /element has wrong array length/) + end + + it "raises TypeError if block returns something other than Array" do + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + -> do + data.to_h { |k, v| "not-array" } + end.should raise_error(TypeError, /wrong element type String/) + end + + it "coerces returned pair to Array with #to_ary" do + x = mock('x') + x.stub!(:to_ary).and_return([:b, 'b']) + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + + data.to_h { |k| x }.should == { :b => 'b' } + end + + it "does not coerce returned pair to Array with #to_a" do + x = mock('x') + x.stub!(:to_a).and_return([:b, 'b']) + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + + -> do + data.to_h { |k| x } + end.should raise_error(TypeError, /wrong element type MockObject/) + end + end + end +end diff --git a/spec/ruby/core/encoding/compatible_spec.rb b/spec/ruby/core/encoding/compatible_spec.rb index 903712b156fe..d5b958ea0b18 100644 --- a/spec/ruby/core/encoding/compatible_spec.rb +++ b/spec/ruby/core/encoding/compatible_spec.rb @@ -168,39 +168,37 @@ # encodings in all possible combinations. describe "compatibility matrix" do -=begin - Use the following script to regenerate the matrix: - - ``` - # -*- encoding: binary -*- - - ENCODINGS = [ - "US-ASCII", - "UTF-8", - "ASCII-8BIT", - "ISO-8859-1", # ASCII-compatible - "UTF-16BE", # non-ASCII-compatible - "ISO-2022-JP" # dummy - ] - - TYPES = [:empty, :"7bits", :non7bits] - - VALUES = { - empty: "", - :"7bits" => "\x01", - non7bits: "\x81" - } - - ENCODINGS.product(TYPES, ENCODINGS, TYPES).each do |encoding1, type1, encoding2, type2| - value1 = VALUES[type1].dup.force_encoding(encoding1) - value2 = VALUES[type2].dup.force_encoding(encoding2) - - result_encoding = Encoding.compatible?(value1, value2) - - puts "[#{encoding1.inspect}, #{value1.inspect}, #{encoding2.inspect}, #{value2.inspect}, #{result_encoding&.name.inspect}]," - end - ``` -=end +# Use the following script to regenerate the matrix: +# +# ``` +# # -*- encoding: binary -*- +# +# ENCODINGS = [ +# "US-ASCII", +# "UTF-8", +# "ASCII-8BIT", +# "ISO-8859-1", # ASCII-compatible +# "UTF-16BE", # non-ASCII-compatible +# "ISO-2022-JP" # dummy +# ] +# +# TYPES = [:empty, :"7bits", :non7bits] +# +# VALUES = { +# empty: "", +# :"7bits" => "\x01", +# non7bits: "\x81" +# } +# +# ENCODINGS.product(TYPES, ENCODINGS, TYPES).each do |encoding1, type1, encoding2, type2| +# value1 = VALUES[type1].dup.force_encoding(encoding1) +# value2 = VALUES[type2].dup.force_encoding(encoding2) +# +# result_encoding = Encoding.compatible?(value1, value2) +# +# puts "[#{encoding1.inspect}, #{value1.inspect}, #{encoding2.inspect}, #{value2.inspect}, #{result_encoding&.name.inspect}]," +# end +# ``` matrix = [ ["US-ASCII", "", "US-ASCII", "", "US-ASCII"], @@ -531,7 +529,7 @@ matrix.each do |encoding1, value1, encoding2, value2, compatible_encoding| it "returns #{compatible_encoding} for #{value1.inspect} in #{encoding1} and #{value2.inspect} in #{encoding2}" do - actual_encoding = Encoding.compatible?(value1.force_encoding(encoding1), value2.force_encoding(encoding2)) + actual_encoding = Encoding.compatible?(value1.dup.force_encoding(encoding1), value2.dup.force_encoding(encoding2)) actual_encoding&.name.should == compatible_encoding end end diff --git a/spec/ruby/core/enumerator/each_with_index_spec.rb b/spec/ruby/core/enumerator/each_with_index_spec.rb index 96e53a2804c0..271e61fec655 100644 --- a/spec/ruby/core/enumerator/each_with_index_spec.rb +++ b/spec/ruby/core/enumerator/each_with_index_spec.rb @@ -21,16 +21,16 @@ it "passes on the given block's return value" do arr = [1,2,3] - arr.delete_if.with_index { |a,b| false } + arr.delete_if.each_with_index { |a,b| false } arr.should == [1,2,3] end it "returns the iterator's return value" do - [1,2,3].select.with_index { |a,b| false }.should == [] + [1,2,3].select.each_with_index { |a,b| false }.should == [] + [1,2,3].select.each_with_index { |a,b| true }.should == [1,2,3] end it "returns the correct value if chained with itself" do [:a].each_with_index.each_with_index.to_a.should == [[[:a,0],0]] - [:a].each.with_index.with_index.to_a.should == [[[:a,0],0]] end end diff --git a/spec/ruby/core/enumerator/with_index_spec.rb b/spec/ruby/core/enumerator/with_index_spec.rb index ac37cee508fa..3aeb3fc869ac 100644 --- a/spec/ruby/core/enumerator/with_index_spec.rb +++ b/spec/ruby/core/enumerator/with_index_spec.rb @@ -69,4 +69,21 @@ @enum.with_index(-1) { |*x| res << x} res.should == [[1,-1], [2,0], [3,1], [4,2]] end + + it "passes on the given block's return value" do + arr = [1,2,3] + arr.delete_if.with_index { |a,b| false } + arr.should == [1,2,3] + + arr.delete_if.with_index { |a,b| true } + arr.should == [] + end + + it "returns the iterator's return value" do + @enum.select.with_index { |a,b| false }.should == [] + end + + it "returns the correct value if chained with itself" do + [:a].each.with_index.with_index.to_a.should == [[[:a,0],0]] + end end diff --git a/spec/ruby/core/fiber/raise_spec.rb b/spec/ruby/core/fiber/raise_spec.rb index b3e021e6360b..2f2baa4a12a2 100644 --- a/spec/ruby/core/fiber/raise_spec.rb +++ b/spec/ruby/core/fiber/raise_spec.rb @@ -42,7 +42,7 @@ -> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error' }.should raise_error(FiberSpecs::CustomError, 'test error') end - it 'accepts error class with with error message and backtrace information' do + it 'accepts error class with error message and backtrace information' do -> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error', ['foo', 'boo'] }.should raise_error(FiberSpecs::CustomError) { |e| diff --git a/spec/ruby/core/file/chown_spec.rb b/spec/ruby/core/file/chown_spec.rb index 8cc8f0d04be6..4db0e3712c21 100644 --- a/spec/ruby/core/file/chown_spec.rb +++ b/spec/ruby/core/file/chown_spec.rb @@ -78,15 +78,15 @@ end describe "File#chown" do - before :each do - @fname = tmp('file_chown_test') - @file = File.open(@fname, 'w') - end + before :each do + @fname = tmp('file_chown_test') + @file = File.open(@fname, 'w') + end - after :each do - @file.close unless @file.closed? - rm_r @fname - end + after :each do + @file.close unless @file.closed? + rm_r @fname + end as_superuser do platform_is :windows do diff --git a/spec/ruby/core/file/shared/update_time.rb b/spec/ruby/core/file/shared/update_time.rb index 9c063a8e9354..3fe7266a00e2 100644 --- a/spec/ruby/core/file/shared/update_time.rb +++ b/spec/ruby/core/file/shared/update_time.rb @@ -84,7 +84,7 @@ end platform_is :linux do - platform_is wordsize: 64 do + platform_is pointer_size: 64 do it "allows Time instances in the far future to set mtime and atime (but some filesystems limit it up to 2446-05-10 or 2038-01-19 or 2486-07-02)" do # https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Inode_Timestamps # "Therefore, timestamps should not overflow until May 2446." diff --git a/spec/ruby/core/float/ceil_spec.rb b/spec/ruby/core/float/ceil_spec.rb index 7fc18d304c26..75f56102922e 100644 --- a/spec/ruby/core/float/ceil_spec.rb +++ b/spec/ruby/core/float/ceil_spec.rb @@ -1,6 +1,11 @@ require_relative '../../spec_helper' +require_relative '../integer/shared/integer_ceil_precision' describe "Float#ceil" do + context "with precision" do + it_behaves_like :integer_ceil_precision, :Float + end + it "returns the smallest Integer greater than or equal to self" do -1.2.ceil.should eql( -1) -1.0.ceil.should eql( -1) diff --git a/spec/ruby/core/float/comparison_spec.rb b/spec/ruby/core/float/comparison_spec.rb index 1373b3a1fb2f..d2e47937ff19 100644 --- a/spec/ruby/core/float/comparison_spec.rb +++ b/spec/ruby/core/float/comparison_spec.rb @@ -72,7 +72,7 @@ def coerce(other) (-Float::MAX.to_i*2 <=> -infinity_value).should == 1 end - it "returns 0 when self is Infinity and other other is infinite?=1" do + it "returns 0 when self is Infinity and other is infinite?=1" do obj = Object.new def obj.infinite? 1 diff --git a/spec/ruby/core/float/floor_spec.rb b/spec/ruby/core/float/floor_spec.rb index 046216d36d4a..8b492ef4732f 100644 --- a/spec/ruby/core/float/floor_spec.rb +++ b/spec/ruby/core/float/floor_spec.rb @@ -1,6 +1,11 @@ require_relative '../../spec_helper' +require_relative '../integer/shared/integer_floor_precision' describe "Float#floor" do + context "with precision" do + it_behaves_like :integer_floor_precision, :Float + end + it "returns the largest Integer less than or equal to self" do -1.2.floor.should eql( -2) -1.0.floor.should eql( -1) diff --git a/spec/ruby/core/hash/element_reference_spec.rb b/spec/ruby/core/hash/element_reference_spec.rb index 94e82378395d..d5859cb34275 100644 --- a/spec/ruby/core/hash/element_reference_spec.rb +++ b/spec/ruby/core/hash/element_reference_spec.rb @@ -12,7 +12,7 @@ h[[]].should == "baz" end - it "returns nil as default default value" do + it "returns nil as default value" do { 0 => 0 }[5].should == nil end diff --git a/spec/ruby/core/hash/hash_spec.rb b/spec/ruby/core/hash/hash_spec.rb index 19eb806dc4ea..9b47d4b2bf9e 100644 --- a/spec/ruby/core/hash/hash_spec.rb +++ b/spec/ruby/core/hash/hash_spec.rb @@ -47,7 +47,7 @@ a = 1 b = 2 - eval('{a:, b:}.should == { a: 1, b: 2 }') + eval('{a:, b:}.should == { a: 1, b: 2 }') end end end diff --git a/spec/ruby/core/hash/new_spec.rb b/spec/ruby/core/hash/new_spec.rb index 6279815fd6e6..5ae3e1f98d62 100644 --- a/spec/ruby/core/hash/new_spec.rb +++ b/spec/ruby/core/hash/new_spec.rb @@ -34,7 +34,7 @@ -> { Hash.new(nil) { 0 } }.should raise_error(ArgumentError) end - ruby_version_is "3.3" do + ruby_version_is "3.3"..."3.4" do it "emits a deprecation warning if keyword arguments are passed" do -> { Hash.new(unknown: true) }.should complain( Regexp.new(Regexp.escape("Calling Hash.new with keyword arguments is deprecated and will be removed in Ruby 3.4; use Hash.new({ key: value }) instead")) @@ -46,4 +46,22 @@ Hash.new({ unknown: true }).default.should == { unknown: true } end end + + ruby_version_is "3.4" do + it "accepts a capacity: argument" do + Hash.new(5, capacity: 42).default.should == 5 + Hash.new(capacity: 42).default.should == nil + (Hash.new(capacity: 42) { 1 }).default_proc.should_not == nil + end + + it "ignores negative capacity" do + -> { Hash.new(capacity: -42) }.should_not raise_error + end + + it "raises an error if unknown keyword arguments are passed" do + -> { Hash.new(unknown: true) }.should raise_error(ArgumentError) + -> { Hash.new(1, unknown: true) }.should raise_error(ArgumentError) + -> { Hash.new(unknown: true) { 0 } }.should raise_error(ArgumentError) + end + end end diff --git a/spec/ruby/core/hash/shared/to_s.rb b/spec/ruby/core/hash/shared/to_s.rb index 7864d7cd4c69..5f0a8f97fdb5 100644 --- a/spec/ruby/core/hash/shared/to_s.rb +++ b/spec/ruby/core/hash/shared/to_s.rb @@ -4,14 +4,8 @@ describe :hash_to_s, shared: true do it "returns a string representation with same order as each()" do h = { a: [1, 2], b: -2, d: -6, nil => nil } - - pairs = [] - h.each do |key, value| - pairs << key.inspect + '=>' + value.inspect - end - - str = '{' + pairs.join(', ') + '}' - h.send(@method).should == str + expected = ruby_version_is("3.4") ? "{a: [1, 2], b: -2, d: -6, nil => nil}" : "{:a=>[1, 2], :b=>-2, :d=>-6, nil=>nil}" + h.send(@method).should == expected end it "calls #inspect on keys and values" do @@ -19,31 +13,31 @@ val = mock('val') key.should_receive(:inspect).and_return('key') val.should_receive(:inspect).and_return('val') - - { key => val }.send(@method).should == '{key=>val}' + expected = ruby_version_is("3.4") ? "{key => val}" : "{key=>val}" + { key => val }.send(@method).should == expected end it "does not call #to_s on a String returned from #inspect" do str = +"abc" str.should_not_receive(:to_s) - - { a: str }.send(@method).should == '{:a=>"abc"}' + expected = ruby_version_is("3.4") ? '{a: "abc"}' : '{:a=>"abc"}' + { a: str }.send(@method).should == expected end it "calls #to_s on the object returned from #inspect if the Object isn't a String" do obj = mock("Hash#inspect/to_s calls #to_s") obj.should_receive(:inspect).and_return(obj) obj.should_receive(:to_s).and_return("abc") - - { a: obj }.send(@method).should == "{:a=>abc}" + expected = ruby_version_is("3.4") ? "{a: abc}" : "{:a=>abc}" + { a: obj }.send(@method).should == expected end it "does not call #to_str on the object returned from #inspect when it is not a String" do obj = mock("Hash#inspect/to_s does not call #to_str") obj.should_receive(:inspect).and_return(obj) obj.should_not_receive(:to_str) - - { a: obj }.send(@method).should =~ /^\{:a=>#\}$/ + expected_pattern = ruby_version_is("3.4") ? /^\{a: #\}$/ : /^\{:a=>#\}$/ + { a: obj }.send(@method).should =~ expected_pattern end it "does not call #to_str on the object returned from #to_s when it is not a String" do @@ -51,8 +45,8 @@ obj.should_receive(:inspect).and_return(obj) obj.should_receive(:to_s).and_return(obj) obj.should_not_receive(:to_str) - - { a: obj }.send(@method).should =~ /^\{:a=>#\}$/ + expected_pattern = ruby_version_is("3.4") ? /^\{a: #\}$/ : /^\{:a=>#\}$/ + { a: obj }.send(@method).should =~ expected_pattern end it "does not swallow exceptions raised by #to_s" do @@ -66,24 +60,28 @@ it "handles hashes with recursive values" do x = {} x[0] = x - x.send(@method).should == '{0=>{...}}' + expected = ruby_version_is("3.4") ? '{0 => {...}}' : '{0=>{...}}' + x.send(@method).should == expected x = {} y = {} x[0] = y y[1] = x - x.send(@method).should == "{0=>{1=>{...}}}" - y.send(@method).should == "{1=>{0=>{...}}}" + expected_x = ruby_version_is("3.4") ? '{0 => {1 => {...}}}' : '{0=>{1=>{...}}}' + expected_y = ruby_version_is("3.4") ? '{1 => {0 => {...}}}' : '{1=>{0=>{...}}}' + x.send(@method).should == expected_x + y.send(@method).should == expected_y end it "does not raise if inspected result is not default external encoding" do utf_16be = mock("utf_16be") utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode(Encoding::UTF_16BE)) - - {a: utf_16be}.send(@method).should == '{:a=>"utf_16be \u3042"}' + expected = ruby_version_is("3.4") ? '{a: "utf_16be \u3042"}' : '{:a=>"utf_16be \u3042"}' + {a: utf_16be}.send(@method).should == expected end it "works for keys and values whose #inspect return a frozen String" do - { true => false }.to_s.should == "{true=>false}" + expected = ruby_version_is("3.4") ? "{true => false}" : "{true=>false}" + { true => false }.to_s.should == expected end end diff --git a/spec/ruby/core/integer/ceil_spec.rb b/spec/ruby/core/integer/ceil_spec.rb index 13bdaf838d98..eb633fba7843 100644 --- a/spec/ruby/core/integer/ceil_spec.rb +++ b/spec/ruby/core/integer/ceil_spec.rb @@ -1,11 +1,16 @@ require_relative '../../spec_helper' require_relative 'shared/to_i' require_relative 'shared/integer_rounding' +require_relative 'shared/integer_ceil_precision' describe "Integer#ceil" do it_behaves_like :integer_to_i, :ceil it_behaves_like :integer_rounding_positive_precision, :ceil + context "with precision" do + it_behaves_like :integer_ceil_precision, :Integer + end + context "precision argument specified as part of the ceil method is negative" do it "returns the smallest integer greater than self with at least precision.abs trailing zeros" do 18.ceil(-1).should eql(20) diff --git a/spec/ruby/core/integer/floor_spec.rb b/spec/ruby/core/integer/floor_spec.rb index aaa816fdc53e..8fb84d58cb8a 100644 --- a/spec/ruby/core/integer/floor_spec.rb +++ b/spec/ruby/core/integer/floor_spec.rb @@ -1,19 +1,13 @@ require_relative '../../spec_helper' require_relative 'shared/to_i' require_relative 'shared/integer_rounding' +require_relative 'shared/integer_floor_precision' describe "Integer#floor" do it_behaves_like :integer_to_i, :floor it_behaves_like :integer_rounding_positive_precision, :floor - context "precision argument specified as part of the floor method is negative" do - it "returns the largest integer less than self with at least precision.abs trailing zeros" do - 1832.floor(-1).should eql(1830) - 1832.floor(-2).should eql(1800) - 1832.floor(-3).should eql(1000) - -1832.floor(-1).should eql(-1840) - -1832.floor(-2).should eql(-1900) - -1832.floor(-3).should eql(-2000) - end + context "with precision" do + it_behaves_like :integer_floor_precision, :Integer end end diff --git a/spec/ruby/core/integer/pow_spec.rb b/spec/ruby/core/integer/pow_spec.rb index 47129110952d..ecaca01eff3b 100644 --- a/spec/ruby/core/integer/pow_spec.rb +++ b/spec/ruby/core/integer/pow_spec.rb @@ -19,13 +19,13 @@ 2.pow(61, 5843009213693951).should eql 3697379018277258 2.pow(62, 5843009213693952).should eql 1551748822859776 2.pow(63, 5843009213693953).should eql 3103497645717974 - 2.pow(64, 5843009213693954).should eql 363986077738838 + 2.pow(64, 5843009213693954).should eql 363986077738838 end it "handles sign like #divmod does" do - 2.pow(5, 12).should == 8 - 2.pow(5, -12).should == -4 - -2.pow(5, 12).should == 4 + 2.pow(5, 12).should == 8 + 2.pow(5, -12).should == -4 + -2.pow(5, 12).should == 4 -2.pow(5, -12).should == -8 end diff --git a/spec/ruby/core/integer/remainder_spec.rb b/spec/ruby/core/integer/remainder_spec.rb index 96268b3af5cb..757e42fbe84f 100644 --- a/spec/ruby/core/integer/remainder_spec.rb +++ b/spec/ruby/core/integer/remainder_spec.rb @@ -15,8 +15,8 @@ end it "keeps sign of self" do - 5.remainder( 3).should == 2 - 5.remainder(-3).should == 2 + 5.remainder( 3).should == 2 + 5.remainder(-3).should == 2 -5.remainder( 3).should == -2 -5.remainder(-3).should == -2 end diff --git a/spec/ruby/core/integer/round_spec.rb b/spec/ruby/core/integer/round_spec.rb index 45ac126fd360..189384f11adf 100644 --- a/spec/ruby/core/integer/round_spec.rb +++ b/spec/ruby/core/integer/round_spec.rb @@ -21,10 +21,8 @@ (-25 * 10**70).round(-71).should eql(-30 * 10**70) end - platform_is_not wordsize: 32 do - it "raises a RangeError when passed a big negative value" do - -> { 42.round(fixnum_min) }.should raise_error(RangeError) - end + it "raises a RangeError when passed a big negative value" do + -> { 42.round(min_long - 1) }.should raise_error(RangeError) end it "raises a RangeError when passed Float::INFINITY" do diff --git a/spec/ruby/core/integer/shared/integer_ceil_precision.rb b/spec/ruby/core/integer/shared/integer_ceil_precision.rb new file mode 100644 index 000000000000..9f31c2cf615e --- /dev/null +++ b/spec/ruby/core/integer/shared/integer_ceil_precision.rb @@ -0,0 +1,43 @@ +describe :integer_ceil_precision, shared: true do + context "precision is zero" do + it "returns integer self" do + send(@method, 0).ceil(0).should.eql?(0) + send(@method, 123).ceil(0).should.eql?(123) + send(@method, -123).ceil(0).should.eql?(-123) + end + end + + context "precision is positive" do + it "returns self" do + send(@method, 0).ceil(1).should.eql?(send(@method, 0)) + send(@method, 0).ceil(10).should.eql?(send(@method, 0)) + + send(@method, 123).ceil(10).should.eql?(send(@method, 123)) + send(@method, -123).ceil(10).should.eql?(send(@method, -123)) + end + end + + context "precision is negative" do + it "always returns 0 when self is 0" do + send(@method, 0).ceil(-1).should.eql?(0) + send(@method, 0).ceil(-10).should.eql?(0) + end + + it "returns largest integer less than self with at least precision.abs trailing zeros" do + send(@method, 123).ceil(-1).should.eql?(130) + send(@method, 123).ceil(-2).should.eql?(200) + send(@method, 123).ceil(-3).should.eql?(1000) + + send(@method, -123).ceil(-1).should.eql?(-120) + send(@method, -123).ceil(-2).should.eql?(-100) + send(@method, -123).ceil(-3).should.eql?(0) + end + + ruby_bug "#20654", ""..."3.4" do + it "returns 10**precision.abs when precision.abs is larger than the number digits of self" do + send(@method, 123).ceil(-20).should.eql?(100000000000000000000) + send(@method, 123).ceil(-50).should.eql?(100000000000000000000000000000000000000000000000000) + end + end + end +end diff --git a/spec/ruby/core/integer/shared/integer_floor_precision.rb b/spec/ruby/core/integer/shared/integer_floor_precision.rb new file mode 100644 index 000000000000..4c5888c6c481 --- /dev/null +++ b/spec/ruby/core/integer/shared/integer_floor_precision.rb @@ -0,0 +1,43 @@ +describe :integer_floor_precision, shared: true do + context "precision is zero" do + it "returns integer self" do + send(@method, 0).floor(0).should.eql?(0) + send(@method, 123).floor(0).should.eql?(123) + send(@method, -123).floor(0).should.eql?(-123) + end + end + + context "precision is positive" do + it "returns self" do + send(@method, 0).floor(1).should.eql?(send(@method, 0)) + send(@method, 0).floor(10).should.eql?(send(@method, 0)) + + send(@method, 123).floor(10).should.eql?(send(@method, 123)) + send(@method, -123).floor(10).should.eql?(send(@method, -123)) + end + end + + context "precision is negative" do + it "always returns 0 when self is 0" do + send(@method, 0).floor(-1).should.eql?(0) + send(@method, 0).floor(-10).should.eql?(0) + end + + it "returns largest integer less than self with at least precision.abs trailing zeros" do + send(@method, 123).floor(-1).should.eql?(120) + send(@method, 123).floor(-2).should.eql?(100) + send(@method, 123).floor(-3).should.eql?(0) + + send(@method, -123).floor(-1).should.eql?(-130) + send(@method, -123).floor(-2).should.eql?(-200) + send(@method, -123).floor(-3).should.eql?(-1000) + end + + ruby_bug "#20654", ""..."3.4" do + it "returns -(10**precision.abs) when self is negative and precision.abs is larger than the number digits of self" do + send(@method, -123).floor(-20).should.eql?(-100000000000000000000) + send(@method, -123).floor(-50).should.eql?(-100000000000000000000000000000000000000000000000000) + end + end + end +end diff --git a/spec/ruby/core/integer/size_spec.rb b/spec/ruby/core/integer/size_spec.rb index a134e8238421..725e9eb062bf 100644 --- a/spec/ruby/core/integer/size_spec.rb +++ b/spec/ruby/core/integer/size_spec.rb @@ -1,7 +1,7 @@ require_relative '../../spec_helper' describe "Integer#size" do - platform_is wordsize: 32 do + platform_is c_long_size: 32 do it "returns the number of bytes in the machine representation of self" do -1.size.should == 4 0.size.should == 4 @@ -9,7 +9,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "returns the number of bytes in the machine representation of self" do -1.size.should == 8 0.size.should == 8 diff --git a/spec/ruby/core/io/dup_spec.rb b/spec/ruby/core/io/dup_spec.rb index 68d538377f68..564e00743871 100644 --- a/spec/ruby/core/io/dup_spec.rb +++ b/spec/ruby/core/io/dup_spec.rb @@ -25,27 +25,27 @@ @i.fileno.should_not == @f.fileno end -quarantine! do # This does not appear to be consistent across platforms - it "shares the original stream between the two IOs" do - start = @f.pos - @i.pos.should == start + quarantine! do # This does not appear to be consistent across platforms + it "shares the original stream between the two IOs" do + start = @f.pos + @i.pos.should == start - s = "Hello, wo.. wait, where am I?\n" - s2 = " Muhahahaa!" + s = "Hello, wo.. wait, where am I?\n" + s2 = " Muhahahaa!" - @f.write s - @i.pos.should == @f.pos + @f.write s + @i.pos.should == @f.pos - @i.rewind - @i.gets.should == s + @i.rewind + @i.gets.should == s - @i.rewind - @i.write s2 + @i.rewind + @i.write s2 - @f.rewind - @f.gets.should == "#{s2}\n" + @f.rewind + @f.gets.should == "#{s2}\n" + end end -end it "allows closing the new IO without affecting the original" do @i.close diff --git a/spec/ruby/core/io/puts_spec.rb b/spec/ruby/core/io/puts_spec.rb index 9ed343c94c3c..a186ddaa5d83 100644 --- a/spec/ruby/core/io/puts_spec.rb +++ b/spec/ruby/core/io/puts_spec.rb @@ -33,7 +33,7 @@ def @io.write(str) ScratchPad.recorded.should == "\n" end - it "writes empty string with a newline when when given nil as multiple args" do + it "writes empty string with a newline when given nil as multiple args" do @io.puts(nil, nil).should == nil ScratchPad.recorded.should == "\n\n" end diff --git a/spec/ruby/core/io/read_spec.rb b/spec/ruby/core/io/read_spec.rb index 8741d9f0179a..567daa55dfc4 100644 --- a/spec/ruby/core/io/read_spec.rb +++ b/spec/ruby/core/io/read_spec.rb @@ -217,19 +217,19 @@ end end -quarantine! do # The process tried to write to a nonexistent pipe. - platform_is :windows do - # TODO: It should raise Errno::ESPIPE on Windows as well - # once https://bugs.ruby-lang.org/issues/12230 is fixed. - it "raises Errno::EINVAL if passed an offset" do - -> { - suppress_warning do # https://bugs.ruby-lang.org/issues/19630 - IO.read("|cmd.exe /C echo hello", 1, 1) - end - }.should raise_error(Errno::EINVAL) + quarantine! do # The process tried to write to a nonexistent pipe. + platform_is :windows do + # TODO: It should raise Errno::ESPIPE on Windows as well + # once https://bugs.ruby-lang.org/issues/12230 is fixed. + it "raises Errno::EINVAL if passed an offset" do + -> { + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + IO.read("|cmd.exe /C echo hello", 1, 1) + end + }.should raise_error(Errno::EINVAL) + end end end -end ruby_version_is "3.3" do # https://bugs.ruby-lang.org/issues/19630 diff --git a/spec/ruby/core/kernel/format_spec.rb b/spec/ruby/core/kernel/format_spec.rb index e8b031e48014..1d0c000c1587 100644 --- a/spec/ruby/core/kernel/format_spec.rb +++ b/spec/ruby/core/kernel/format_spec.rb @@ -12,4 +12,36 @@ it "is accessible as a module function" do Kernel.format("%s", "hello").should == "hello" end + + describe "when $VERBOSE is true" do + it "warns if too many arguments are passed" do + code = <<~RUBY + $VERBOSE = true + format("test", 1) + RUBY + + ruby_exe(code, args: "2>&1").should include("warning: too many arguments for format string") + end + + it "does not warns if too many keyword arguments are passed" do + code = <<~RUBY + $VERBOSE = true + format("test %{test}", test: 1, unused: 2) + RUBY + + ruby_exe(code, args: "2>&1").should_not include("warning") + end + + ruby_bug "#20593", ""..."3.4" do + it "doesn't warns if keyword arguments are passed and none are used" do + code = <<~RUBY + $VERBOSE = true + format("test", test: 1) + format("test", {}) + RUBY + + ruby_exe(code, args: "2>&1").should_not include("warning") + end + end + end end diff --git a/spec/ruby/core/kernel/select_spec.rb b/spec/ruby/core/kernel/select_spec.rb index e0d82f3079b4..df23414b2848 100644 --- a/spec/ruby/core/kernel/select_spec.rb +++ b/spec/ruby/core/kernel/select_spec.rb @@ -10,9 +10,9 @@ describe "Kernel.select" do it 'does not block when timeout is 0' do IO.pipe do |read, write| - IO.select([read], [], [], 0).should == nil + select([read], [], [], 0).should == nil write.write 'data' - IO.select([read], [], [], 0).should == [[read], [], []] + select([read], [], [], 0).should == [[read], [], []] end end end diff --git a/spec/ruby/core/kernel/sleep_spec.rb b/spec/ruby/core/kernel/sleep_spec.rb index d35e3130063f..1de52a707fcb 100644 --- a/spec/ruby/core/kernel/sleep_spec.rb +++ b/spec/ruby/core/kernel/sleep_spec.rb @@ -51,6 +51,20 @@ def o.divmod(*); [0, 0.001]; end t.value.should == 5 end + platform_is_not :darwin do + it "sleeps with nanosecond precision" do + start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 100.times do + sleep(0.0001) + end + end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + actual_duration = end_time - start_time + (actual_duration > 0.01).should == true # 100 * 0.0001 => 0.01 + (actual_duration < 0.03).should == true + end + end + ruby_version_is ""..."3.3" do it "raises a TypeError when passed nil" do -> { sleep(nil) }.should raise_error(TypeError) diff --git a/spec/ruby/core/marshal/dump_spec.rb b/spec/ruby/core/marshal/dump_spec.rb index 0f77279a4fa7..adabfdf025c0 100644 --- a/spec/ruby/core/marshal/dump_spec.rb +++ b/spec/ruby/core/marshal/dump_spec.rb @@ -38,7 +38,7 @@ ].should be_computed_by(:dump) end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "dumps a positive Fixnum > 31 bits as a Bignum" do Marshal.dump(2**31 + 1).should == "\x04\bl+\a\x01\x00\x00\x80" end diff --git a/spec/ruby/core/marshal/fixtures/marshal_data.rb b/spec/ruby/core/marshal/fixtures/marshal_data.rb index a508b6bea1dc..aae3fce0aa28 100644 --- a/spec/ruby/core/marshal/fixtures/marshal_data.rb +++ b/spec/ruby/core/marshal/fixtures/marshal_data.rb @@ -1,4 +1,7 @@ # -*- encoding: binary -*- + +require_relative 'marshal_multibyte_data' + class UserDefined class Nested def ==(other) @@ -267,17 +270,6 @@ def self.name end end - module_eval(<<~ruby.dup.force_encoding(Encoding::UTF_8)) - class MultibyteぁあぃいClass - end - - module MultibyteけげこごModule - end - - class MultibyteぁあぃいTime < Time - end - ruby - class ObjectWithFreezeRaisingException < Object def freeze raise diff --git a/spec/ruby/core/marshal/fixtures/marshal_multibyte_data.rb b/spec/ruby/core/marshal/fixtures/marshal_multibyte_data.rb new file mode 100644 index 000000000000..98a0d4339218 --- /dev/null +++ b/spec/ruby/core/marshal/fixtures/marshal_multibyte_data.rb @@ -0,0 +1,12 @@ +# -*- encoding: utf-8 -*- + +module MarshalSpec + class MultibyteぁあぃいClass + end + + module MultibyteけげこごModule + end + + class MultibyteぁあぃいTime < Time + end +end diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb index f59904252934..4eac21a95261 100644 --- a/spec/ruby/core/marshal/shared/load.rb +++ b/spec/ruby/core/marshal/shared/load.rb @@ -1049,7 +1049,7 @@ def io.binmode; raise "binmode"; end end describe "for a Bignum" do - platform_is wordsize: 64 do + platform_is c_long_size: 64 do context "that is Bignum on 32-bit platforms but Fixnum on 64-bit" do it "dumps a Fixnum" do val = Marshal.send(@method, "\004\bl+\ab:wU") diff --git a/spec/ruby/core/module/name_spec.rb b/spec/ruby/core/module/name_spec.rb index 2d946a13a9bd..33e8400e88a8 100644 --- a/spec/ruby/core/module/name_spec.rb +++ b/spec/ruby/core/module/name_spec.rb @@ -148,11 +148,11 @@ def const_added(name) puts const_get(name).name end end - + # module with name module TEST1 end - + # anonymous module TEST2 = Module.new RUBY diff --git a/spec/ruby/core/module/new_spec.rb b/spec/ruby/core/module/new_spec.rb index da7f3b872074..ec521360bd7f 100644 --- a/spec/ruby/core/module/new_spec.rb +++ b/spec/ruby/core/module/new_spec.rb @@ -6,6 +6,10 @@ Module.new.is_a?(Module).should == true end + it "creates a module without a name" do + Module.new.name.should be_nil + end + it "creates a new Module and passes it to the provided block" do test_mod = nil m = Module.new do |mod| diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb index 11085c325b13..8b9ea5eca8c8 100644 --- a/spec/ruby/core/module/refine_spec.rb +++ b/spec/ruby/core/module/refine_spec.rb @@ -245,7 +245,7 @@ def foo; "foo from singleton class"; end ruby_version_is ""..."3.2" do it "looks in the included modules for builtin methods" do - result = ruby_exe(<<-RUBY) + result = ruby_exe(<<-RUBY) a = Module.new do def /(other) quo(other) end end diff --git a/spec/ruby/core/objectspace/add_finalizer_spec.rb b/spec/ruby/core/objectspace/add_finalizer_spec.rb deleted file mode 100644 index 3540ac0413d8..000000000000 --- a/spec/ruby/core/objectspace/add_finalizer_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../spec_helper' - -describe "ObjectSpace.add_finalizer" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/objectspace/call_finalizer_spec.rb b/spec/ruby/core/objectspace/call_finalizer_spec.rb deleted file mode 100644 index 6dce92ddd6ee..000000000000 --- a/spec/ruby/core/objectspace/call_finalizer_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../spec_helper' - -describe "ObjectSpace.call_finalizer" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/objectspace/define_finalizer_spec.rb b/spec/ruby/core/objectspace/define_finalizer_spec.rb index effecc41d0a6..4d4cfa9270c3 100644 --- a/spec/ruby/core/objectspace/define_finalizer_spec.rb +++ b/spec/ruby/core/objectspace/define_finalizer_spec.rb @@ -168,6 +168,31 @@ def finalizer(zelf) ruby_exe(code).lines.sort.should == ["finalized1\n", "finalized2\n"] end + it "defines same finalizer only once" do + code = <<~RUBY + obj = Object.new + p = proc { |id| print "ok" } + ObjectSpace.define_finalizer(obj, p.dup) + ObjectSpace.define_finalizer(obj, p.dup) + RUBY + + ruby_exe(code).should == "ok" + end + + it "returns the defined finalizer" do + obj = Object.new + p = proc { |id| } + p2 = p.dup + + ret = ObjectSpace.define_finalizer(obj, p) + ret.should == [0, p] + ret[1].should.equal?(p) + + ret = ObjectSpace.define_finalizer(obj, p2) + ret.should == [0, p] + ret[1].should.equal?(p) + end + ruby_version_is "3.1" do describe "when $VERBOSE is not nil" do it "warns if an exception is raised in finalizer" do diff --git a/spec/ruby/core/objectspace/finalizers_spec.rb b/spec/ruby/core/objectspace/finalizers_spec.rb deleted file mode 100644 index e7f20fc8a020..000000000000 --- a/spec/ruby/core/objectspace/finalizers_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../spec_helper' - -describe "ObjectSpace.finalizers" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/objectspace/remove_finalizer_spec.rb b/spec/ruby/core/objectspace/remove_finalizer_spec.rb deleted file mode 100644 index 0b2b8cf16b60..000000000000 --- a/spec/ruby/core/objectspace/remove_finalizer_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../spec_helper' - -describe "ObjectSpace.remove_finalizer" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/objectspace/undefine_finalizer_spec.rb b/spec/ruby/core/objectspace/undefine_finalizer_spec.rb index 11d43121f868..f57d5a784526 100644 --- a/spec/ruby/core/objectspace/undefine_finalizer_spec.rb +++ b/spec/ruby/core/objectspace/undefine_finalizer_spec.rb @@ -1,5 +1,33 @@ require_relative '../../spec_helper' describe "ObjectSpace.undefine_finalizer" do - it "needs to be reviewed for spec completeness" + it "removes finalizers for an object" do + code = <<~RUBY + obj = Object.new + ObjectSpace.define_finalizer(obj, proc { |id| puts "hello" }) + ObjectSpace.undefine_finalizer(obj) + RUBY + + ruby_exe(code).should.empty? + end + + it "should not remove finalizers for a frozen object" do + code = <<~RUBY + obj = Object.new + ObjectSpace.define_finalizer(obj, proc { |id| print "ok" }) + obj.freeze + begin + ObjectSpace.undefine_finalizer(obj) + rescue + end + RUBY + + ruby_exe(code).should == "ok" + end + + it "should raise when removing finalizers for a frozen object" do + obj = Object.new + obj.freeze + -> { ObjectSpace.undefine_finalizer(obj) }.should raise_error(FrozenError) + end end diff --git a/spec/ruby/core/proc/curry_spec.rb b/spec/ruby/core/proc/curry_spec.rb index 24df2a8a72f4..6daabe0ee170 100644 --- a/spec/ruby/core/proc/curry_spec.rb +++ b/spec/ruby/core/proc/curry_spec.rb @@ -159,15 +159,14 @@ end it "can be passed more than _arity_ arguments if created from a proc" do - -> { @proc_add.curry(3)[1,2,3,4].should == 6 }.should_not - raise_error(ArgumentError) - -> { @proc_add.curry(1)[1,2].curry(3)[3,4,5,6].should == 6 }.should_not - raise_error(ArgumentError) + @proc_add.curry(3)[1,2,3,4].should == 6 + + @proc_add.curry(3)[1,2].curry(3)[3,4,5,6].should == 6 end it "raises an ArgumentError if passed more than _arity_ arguments when created from a lambda" do -> { @lambda_add.curry(3)[1,2,3,4] }.should raise_error(ArgumentError) - -> { @lambda_add.curry(1)[1,2].curry(3)[3,4,5,6] }.should raise_error(ArgumentError) + -> { @lambda_add.curry(3)[1,2].curry(3)[3,4,5,6] }.should raise_error(ArgumentError) end it "returns Procs with arities of -1 regardless of the value of _arity_" do diff --git a/spec/ruby/core/process/constants_spec.rb b/spec/ruby/core/process/constants_spec.rb index 616c54b8e1b4..57cacadef2ba 100644 --- a/spec/ruby/core/process/constants_spec.rb +++ b/spec/ruby/core/process/constants_spec.rb @@ -2,69 +2,91 @@ describe "Process::Constants" do platform_is :darwin, :netbsd, :freebsd do - it "has the correct constant values on BSD-like systems" do - Process::WNOHANG.should == 1 - Process::WUNTRACED.should == 2 - Process::PRIO_PROCESS.should == 0 - Process::PRIO_PGRP.should == 1 - Process::PRIO_USER.should == 2 - Process::RLIM_INFINITY.should == 9223372036854775807 - Process::RLIMIT_CPU.should == 0 - Process::RLIMIT_FSIZE.should == 1 - Process::RLIMIT_DATA.should == 2 - Process::RLIMIT_STACK.should == 3 - Process::RLIMIT_CORE.should == 4 - Process::RLIMIT_RSS.should == 5 - Process::RLIMIT_MEMLOCK.should == 6 - Process::RLIMIT_NPROC.should == 7 - Process::RLIMIT_NOFILE.should == 8 + it "are all present on BSD-like systems" do + %i[ + WNOHANG + WUNTRACED + PRIO_PROCESS + PRIO_PGRP + PRIO_USER + RLIM_INFINITY + RLIMIT_CPU + RLIMIT_FSIZE + RLIMIT_DATA + RLIMIT_STACK + RLIMIT_CORE + RLIMIT_RSS + RLIMIT_MEMLOCK + RLIMIT_NPROC + RLIMIT_NOFILE + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end platform_is :darwin do - it "has the correct constant values on Darwin" do - Process::RLIM_SAVED_MAX.should == 9223372036854775807 - Process::RLIM_SAVED_CUR.should == 9223372036854775807 - Process::RLIMIT_AS.should == 5 + it "are all present on Darwin" do + %i[ + RLIM_SAVED_MAX + RLIM_SAVED_CUR + RLIMIT_AS + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end platform_is :linux do - it "has the correct constant values on Linux" do - Process::WNOHANG.should == 1 - Process::WUNTRACED.should == 2 - Process::PRIO_PROCESS.should == 0 - Process::PRIO_PGRP.should == 1 - Process::PRIO_USER.should == 2 - Process::RLIMIT_CPU.should == 0 - Process::RLIMIT_FSIZE.should == 1 - Process::RLIMIT_DATA.should == 2 - Process::RLIMIT_STACK.should == 3 - Process::RLIMIT_CORE.should == 4 - Process::RLIMIT_RSS.should == 5 - Process::RLIMIT_NPROC.should == 6 - Process::RLIMIT_NOFILE.should == 7 - Process::RLIMIT_MEMLOCK.should == 8 - Process::RLIMIT_AS.should == 9 - - # These values appear to change according to the platform. - values = [4294967295, 9223372036854775807, 18446744073709551615] - values.include?(Process::RLIM_INFINITY).should be_true - values.include?(Process::RLIM_SAVED_MAX).should be_true - values.include?(Process::RLIM_SAVED_CUR).should be_true + it "are all present on Linux" do + %i[ + WNOHANG + WUNTRACED + PRIO_PROCESS + PRIO_PGRP + PRIO_USER + RLIMIT_CPU + RLIMIT_FSIZE + RLIMIT_DATA + RLIMIT_STACK + RLIMIT_CORE + RLIMIT_RSS + RLIMIT_NPROC + RLIMIT_NOFILE + RLIMIT_MEMLOCK + RLIMIT_AS + RLIM_INFINITY + RLIM_SAVED_MAX + RLIM_SAVED_CUR + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end platform_is :netbsd, :freebsd do - it "has the correct constant values on NetBSD and FreeBSD" do - Process::RLIMIT_SBSIZE.should == 9 # FIXME: what's it equal? - Process::RLIMIT_AS.should == 10 + it "are all present on NetBSD and FreeBSD" do + %i[ + RLIMIT_SBSIZE + RLIMIT_AS + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end platform_is :freebsd do - it "has the correct constant values on FreeBSD" do - Process::RLIMIT_NPTS.should == 11 + it "are all present on FreeBSD" do + %i[ + RLIMIT_NPTS + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end diff --git a/spec/ruby/core/process/daemon_spec.rb b/spec/ruby/core/process/daemon_spec.rb index 70ffd1b32015..20b0d743b9a9 100644 --- a/spec/ruby/core/process/daemon_spec.rb +++ b/spec/ruby/core/process/daemon_spec.rb @@ -2,6 +2,9 @@ require_relative 'fixtures/common' platform_is_not :windows do + # macOS 15 is not working this examples + return if /darwin/ =~ RUBY_PLATFORM && /15/ =~ `sw_vers -productVersion` + describe :process_daemon_keep_stdio_open_false, shared: true do it "redirects stdout to /dev/null" do @daemon.invoke("keep_stdio_open_false_stdout", @object).should == "" diff --git a/spec/ruby/core/queue/freeze_spec.rb b/spec/ruby/core/queue/freeze_spec.rb new file mode 100644 index 000000000000..ced2cc52dde6 --- /dev/null +++ b/spec/ruby/core/queue/freeze_spec.rb @@ -0,0 +1,6 @@ +require_relative '../../spec_helper' +require_relative '../../shared/queue/freeze' + +describe "Queue#freeze" do + it_behaves_like :queue_freeze, :freeze, -> { Queue.new } +end diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb index 64ea3de4ed55..31cfd400ccc9 100644 --- a/spec/ruby/core/range/step_spec.rb +++ b/spec/ruby/core/range/step_spec.rb @@ -10,44 +10,50 @@ r.step { }.should equal(r) end - it "raises TypeError if step" do - obj = mock("mock") - -> { (1..10).step(obj) { } }.should raise_error(TypeError) - end + ruby_version_is ""..."3.4" do + it "calls #to_int to coerce step to an Integer" do + obj = mock("Range#step") + obj.should_receive(:to_int).and_return(1) - it "calls #to_int to coerce step to an Integer" do - obj = mock("Range#step") - obj.should_receive(:to_int).and_return(1) + (1..2).step(obj) { |x| ScratchPad << x } + ScratchPad.recorded.should eql([1, 2]) + end - (1..2).step(obj) { |x| ScratchPad << x } - ScratchPad.recorded.should eql([1, 2]) - end + it "raises a TypeError if step does not respond to #to_int" do + obj = mock("Range#step non-integer") - it "raises a TypeError if step does not respond to #to_int" do - obj = mock("Range#step non-integer") + -> { (1..2).step(obj) { } }.should raise_error(TypeError) + end - -> { (1..2).step(obj) { } }.should raise_error(TypeError) - end + it "raises a TypeError if #to_int does not return an Integer" do + obj = mock("Range#step non-integer") + obj.should_receive(:to_int).and_return("1") - it "raises a TypeError if #to_int does not return an Integer" do - obj = mock("Range#step non-integer") - obj.should_receive(:to_int).and_return("1") + -> { (1..2).step(obj) { } }.should raise_error(TypeError) + end - -> { (1..2).step(obj) { } }.should raise_error(TypeError) - end + it "raises a TypeError if the first element does not respond to #succ" do + obj = mock("Range#step non-comparable") + obj.should_receive(:<=>).with(obj).and_return(1) - it "coerces the argument to integer by invoking to_int" do - (obj = mock("2")).should_receive(:to_int).and_return(2) - res = [] - (1..10).step(obj) {|x| res << x} - res.should == [1, 3, 5, 7, 9] + -> { (obj..obj).step { |x| x } }.should raise_error(TypeError) + end end - it "raises a TypeError if the first element does not respond to #succ" do - obj = mock("Range#step non-comparable") - obj.should_receive(:<=>).with(obj).and_return(1) + ruby_version_is "3.4" do + it "calls #coerce to coerce step to an Integer" do + obj = mock("Range#step") + obj.should_receive(:coerce).at_least(:once).and_return([1, 2]) + + (1..3).step(obj) { |x| ScratchPad << x } + ScratchPad.recorded.should eql([1, 3]) + end + + it "raises a TypeError if step does not respond to #coerce" do + obj = mock("Range#step non-coercible") - -> { (obj..obj).step { |x| x } }.should raise_error(TypeError) + -> { (1..2).step(obj) { } }.should raise_error(TypeError) + end end it "raises an ArgumentError if step is 0" do @@ -58,8 +64,17 @@ -> { (-1..1).step(0.0) { |x| x } }.should raise_error(ArgumentError) end - it "raises an ArgumentError if step is negative" do - -> { (-1..1).step(-2) { |x| x } }.should raise_error(ArgumentError) + ruby_version_is "3.4" do + it "does not raise an ArgumentError if step is 0 for non-numeric ranges" do + t = Time.utc(2023, 2, 24) + -> { (t..t+1).step(0) { break } }.should_not raise_error(ArgumentError) + end + end + + ruby_version_is ""..."3.4" do + it "raises an ArgumentError if step is negative" do + -> { (-1..1).step(-2) { |x| x } }.should raise_error(ArgumentError) + end end describe "with inclusive end" do @@ -78,6 +93,18 @@ (-2..2).step(1.5) { |x| ScratchPad << x } ScratchPad.recorded.should eql([-2.0, -0.5, 1.0]) end + + ruby_version_is "3.4" do + it "does not iterate if step is negative for forward range" do + (-1..1).step(-1) { |x| ScratchPad << x } + ScratchPad.recorded.should eql([]) + end + + it "iterates backward if step is negative for backward range" do + (1..-1).step(-1) { |x| ScratchPad << x } + ScratchPad.recorded.should eql([1, 0, -1]) + end + end end describe "and Float values" do @@ -162,13 +189,96 @@ -> { ("A".."G").step(2.0) { } }.should raise_error(TypeError) end - it "calls #succ on begin and each element returned by #succ" do - obj = mock("Range#step String start") - obj.should_receive(:<=>).exactly(3).times.and_return(-1, -1, -1, 0) - obj.should_receive(:succ).exactly(2).times.and_return(obj) + ruby_version_is ""..."3.4" do + it "calls #succ on begin and each element returned by #succ" do + obj = mock("Range#step String start") + obj.should_receive(:<=>).exactly(3).times.and_return(-1, -1, -1, 0) + obj.should_receive(:succ).exactly(2).times.and_return(obj) + + (obj..obj).step { |x| ScratchPad << x } + ScratchPad.recorded.should == [obj, obj, obj] + end + end + + ruby_version_is "3.4" do + it "yields String values adjusted by step and less than or equal to end" do + ("A".."AAA").step("A") { |x| ScratchPad << x } + ScratchPad.recorded.should == ["A", "AA", "AAA"] + end + + it "raises a TypeError when passed an incompatible type step" do + -> { ("A".."G").step([]) { } }.should raise_error(TypeError) + end + + it "calls #+ on begin and each element returned by #+" do + start = mock("Range#step String start") + stop = mock("Range#step String stop") + + mid1 = mock("Range#step String mid1") + mid2 = mock("Range#step String mid2") + + step = mock("Range#step String step") + + # Deciding on the direction of iteration + start.should_receive(:<=>).with(stop).at_least(:twice).and_return(-1) + # Deciding whether the step moves iteration in the right direction + start.should_receive(:<=>).with(mid1).and_return(-1) + # Iteration 1 + start.should_receive(:+).at_least(:once).with(step).and_return(mid1) + # Iteration 2 + mid1.should_receive(:<=>).with(stop).and_return(-1) + mid1.should_receive(:+).with(step).and_return(mid2) + # Iteration 3 + mid2.should_receive(:<=>).with(stop).and_return(0) + + (start..stop).step(step) { |x| ScratchPad << x } + ScratchPad.recorded.should == [start, mid1, mid2] + end + + it "iterates backward if the step is decreasing values, and the range is backward" do + start = mock("Range#step String start") + stop = mock("Range#step String stop") + + mid1 = mock("Range#step String mid1") + mid2 = mock("Range#step String mid2") + + step = mock("Range#step String step") + + # Deciding on the direction of iteration + start.should_receive(:<=>).with(stop).at_least(:twice).and_return(1) + # Deciding whether the step moves iteration in the right direction + start.should_receive(:<=>).with(mid1).and_return(1) + # Iteration 1 + start.should_receive(:+).at_least(:once).with(step).and_return(mid1) + # Iteration 2 + mid1.should_receive(:<=>).with(stop).and_return(1) + mid1.should_receive(:+).with(step).and_return(mid2) + # Iteration 3 + mid2.should_receive(:<=>).with(stop).and_return(0) + + (start..stop).step(step) { |x| ScratchPad << x } + ScratchPad.recorded.should == [start, mid1, mid2] + end + + it "does no iteration of the direction of the range and of the step don't match" do + start = mock("Range#step String start") + stop = mock("Range#step String stop") + + mid1 = mock("Range#step String mid1") + mid2 = mock("Range#step String mid2") + + step = mock("Range#step String step") + + # Deciding on the direction of iteration: stop > start + start.should_receive(:<=>).with(stop).at_least(:twice).and_return(1) + # Deciding whether the step moves iteration in the right direction + # start + step < start, the direction is opposite to the range's + start.should_receive(:+).with(step).and_return(mid1) + start.should_receive(:<=>).with(mid1).and_return(-1) - (obj..obj).step { |x| ScratchPad << x } - ScratchPad.recorded.should == [obj, obj, obj] + (start..stop).step(step) { |x| ScratchPad << x } + ScratchPad.recorded.should == [] + end end end end @@ -266,18 +376,31 @@ end describe "and String values" do - it "yields String values incremented by #succ and less than or equal to end when not passed a step" do - ("A"..."E").step { |x| ScratchPad << x } - ScratchPad.recorded.should == ["A", "B", "C", "D"] - end + ruby_version_is ""..."3.4" do + it "yields String values incremented by #succ and less than or equal to end when not passed a step" do + ("A"..."E").step { |x| ScratchPad << x } + ScratchPad.recorded.should == ["A", "B", "C", "D"] + end - it "yields String values incremented by #succ called Integer step times" do - ("A"..."G").step(2) { |x| ScratchPad << x } - ScratchPad.recorded.should == ["A", "C", "E"] + it "yields String values incremented by #succ called Integer step times" do + ("A"..."G").step(2) { |x| ScratchPad << x } + ScratchPad.recorded.should == ["A", "C", "E"] + end + + it "raises a TypeError when passed a Float step" do + -> { ("A"..."G").step(2.0) { } }.should raise_error(TypeError) + end end - it "raises a TypeError when passed a Float step" do - -> { ("A"..."G").step(2.0) { } }.should raise_error(TypeError) + ruby_version_is "3.4" do + it "yields String values adjusted by step and less than or equal to end" do + ("A"..."AAA").step("A") { |x| ScratchPad << x } + ScratchPad.recorded.should == ["A", "AA"] + end + + it "raises a TypeError when passed an incompatible type step" do + -> { ("A".."G").step([]) { } }.should raise_error(TypeError) + end end end end @@ -373,6 +496,22 @@ -> { eval("('A'..)").step(2.0) { } }.should raise_error(TypeError) -> { eval("('A'...)").step(2.0) { } }.should raise_error(TypeError) end + + ruby_version_is "3.4" do + it "yields String values adjusted by step" do + eval("('A'..)").step("A") { |x| break if x > "AAA"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "AA", "AAA"] + + ScratchPad.record [] + eval("('A'...)").step("A") { |x| break if x > "AAA"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "AA", "AAA"] + end + + it "raises a TypeError when passed an incompatible type step" do + -> { eval("('A'..)").step([]) { } }.should raise_error(TypeError) + -> { eval("('A'...)").step([]) { } }.should raise_error(TypeError) + end + end end end @@ -383,15 +522,24 @@ describe "returned Enumerator" do describe "size" do - it "raises a TypeError if step does not respond to #to_int" do - obj = mock("Range#step non-integer") - -> { (1..2).step(obj) }.should raise_error(TypeError) + ruby_version_is ""..."3.4" do + it "raises a TypeError if step does not respond to #to_int" do + obj = mock("Range#step non-integer") + -> { (1..2).step(obj) }.should raise_error(TypeError) + end + + it "raises a TypeError if #to_int does not return an Integer" do + obj = mock("Range#step non-integer") + obj.should_receive(:to_int).and_return("1") + -> { (1..2).step(obj) }.should raise_error(TypeError) + end end - it "raises a TypeError if #to_int does not return an Integer" do - obj = mock("Range#step non-integer") - obj.should_receive(:to_int).and_return("1") - -> { (1..2).step(obj) }.should raise_error(TypeError) + ruby_version_is "3.4" do + it "does not raise if step is incompatible" do + obj = mock("Range#step non-integer") + -> { (1..2).step(obj) }.should_not raise_error + end end it "returns the ceil of range size divided by the number of steps" do @@ -431,19 +579,36 @@ (1.0...6.4).step(1.8).size.should == 3 end - it "returns nil with begin and end are String" do - ("A".."E").step(2).size.should == nil - ("A"..."E").step(2).size.should == nil - ("A".."E").step.size.should == nil - ("A"..."E").step.size.should == nil + ruby_version_is ""..."3.4" do + it "returns nil with begin and end are String" do + ("A".."E").step(2).size.should == nil + ("A"..."E").step(2).size.should == nil + ("A".."E").step.size.should == nil + ("A"..."E").step.size.should == nil + end + + it "return nil and not raises a TypeError if the first element does not respond to #succ" do + obj = mock("Range#step non-comparable") + obj.should_receive(:<=>).with(obj).and_return(1) + enum = (obj..obj).step + -> { enum.size }.should_not raise_error + enum.size.should == nil + end end - it "return nil and not raises a TypeError if the first element does not respond to #succ" do - obj = mock("Range#step non-comparable") - obj.should_receive(:<=>).with(obj).and_return(1) - enum = (obj..obj).step - -> { enum.size }.should_not raise_error - enum.size.should == nil + ruby_version_is "3.4" do + it "returns nil with begin and end are String" do + ("A".."E").step("A").size.should == nil + ("A"..."E").step("A").size.should == nil + end + + it "return nil and not raises a TypeError if the first element is not of compatible type" do + obj = mock("Range#step non-comparable") + obj.should_receive(:<=>).with(obj).and_return(1) + enum = (obj..obj).step(obj) + -> { enum.size }.should_not raise_error + enum.size.should == nil + end end end @@ -470,22 +635,48 @@ (1..).step(2).take(3).should == [1, 3, 5] end - it "returns an instance of Enumerator when begin is not numeric" do - ("a"..).step.class.should == Enumerator - ("a"..).step(2).take(3).should == %w[a c e] + ruby_version_is ""..."3.4" do + it "returns an instance of Enumerator when begin is not numeric" do + ("a"..).step.class.should == Enumerator + ("a"..).step(2).take(3).should == %w[a c e] + end + end + + ruby_version_is "3.4" do + it "returns an instance of Enumerator when begin is not numeric" do + ("a"..).step("a").class.should == Enumerator + ("a"..).step("a").take(3).should == %w[a aa aaa] + end end end context "when range is beginless and endless" do - it "returns an instance of Enumerator" do - Range.new(nil, nil).step.class.should == Enumerator + ruby_version_is ""..."3.4" do + it "returns an instance of Enumerator" do + Range.new(nil, nil).step.class.should == Enumerator + end + end + + ruby_version_is "3.4" do + it "raises an ArgumentError" do + -> { Range.new(nil, nil).step(1) }.should raise_error(ArgumentError) + end end end context "when begin and end are not numerics" do - it "returns an instance of Enumerator" do - ("a".."z").step.class.should == Enumerator - ("a".."z").step(3).take(4).should == %w[a d g j] + ruby_version_is ""..."3.4" do + it "returns an instance of Enumerator" do + ("a".."z").step.class.should == Enumerator + ("a".."z").step(3).take(4).should == %w[a d g j] + end + end + + ruby_version_is "3.4" do + it "returns an instance of Enumerator" do + ("a".."z").step("a").class.should == Enumerator + ("a".."z").step("a").take(4).should == %w[a aa aaa aaaa] + end end end end diff --git a/spec/ruby/core/regexp/shared/new.rb b/spec/ruby/core/regexp/shared/new.rb index 7052bcab638c..3ca50d5a478f 100644 --- a/spec/ruby/core/regexp/shared/new.rb +++ b/spec/ruby/core/regexp/shared/new.rb @@ -460,6 +460,10 @@ def obj.to_int() ScratchPad.record(:called) end -> { Regexp.send(@method, "\\" + "u{}") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode list: /\\u{}/"))) end + it "raises a RegexpError if the \\u{} escape contains non hexadecimal digits" do + -> { Regexp.send(@method, "\\" + "u{abcX}") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode list: /\\u{abcX}/"))) + end + it "raises a RegexpError if more than six hexadecimal digits are given" do -> { Regexp.send(@method, "\\" + "u{0ffffff}") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode range: /\\u{0ffffff}/"))) end diff --git a/spec/ruby/core/regexp/shared/quote.rb b/spec/ruby/core/regexp/shared/quote.rb index b5ecc35f0423..48179444f091 100644 --- a/spec/ruby/core/regexp/shared/quote.rb +++ b/spec/ruby/core/regexp/shared/quote.rb @@ -2,8 +2,8 @@ describe :regexp_quote, shared: true do it "escapes any characters with special meaning in a regular expression" do - Regexp.send(@method, '\*?{}.+^[]()- ').should == '\\\\\*\?\{\}\.\+\^\[\]\(\)\-\\ ' - Regexp.send(@method, "\*?{}.+^[]()- ").should == '\\*\\?\\{\\}\\.\\+\\^\\[\\]\\(\\)\\-\\ ' + Regexp.send(@method, '\*?{}.+^$[]()- ').should == '\\\\\*\?\{\}\.\+\^\$\[\]\(\)\-\\ ' + Regexp.send(@method, "\*?{}.+^$[]()- ").should == '\\*\\?\\{\\}\\.\\+\\^\\$\\[\\]\\(\\)\\-\\ ' Regexp.send(@method, '\n\r\f\t').should == '\\\\n\\\\r\\\\f\\\\t' Regexp.send(@method, "\n\r\f\t").should == '\\n\\r\\f\\t' end diff --git a/spec/ruby/core/sizedqueue/freeze_spec.rb b/spec/ruby/core/sizedqueue/freeze_spec.rb new file mode 100644 index 000000000000..98f01cae2f87 --- /dev/null +++ b/spec/ruby/core/sizedqueue/freeze_spec.rb @@ -0,0 +1,6 @@ +require_relative '../../spec_helper' +require_relative '../../shared/queue/freeze' + +describe "SizedQueue#freeze" do + it_behaves_like :queue_freeze, :freeze, -> { SizedQueue.new(1) } +end diff --git a/spec/ruby/core/string/append_as_bytes_spec.rb b/spec/ruby/core/string/append_as_bytes_spec.rb new file mode 100644 index 000000000000..0e1d09558bd1 --- /dev/null +++ b/spec/ruby/core/string/append_as_bytes_spec.rb @@ -0,0 +1,46 @@ +require_relative '../../spec_helper' + +describe "String#append_bytes" do + ruby_version_is "3.4" do + it "doesn't allow to mutate frozen strings" do + str = "hello".freeze + -> { str.append_as_bytes("\xE2\x82") }.should raise_error(FrozenError) + end + + it "allows creating broken strings" do + str = +"hello" + str.append_as_bytes("\xE2\x82") + str.valid_encoding?.should == false + + str.append_as_bytes("\xAC") + str.valid_encoding?.should == true + + str = "abc".encode(Encoding::UTF_32LE) + str.append_as_bytes("def") + str.encoding.should == Encoding::UTF_32LE + str.valid_encoding?.should == false + end + + it "never changes the receiver encoding" do + str = "".b + str.append_as_bytes("€") + str.encoding.should == Encoding::BINARY + end + + it "accepts variadic String or Integer arguments" do + str = "hello".b + str.append_as_bytes("\xE2\x82", 12, 43, "\xAC") + str.encoding.should == Encoding::BINARY + str.should == "hello\xE2\x82\f+\xAC".b + end + + it "only accepts strings or integers, and doesn't attempt to cast with #to_str or #to_int" do + to_str = mock("to_str") + to_str.should_not_receive(:to_str) + to_str.should_not_receive(:to_int) + + str = +"hello" + -> { str.append_as_bytes(to_str) }.should raise_error(TypeError, "wrong argument type MockObject (expected String or Integer)") + end + end +end diff --git a/spec/ruby/core/string/byteslice_spec.rb b/spec/ruby/core/string/byteslice_spec.rb index 5b1027f4a579..9fe504aeb1c1 100644 --- a/spec/ruby/core/string/byteslice_spec.rb +++ b/spec/ruby/core/string/byteslice_spec.rb @@ -17,7 +17,7 @@ it_behaves_like :string_slice_range, :byteslice end -describe "String#byteslice on on non ASCII strings" do +describe "String#byteslice on non ASCII strings" do it "returns byteslice of unicode strings" do "\u3042".byteslice(1).should == "\x81".dup.force_encoding("UTF-8") "\u3042".byteslice(1, 2).should == "\x81\x82".dup.force_encoding("UTF-8") diff --git a/spec/ruby/core/string/modulo_spec.rb b/spec/ruby/core/string/modulo_spec.rb index 9045afa263a6..8e3853551f36 100644 --- a/spec/ruby/core/string/modulo_spec.rb +++ b/spec/ruby/core/string/modulo_spec.rb @@ -570,7 +570,7 @@ def universal.to_f() 0.0 end ("%1$p" % [10, 5]).should == "10" ("%-22p" % 10).should == "10 " ("%*p" % [10, 10]).should == " 10" - ("%p" % {capture: 1}).should == "{:capture=>1}" + ("%p" % {capture: 1}).should == {capture: 1}.inspect ("%p" % "str").should == "\"str\"" end @@ -749,6 +749,9 @@ def obj.to_s() "obj" end (format % "-10.4e-20").should == (format % -10.4e-20) (format % ".5").should == (format % 0.5) (format % "-.5").should == (format % -0.5) + ruby_bug("#20705", ""..."3.4") do + (format % "10.").should == (format % 10) + end # Something's strange with this spec: # it works just fine in individual mode, but not when run as part of a group (format % "10_1_0.5_5_5").should == (format % 1010.555) @@ -758,7 +761,6 @@ def obj.to_s() "obj" end -> { format % "" }.should raise_error(ArgumentError) -> { format % "x" }.should raise_error(ArgumentError) -> { format % "." }.should raise_error(ArgumentError) - -> { format % "10." }.should raise_error(ArgumentError) -> { format % "5x" }.should raise_error(ArgumentError) -> { format % "0b1" }.should raise_error(ArgumentError) -> { format % "10e10.5" }.should raise_error(ArgumentError) diff --git a/spec/ruby/core/string/unpack/l_spec.rb b/spec/ruby/core/string/unpack/l_spec.rb index 18bb68b8d06a..0adb567eca65 100644 --- a/spec/ruby/core/string/unpack/l_spec.rb +++ b/spec/ruby/core/string/unpack/l_spec.rb @@ -14,7 +14,7 @@ it_behaves_like :string_unpack_32bit_be_unsigned, 'L>' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "with modifier '<' and '_'" do it_behaves_like :string_unpack_32bit_le, 'L<_' it_behaves_like :string_unpack_32bit_le, 'L_<' @@ -44,7 +44,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "with modifier '<' and '_'" do it_behaves_like :string_unpack_64bit_le, 'L<_' it_behaves_like :string_unpack_64bit_le, 'L_<' @@ -86,7 +86,7 @@ it_behaves_like :string_unpack_32bit_be_signed, 'l>' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "with modifier '<' and '_'" do it_behaves_like :string_unpack_32bit_le, 'l<_' it_behaves_like :string_unpack_32bit_le, 'l_<' @@ -116,7 +116,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "with modifier '<' and '_'" do it_behaves_like :string_unpack_64bit_le, 'l<_' it_behaves_like :string_unpack_64bit_le, 'l_<' @@ -160,7 +160,7 @@ it_behaves_like :string_unpack_32bit_le_signed, 'l' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "String#unpack with format 'L' with modifier '_'" do it_behaves_like :string_unpack_32bit_le, 'L_' it_behaves_like :string_unpack_32bit_le_unsigned, 'L_' @@ -182,7 +182,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "String#unpack with format 'L' with modifier '_'" do it_behaves_like :string_unpack_64bit_le, 'L_' it_behaves_like :string_unpack_64bit_le_unsigned, 'L_' @@ -218,7 +218,7 @@ it_behaves_like :string_unpack_32bit_be_signed, 'l' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "String#unpack with format 'L' with modifier '_'" do it_behaves_like :string_unpack_32bit_be, 'L_' it_behaves_like :string_unpack_32bit_be_unsigned, 'L_' @@ -240,7 +240,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "String#unpack with format 'L' with modifier '_'" do it_behaves_like :string_unpack_64bit_be, 'L_' it_behaves_like :string_unpack_64bit_be_unsigned, 'L_' diff --git a/spec/ruby/core/thread/group_spec.rb b/spec/ruby/core/thread/group_spec.rb index 59f5ac37c8bc..d0d4704b66fe 100644 --- a/spec/ruby/core/thread/group_spec.rb +++ b/spec/ruby/core/thread/group_spec.rb @@ -1,5 +1,16 @@ require_relative '../../spec_helper' -require_relative 'fixtures/classes' + describe "Thread#group" do - it "needs to be reviewed for spec completeness" + it "returns the default thread group for the main thread" do + Thread.main.group.should == ThreadGroup::Default + end + + it "returns the thread group explicitly set for this thread" do + thread = Thread.new { nil } + thread_group = ThreadGroup.new + thread_group.add(thread) + thread.group.should == thread_group + ensure + thread.join if thread + end end diff --git a/spec/ruby/core/thread/thread_variable_get_spec.rb b/spec/ruby/core/thread/thread_variable_get_spec.rb index 69eccd376515..1ea34cf2b319 100644 --- a/spec/ruby/core/thread/thread_variable_get_spec.rb +++ b/spec/ruby/core/thread/thread_variable_get_spec.rb @@ -41,15 +41,20 @@ @t.thread_variable_get(:a).should be_nil end - ruby_bug "#20606", ""..."3.4" do - it "raises a TypeError if the key is neither Symbol nor String, nor responds to #to_str" do + it "raises a TypeError if the key is neither Symbol nor String when thread variables are already set" do + @t.thread_variable_set(:a, 49) + -> { @t.thread_variable_get(123) }.should raise_error(TypeError, /123 is not a symbol/) + end + + ruby_version_is '3.4' do + it "raises a TypeError if the key is neither Symbol nor String when no thread variables are set" do -> { @t.thread_variable_get(123) }.should raise_error(TypeError, /123 is not a symbol/) end - it "does not try to convert the key with #to_sym" do + it "raises a TypeError if the key is neither Symbol nor String without calling #to_sym" do key = mock('key') key.should_not_receive(:to_sym) - -> { @t.thread_variable_get(key) }.should raise_error(TypeError) + -> { @t.thread_variable_get(key) }.should raise_error(TypeError, /#{Regexp.escape(key.inspect)} is not a symbol/) end end end diff --git a/spec/ruby/core/thread/thread_variable_set_spec.rb b/spec/ruby/core/thread/thread_variable_set_spec.rb index 52a414c1a3c1..eadee76afba0 100644 --- a/spec/ruby/core/thread/thread_variable_set_spec.rb +++ b/spec/ruby/core/thread/thread_variable_set_spec.rb @@ -57,6 +57,6 @@ it "does not try to convert the key with #to_sym" do key = mock('key') key.should_not_receive(:to_sym) - -> { @t.thread_variable_set(key, 42) }.should raise_error(TypeError, /#{key.inspect} is not a symbol/) + -> { @t.thread_variable_set(key, 42) }.should raise_error(TypeError, /#{Regexp.quote(key.inspect)} is not a symbol/) end end diff --git a/spec/ruby/core/thread/thread_variable_spec.rb b/spec/ruby/core/thread/thread_variable_spec.rb index 326e0f419ca6..1b021e94044d 100644 --- a/spec/ruby/core/thread/thread_variable_spec.rb +++ b/spec/ruby/core/thread/thread_variable_spec.rb @@ -41,15 +41,20 @@ @t.thread_variable?(:a).should be_false end - ruby_bug "#20606", ""..."3.4" do - it "raises a TypeError if the key is neither Symbol nor String, nor responds to #to_str" do + it "raises a TypeError if the key is neither Symbol nor String when thread variables are already set" do + @t.thread_variable_set(:a, 49) + -> { @t.thread_variable?(123) }.should raise_error(TypeError, /123 is not a symbol/) + end + + ruby_version_is '3.4' do + it "raises a TypeError if the key is neither Symbol nor String when no thread variables are set" do -> { @t.thread_variable?(123) }.should raise_error(TypeError, /123 is not a symbol/) end - it "does not try to convert the key with #to_sym" do + it "raises a TypeError if the key is neither Symbol nor String without calling #to_sym" do key = mock('key') key.should_not_receive(:to_sym) - -> { @t.thread_variable?(key) }.should raise_error(TypeError) + -> { @t.thread_variable?(key) }.should raise_error(TypeError, /#{Regexp.escape(key.inspect)} is not a symbol/) end end end diff --git a/spec/ruby/core/time/iso8601_spec.rb b/spec/ruby/core/time/iso8601_spec.rb new file mode 100644 index 000000000000..ad60c3bb3221 --- /dev/null +++ b/spec/ruby/core/time/iso8601_spec.rb @@ -0,0 +1,6 @@ +require_relative '../../spec_helper' +require_relative 'shared/xmlschema' + +describe "Time#iso8601" do + it_behaves_like :time_xmlschema, :iso8601 +end diff --git a/spec/ruby/core/time/new_spec.rb b/spec/ruby/core/time/new_spec.rb index 66f16adf9135..c310a8631e26 100644 --- a/spec/ruby/core/time/new_spec.rb +++ b/spec/ruby/core/time/new_spec.rb @@ -645,7 +645,7 @@ def obj.to_int; 3; end -> { Time.new("2020-12-25 00:56:17 +23:59:60") - }.should raise_error(ArgumentError, /(utc_offset|argument) out of range/) + }.should raise_error(ArgumentError, /utc_offset|argument out of range/) -> { Time.new("2020-12-25 00:56:17 +24:00") @@ -653,7 +653,13 @@ def obj.to_int; 3; end -> { Time.new("2020-12-25 00:56:17 +23:61") - }.should raise_error(ArgumentError, /#{Regexp.escape('"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +23:61')}|can't parse:/) + }.should raise_error(ArgumentError, /utc_offset|can't parse:/) + + ruby_bug '#20797', ''...'3.4' do + -> { + Time.new("2020-12-25 00:56:17 +00:23:61") + }.should raise_error(ArgumentError, /utc_offset/) + end end it "raises ArgumentError if string has not ascii-compatible encoding" do diff --git a/spec/ruby/core/time/shared/xmlschema.rb b/spec/ruby/core/time/shared/xmlschema.rb new file mode 100644 index 000000000000..d68c18df364b --- /dev/null +++ b/spec/ruby/core/time/shared/xmlschema.rb @@ -0,0 +1,31 @@ +describe :time_xmlschema, shared: true do + ruby_version_is "3.4" do + it "generates ISO-8601 strings in Z for UTC times" do + t = Time.utc(1985, 4, 12, 23, 20, 50, 521245) + t.send(@method).should == "1985-04-12T23:20:50Z" + t.send(@method, 2).should == "1985-04-12T23:20:50.52Z" + t.send(@method, 9).should == "1985-04-12T23:20:50.521245000Z" + end + + it "generates ISO-8601 string with timeone offset for non-UTC times" do + t = Time.new(1985, 4, 12, 23, 20, 50, "+02:00") + t.send(@method).should == "1985-04-12T23:20:50+02:00" + t.send(@method, 2).should == "1985-04-12T23:20:50.00+02:00" + end + + it "year is always at least 4 digits" do + t = Time.utc(12, 4, 12) + t.send(@method).should == "0012-04-12T00:00:00Z" + end + + it "year can be more than 4 digits" do + t = Time.utc(40_000, 4, 12) + t.send(@method).should == "40000-04-12T00:00:00Z" + end + + it "year can be negative" do + t = Time.utc(-2000, 4, 12) + t.send(@method).should == "-2000-04-12T00:00:00Z" + end + end +end diff --git a/spec/ruby/core/time/xmlschema_spec.rb b/spec/ruby/core/time/xmlschema_spec.rb new file mode 100644 index 000000000000..bdf1dc7923ee --- /dev/null +++ b/spec/ruby/core/time/xmlschema_spec.rb @@ -0,0 +1,6 @@ +require_relative '../../spec_helper' +require_relative 'shared/xmlschema' + +describe "Time#xmlschema" do + it_behaves_like :time_xmlschema, :xmlschema +end diff --git a/spec/ruby/core/tracepoint/inspect_spec.rb b/spec/ruby/core/tracepoint/inspect_spec.rb index d0e633c49b04..6cc2ebe24342 100644 --- a/spec/ruby/core/tracepoint/inspect_spec.rb +++ b/spec/ruby/core/tracepoint/inspect_spec.rb @@ -67,7 +67,7 @@ def trace_point_spec_test_return end trace_point_spec_test_return end - ruby_version_is("3.4") { line = "(?:#{line}|#{line-1})" } + ruby_version_is("3.4") { line -= 1 } inspect.should =~ /\A#\z/ end diff --git a/spec/ruby/fixtures/constants.rb b/spec/ruby/fixtures/constants.rb index ffe45fb1f670..7f0b88daab7c 100644 --- a/spec/ruby/fixtures/constants.rb +++ b/spec/ruby/fixtures/constants.rb @@ -10,7 +10,7 @@ # variety in class and module configurations, including hierarchy, # containment, inclusion, singletons and toplevel. # -# Constants are numbered for for uniqueness. The CS_ prefix is uniformly used +# Constants are numbered for uniqueness. The CS_ prefix is uniformly used # and is to minimize clashes with other toplevel constants (see e.g. ModuleA # which is included in Object). Constant values are symbols. A numbered suffix # is used to distinguish constants with the same name defined in different diff --git a/spec/ruby/language/fixtures/private.rb b/spec/ruby/language/fixtures/private.rb index 96f73cea3fd6..da3e0a97f9e1 100644 --- a/spec/ruby/language/fixtures/private.rb +++ b/spec/ruby/language/fixtures/private.rb @@ -43,17 +43,17 @@ def foo end end - class E - include D - end - - class G - def foo - "foo" - end - end - - class H < A - private :foo - end + class E + include D + end + + class G + def foo + "foo" + end + end + + class H < A + private :foo + end end diff --git a/spec/ruby/language/fixtures/send.rb b/spec/ruby/language/fixtures/send.rb index 918241e17113..5d1d9da21439 100644 --- a/spec/ruby/language/fixtures/send.rb +++ b/spec/ruby/language/fixtures/send.rb @@ -43,9 +43,9 @@ class PrivateSetter attr_writer :foo private :foo= - def call_self_foo_equals(value) - self.foo = value - end + def call_self_foo_equals(value) + self.foo = value + end def call_self_foo_equals_masgn(value) a, self.foo = 1, value diff --git a/spec/ruby/language/pattern_matching_spec.rb b/spec/ruby/language/pattern_matching_spec.rb index 52608b48bea4..94432b1fa000 100644 --- a/spec/ruby/language/pattern_matching_spec.rb +++ b/spec/ruby/language/pattern_matching_spec.rb @@ -232,11 +232,12 @@ end }.should raise_error(NoMatchingPatternError, /\[0, 1\]/) + error_pattern = ruby_version_is("3.4") ? /\{a: 0, b: 1\}/ : /\{:a=>0, :b=>1\}/ -> { case {a: 0, b: 1} in a: 1, b: 1 end - }.should raise_error(NoMatchingPatternError, /\{:a=>0, :b=>1\}/) + }.should raise_error(NoMatchingPatternError, error_pattern) end it "raises NoMatchingPatternError if no pattern matches and evaluates the expression only once" do diff --git a/spec/ruby/language/precedence_spec.rb b/spec/ruby/language/precedence_spec.rb index c5adcca2c046..5e606c16d86a 100644 --- a/spec/ruby/language/precedence_spec.rb +++ b/spec/ruby/language/precedence_spec.rb @@ -294,14 +294,14 @@ class FalseClass; undef_method :=~; end -> { eval("1...2...3") }.should raise_error(SyntaxError) end - it ".. ... have higher precedence than ? :" do - # Use variables to avoid warnings - from = 1 - to = 2 - # These are flip-flop, not Range instances - (from..to ? 3 : 4).should == 3 - (from...to ? 3 : 4).should == 3 - end + it ".. ... have higher precedence than ? :" do + # Use variables to avoid warnings + from = 1 + to = 2 + # These are flip-flop, not Range instances + (from..to ? 3 : 4).should == 3 + (from...to ? 3 : 4).should == 3 + end it "? : is right-associative" do (true ? 2 : 3 ? 4 : 5).should == 2 diff --git a/spec/ruby/language/regexp_spec.rb b/spec/ruby/language/regexp_spec.rb index 89d091480725..dbf341b19ea5 100644 --- a/spec/ruby/language/regexp_spec.rb +++ b/spec/ruby/language/regexp_spec.rb @@ -62,7 +62,7 @@ end end - it "supports non-paired delimiters delimiters with %r" do + it "supports non-paired delimiters with %r" do LanguageSpecs.non_paired_delimiters.each do |c| eval("%r#{c} foo #{c}").should == / foo / end diff --git a/spec/ruby/language/super_spec.rb b/spec/ruby/language/super_spec.rb index a98b3b3091ef..7d9e896d8b11 100644 --- a/spec/ruby/language/super_spec.rb +++ b/spec/ruby/language/super_spec.rb @@ -70,7 +70,7 @@ SuperSpecs::S4::B.new.foo([],"test").should == ["B#foo(a,test)", "A#foo"] end - it "raises an error error when super method does not exist" do + it "raises an error when super method does not exist" do sup = Class.new sub_normal = Class.new(sup) do def foo diff --git a/spec/ruby/library/bigdecimal/fix_spec.rb b/spec/ruby/library/bigdecimal/fix_spec.rb index 231c9a587e3c..2c6276899ed9 100644 --- a/spec/ruby/library/bigdecimal/fix_spec.rb +++ b/spec/ruby/library/bigdecimal/fix_spec.rb @@ -2,20 +2,20 @@ require 'bigdecimal' describe "BigDecimal#fix" do - before :each do - @zero = BigDecimal("0") - @mixed = BigDecimal("1.23456789") - @pos_int = BigDecimal("2E5555") - @neg_int = BigDecimal("-2E5555") - @pos_frac = BigDecimal("2E-9999") - @neg_frac = BigDecimal("-2E-9999") - - @infinity = BigDecimal("Infinity") - @infinity_neg = BigDecimal("-Infinity") - @nan = BigDecimal("NaN") - @zero_pos = BigDecimal("+0") - @zero_neg = BigDecimal("-0") - end + before :each do + @zero = BigDecimal("0") + @mixed = BigDecimal("1.23456789") + @pos_int = BigDecimal("2E5555") + @neg_int = BigDecimal("-2E5555") + @pos_frac = BigDecimal("2E-9999") + @neg_frac = BigDecimal("-2E-9999") + + @infinity = BigDecimal("Infinity") + @infinity_neg = BigDecimal("-Infinity") + @nan = BigDecimal("NaN") + @zero_pos = BigDecimal("+0") + @zero_neg = BigDecimal("-0") + end it "returns a BigDecimal" do BigDecimal("2E100000000").fix.kind_of?(BigDecimal).should == true diff --git a/spec/ruby/library/bigdecimal/sqrt_spec.rb b/spec/ruby/library/bigdecimal/sqrt_spec.rb index 8fd1ec0f39fa..42cf4545cb3e 100644 --- a/spec/ruby/library/bigdecimal/sqrt_spec.rb +++ b/spec/ruby/library/bigdecimal/sqrt_spec.rb @@ -36,7 +36,7 @@ BigDecimal('121').sqrt(5).should be_close(11, 0.00001) end - platform_is_not wordsize: 32 do # fails on i686 + platform_is_not c_long_size: 32 do # fails on i686 it "returns square root of 0.9E-99999 with desired precision" do @frac_2.sqrt(1).to_s.should =~ /\A0\.3E-49999\z/i end diff --git a/spec/ruby/library/date/mon_spec.rb b/spec/ruby/library/date/mon_spec.rb index 724e7d6564ee..616d72cf8824 100644 --- a/spec/ruby/library/date/mon_spec.rb +++ b/spec/ruby/library/date/mon_spec.rb @@ -1,6 +1,7 @@ require_relative '../../spec_helper' +require_relative 'shared/month' require 'date' describe "Date#mon" do - it "needs to be reviewed for spec completeness" + it_behaves_like :date_month, :mon end diff --git a/spec/ruby/library/date/month_spec.rb b/spec/ruby/library/date/month_spec.rb index e040f9a94c9f..f493ec81192f 100644 --- a/spec/ruby/library/date/month_spec.rb +++ b/spec/ruby/library/date/month_spec.rb @@ -1,9 +1,7 @@ require_relative '../../spec_helper' +require_relative 'shared/month' require 'date' describe "Date#month" do - it "returns the month" do - m = Date.new(2000, 7, 1).month - m.should == 7 - end + it_behaves_like :date_month, :month end diff --git a/spec/ruby/library/date/shared/month.rb b/spec/ruby/library/date/shared/month.rb new file mode 100644 index 000000000000..5fcb2cbeb0ce --- /dev/null +++ b/spec/ruby/library/date/shared/month.rb @@ -0,0 +1,6 @@ +describe :date_month, shared: true do + it "returns the month" do + m = Date.new(2000, 7, 1).send(@method) + m.should == 7 + end +end diff --git a/spec/ruby/library/erb/new_spec.rb b/spec/ruby/library/erb/new_spec.rb index a5aeeaeed101..f721529ab004 100644 --- a/spec/ruby/library/erb/new_spec.rb +++ b/spec/ruby/library/erb/new_spec.rb @@ -130,7 +130,7 @@ <%#= item %> <%# end %> END - ERBSpecs.new_erb(input).result.should == "\n\n\n" + ERBSpecs.new_erb(input).result.should == "\n\n\n" ERBSpecs.new_erb(input, trim_mode: '<>').result.should == "\n" end diff --git a/spec/ruby/library/logger/logger/new_spec.rb b/spec/ruby/library/logger/logger/new_spec.rb index d3100ee2d1be..6dcb030ae1fe 100644 --- a/spec/ruby/library/logger/logger/new_spec.rb +++ b/spec/ruby/library/logger/logger/new_spec.rb @@ -13,19 +13,19 @@ rm_r @file_path end - it "creates a new logger object" do - l = Logger.new(STDERR) - -> { l.add(Logger::WARN, "Foo") }.should output_to_fd(/Foo/, STDERR) - end - - it "receives a logging device as first argument" do - l = Logger.new(@log_file) - l.add(Logger::WARN, "Test message") - - @log_file.rewind - LoggerSpecs.strip_date(@log_file.readline).should == "WARN -- : Test message\n" - l.close - end + it "creates a new logger object" do + l = Logger.new(STDERR) + -> { l.add(Logger::WARN, "Foo") }.should output_to_fd(/Foo/, STDERR) + end + + it "receives a logging device as first argument" do + l = Logger.new(@log_file) + l.add(Logger::WARN, "Test message") + + @log_file.rewind + LoggerSpecs.strip_date(@log_file.readline).should == "WARN -- : Test message\n" + l.close + end it "receives a frequency rotation as second argument" do -> { Logger.new(@log_file, "daily") }.should_not raise_error diff --git a/spec/ruby/library/net-http/http/post_spec.rb b/spec/ruby/library/net-http/http/post_spec.rb index d7d94fec4a70..ac020bd6bed8 100644 --- a/spec/ruby/library/net-http/http/post_spec.rb +++ b/spec/ruby/library/net-http/http/post_spec.rb @@ -27,7 +27,7 @@ it "sends Content-Type: application/x-www-form-urlencoded by default" do response = Net::HTTP.post(URI("http://localhost:#{NetHTTPSpecs.port}/request/header"), "test=test") - response.body.should include('"Content-Type"=>"application/x-www-form-urlencoded"') + response.body.should include({ "Content-Type" => "application/x-www-form-urlencoded" }.inspect.delete("{}")) end it "does not support HTTP Basic Auth" do diff --git a/spec/ruby/library/net-http/http/send_request_spec.rb b/spec/ruby/library/net-http/http/send_request_spec.rb index e82b2a96a187..af35c068ceae 100644 --- a/spec/ruby/library/net-http/http/send_request_spec.rb +++ b/spec/ruby/library/net-http/http/send_request_spec.rb @@ -54,7 +54,7 @@ @methods.each do |method| response = @http.send_request(method, "/request/header", "test=test", "referer" => referer) - response.body.should include('"Referer"=>"' + referer + '"') + response.body.should include({ "Referer" => referer }.inspect.delete("{}")) end end end diff --git a/spec/ruby/library/objectspace/memsize_of_spec.rb b/spec/ruby/library/objectspace/memsize_of_spec.rb index eefafbb334df..cbb5a07d54f9 100644 --- a/spec/ruby/library/objectspace/memsize_of_spec.rb +++ b/spec/ruby/library/objectspace/memsize_of_spec.rb @@ -13,7 +13,7 @@ end it "returns 0 for literal Symbols" do - ObjectSpace.memsize_of(:abc).should == 0 + ObjectSpace.memsize_of(:object_space_memsize_spec_static_sym).should == 0 end it "returns a positive Integer for an Object" do diff --git a/spec/ruby/library/pathname/glob_spec.rb b/spec/ruby/library/pathname/glob_spec.rb index ced810fa907e..de322bab4763 100644 --- a/spec/ruby/library/pathname/glob_spec.rb +++ b/spec/ruby/library/pathname/glob_spec.rb @@ -21,6 +21,10 @@ Pathname.glob(@dir + 'lib/*.js').should == [] end + it 'returns [] when the pathname does not exist' do + Pathname.glob('i_dont_exist/lib/*.js').should == [] + end + it 'returns matching file paths' do Pathname.glob(@dir + 'lib/*i*.rb').sort.should == [Pathname.new(@file_1), Pathname.new(@file_2)].sort end @@ -67,6 +71,10 @@ Pathname.new(@dir).glob('lib/*.js').should == [] end + it 'returns [] when the pathname does not exist' do + Pathname.new('./i_dont_exist').glob('lib/*.js').should == [] + end + it 'returns matching file paths' do Pathname.new(@dir).glob('lib/*i*.rb').sort.should == [Pathname.new(@file_1), Pathname.new(@file_2)].sort end diff --git a/spec/ruby/library/pp/pp_spec.rb b/spec/ruby/library/pp/pp_spec.rb index 243478efd967..e45a6bb94f67 100644 --- a/spec/ruby/library/pp/pp_spec.rb +++ b/spec/ruby/library/pp/pp_spec.rb @@ -25,6 +25,6 @@ hash = { 'key' => 42 } -> { PP.pp hash - }.should output('{"key"=>42}' + "\n") + }.should output("#{hash.inspect}\n") end end diff --git a/spec/ruby/library/set/hash_spec.rb b/spec/ruby/library/set/hash_spec.rb index 47c43c05f16a..c5bab73931fe 100644 --- a/spec/ruby/library/set/hash_spec.rb +++ b/spec/ruby/library/set/hash_spec.rb @@ -10,4 +10,9 @@ Set[].hash.should_not == Set[1, 2, 3].hash Set[1, 2, 3].hash.should_not == Set[:a, "b", ?c].hash end + + # see https://github.com/jruby/jruby/issues/8393 + it "is equal to nil.hash for an uninitialized Set" do + Set.allocate.hash.should == nil.hash + end end diff --git a/spec/ruby/library/set/merge_spec.rb b/spec/ruby/library/set/merge_spec.rb index a8e3ffc87090..3ae0da827c82 100644 --- a/spec/ruby/library/set/merge_spec.rb +++ b/spec/ruby/library/set/merge_spec.rb @@ -16,4 +16,16 @@ -> { Set[1, 2].merge(1) }.should raise_error(ArgumentError) -> { Set[1, 2].merge(Object.new) }.should raise_error(ArgumentError) end + + ruby_version_is ""..."3.3" do + it "accepts only a single argument" do + -> { Set[].merge([], []) }.should raise_error(ArgumentError, "wrong number of arguments (given 2, expected 1)") + end + end + + ruby_version_is "3.3" do + it "accepts multiple arguments" do + Set[:a, :b].merge(Set[:b, :c], [:d]).should == Set[:a, :b, :c, :d] + end + end end diff --git a/spec/ruby/library/socket/addrinfo/initialize_spec.rb b/spec/ruby/library/socket/addrinfo/initialize_spec.rb index 83b204b57574..d8885c5d622d 100644 --- a/spec/ruby/library/socket/addrinfo/initialize_spec.rb +++ b/spec/ruby/library/socket/addrinfo/initialize_spec.rb @@ -335,7 +335,7 @@ @sockaddr = ['AF_INET6', 80, 'hostname', '127.0.0.1'] end - it "raises SocketError when using any Socket constant except except AF_INET(6)/PF_INET(6)" do + it "raises SocketError when using any Socket constant except AF_INET(6)/PF_INET(6)" do Socket.constants.grep(/(^AF_|^PF_)(?!INET)/).each do |constant| value = Socket.const_get(constant) -> { diff --git a/spec/ruby/library/socket/basicsocket/send_spec.rb b/spec/ruby/library/socket/basicsocket/send_spec.rb index 86b5567026d8..1c028480e3e8 100644 --- a/spec/ruby/library/socket/basicsocket/send_spec.rb +++ b/spec/ruby/library/socket/basicsocket/send_spec.rb @@ -16,27 +16,27 @@ @socket.close end - it "sends a message to another socket and returns the number of bytes sent" do - data = +"" - t = Thread.new do - client = @server.accept - loop do - got = client.recv(5) - break if got.nil? || got.empty? - data << got - end - client.close - end - Thread.pass while t.status and t.status != "sleep" - t.status.should_not be_nil + it "sends a message to another socket and returns the number of bytes sent" do + data = +"" + t = Thread.new do + client = @server.accept + loop do + got = client.recv(5) + break if got.nil? || got.empty? + data << got + end + client.close + end + Thread.pass while t.status and t.status != "sleep" + t.status.should_not be_nil - @socket.send('hello', 0).should == 5 - @socket.shutdown(1) # indicate, that we are done sending - @socket.recv(10) + @socket.send('hello', 0).should == 5 + @socket.shutdown(1) # indicate, that we are done sending + @socket.recv(10) - t.join - data.should == 'hello' - end + t.join + data.should == 'hello' + end platform_is_not :solaris, :windows do it "accepts flags to specify unusual sending behaviour" do diff --git a/spec/ruby/library/socket/socket/connect_spec.rb b/spec/ruby/library/socket/socket/connect_spec.rb index 8653fba552bd..175c9942bcd6 100644 --- a/spec/ruby/library/socket/socket/connect_spec.rb +++ b/spec/ruby/library/socket/socket/connect_spec.rb @@ -53,4 +53,18 @@ end end end + + ruby_version_is "3.4" do + it "fails with timeout" do + # TEST-NET-1 IP address are reserved for documentation and example purposes. + address = Socket.pack_sockaddr_in(1, "192.0.2.1") + + client = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM) + client.timeout = 0 + + -> { + client.connect(address) + }.should raise_error(IO::TimeoutError) + end + end end diff --git a/spec/ruby/library/stringio/fixtures/classes.rb b/spec/ruby/library/stringio/fixtures/classes.rb index bb8dc354cc44..832c5457d771 100644 --- a/spec/ruby/library/stringio/fixtures/classes.rb +++ b/spec/ruby/library/stringio/fixtures/classes.rb @@ -4,12 +4,12 @@ class StringSubclass < String; end module StringIOSpecs def self.build - str = <<-EOS + str = <<-EOS each peach pear plum - EOS + EOS StringIO.new(str) end end diff --git a/spec/ruby/library/stringio/shared/sysread.rb b/spec/ruby/library/stringio/shared/sysread.rb index 937bac705cb6..3e23fbc23351 100644 --- a/spec/ruby/library/stringio/shared/sysread.rb +++ b/spec/ruby/library/stringio/shared/sysread.rb @@ -10,6 +10,6 @@ it "raises an EOFError when passed length > 0 and no data remains" do @io.read.should == "example" - -> { @io.sysread(1) }.should raise_error(EOFError) + -> { @io.send(@method, 1) }.should raise_error(EOFError) end end diff --git a/spec/ruby/library/stringio/sysread_spec.rb b/spec/ruby/library/stringio/sysread_spec.rb index 8f78073f428b..fabb06dd9a66 100644 --- a/spec/ruby/library/stringio/sysread_spec.rb +++ b/spec/ruby/library/stringio/sysread_spec.rb @@ -1,6 +1,7 @@ require_relative '../../spec_helper' require "stringio" require_relative 'shared/read' +require_relative 'shared/sysread' describe "StringIO#sysread when passed length, buffer" do it_behaves_like :stringio_read, :sysread @@ -32,6 +33,10 @@ end end +describe "StringIO#sysread when passed length" do + it_behaves_like :stringio_sysread_length, :sysread +end + describe "StringIO#sysread when passed [length]" do before :each do @io = StringIO.new("example") diff --git a/spec/ruby/library/stringscanner/check_until_spec.rb b/spec/ruby/library/stringscanner/check_until_spec.rb index ad222fd76b3e..1d89f88a25bf 100644 --- a/spec/ruby/library/stringscanner/check_until_spec.rb +++ b/spec/ruby/library/stringscanner/check_until_spec.rb @@ -13,9 +13,11 @@ @s.check_until(/test/).should == "This is a test" end - it "raises TypeError if given a String" do - -> { - @s.check_until('T') - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.check_until('T') + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/stringscanner/exist_spec.rb b/spec/ruby/library/stringscanner/exist_spec.rb index ff860a0d3e35..a18f5ce35273 100644 --- a/spec/ruby/library/stringscanner/exist_spec.rb +++ b/spec/ruby/library/stringscanner/exist_spec.rb @@ -22,9 +22,11 @@ @s.exist?(/i/).should == nil end - it "raises TypeError if given a String" do - -> { - @s.exist?('T') - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.exist?('T') + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/stringscanner/scan_until_spec.rb b/spec/ruby/library/stringscanner/scan_until_spec.rb index a8162f1f0399..1e318d053b92 100644 --- a/spec/ruby/library/stringscanner/scan_until_spec.rb +++ b/spec/ruby/library/stringscanner/scan_until_spec.rb @@ -21,9 +21,11 @@ @s.scan_until(/^h/).should == "h" end - it "raises TypeError if given a String" do - -> { - @s.scan_until('T') - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.scan_until('T') + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/stringscanner/search_full_spec.rb b/spec/ruby/library/stringscanner/search_full_spec.rb index 7d2a714fa567..713ab00d22b2 100644 --- a/spec/ruby/library/stringscanner/search_full_spec.rb +++ b/spec/ruby/library/stringscanner/search_full_spec.rb @@ -28,9 +28,11 @@ @s.pos.should == 4 end - it "raises TypeError if given a String" do - -> { - @s.search_full('T', true, true) - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.search_full('T', true, true) + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/stringscanner/skip_until_spec.rb b/spec/ruby/library/stringscanner/skip_until_spec.rb index 7b56f13e4f6e..b6a020f9ba8f 100644 --- a/spec/ruby/library/stringscanner/skip_until_spec.rb +++ b/spec/ruby/library/stringscanner/skip_until_spec.rb @@ -16,9 +16,11 @@ @s.skip_until(/d+/).should == nil end - it "raises TypeError if given a String" do - -> { - @s.skip_until('T') - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.skip_until('T') + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/time/iso8601_spec.rb b/spec/ruby/library/time/iso8601_spec.rb index 4a9eb4561386..9e2607fbd0b8 100644 --- a/spec/ruby/library/time/iso8601_spec.rb +++ b/spec/ruby/library/time/iso8601_spec.rb @@ -3,5 +3,5 @@ require 'time' describe "Time.xmlschema" do - it_behaves_like :time_xmlschema, :iso8601 + it_behaves_like :time_library_xmlschema, :iso8601 end diff --git a/spec/ruby/library/time/shared/rfc2822.rb b/spec/ruby/library/time/shared/rfc2822.rb index d99f1f76decf..e460d655a68d 100644 --- a/spec/ruby/library/time/shared/rfc2822.rb +++ b/spec/ruby/library/time/shared/rfc2822.rb @@ -1,33 +1,33 @@ describe :time_rfc2822, shared: true do it "parses RFC-822 strings" do t1 = (Time.utc(1976, 8, 26, 14, 30) + 4 * 3600) - t2 = Time.rfc2822("26 Aug 76 14:30 EDT") + t2 = Time.send(@method, "26 Aug 76 14:30 EDT") t1.should == t2 t3 = Time.utc(1976, 8, 27, 9, 32) + 7 * 3600 - t4 = Time.rfc2822("27 Aug 76 09:32 PDT") + t4 = Time.send(@method, "27 Aug 76 09:32 PDT") t3.should == t4 end it "parses RFC-2822 strings" do t1 = Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600 - t2 = Time.rfc2822("Fri, 21 Nov 1997 09:55:06 -0600") + t2 = Time.send(@method, "Fri, 21 Nov 1997 09:55:06 -0600") t1.should == t2 t3 = Time.utc(2003, 7, 1, 10, 52, 37) - 2 * 3600 - t4 = Time.rfc2822("Tue, 1 Jul 2003 10:52:37 +0200") + t4 = Time.send(@method, "Tue, 1 Jul 2003 10:52:37 +0200") t3.should == t4 t5 = Time.utc(1997, 11, 21, 10, 1, 10) + 6 * 3600 - t6 = Time.rfc2822("Fri, 21 Nov 1997 10:01:10 -0600") + t6 = Time.send(@method, "Fri, 21 Nov 1997 10:01:10 -0600") t5.should == t6 t7 = Time.utc(1997, 11, 21, 11, 0, 0) + 6 * 3600 - t8 = Time.rfc2822("Fri, 21 Nov 1997 11:00:00 -0600") + t8 = Time.send(@method, "Fri, 21 Nov 1997 11:00:00 -0600") t7.should == t8 t9 = Time.utc(1997, 11, 24, 14, 22, 1) + 8 * 3600 - t10 = Time.rfc2822("Mon, 24 Nov 1997 14:22:01 -0800") + t10 = Time.send(@method, "Mon, 24 Nov 1997 14:22:01 -0800") t9.should == t10 begin @@ -36,11 +36,11 @@ # ignore else t11 = Time.utc(1969, 2, 13, 23, 32, 54) + 3 * 3600 + 30 * 60 - t12 = Time.rfc2822("Thu, 13 Feb 1969 23:32:54 -0330") + t12 = Time.send(@method, "Thu, 13 Feb 1969 23:32:54 -0330") t11.should == t12 t13 = Time.utc(1969, 2, 13, 23, 32, 0) + 3 * 3600 + 30 * 60 - t14 = Time.rfc2822(" Thu, + t14 = Time.send(@method, " Thu, 13 Feb 1969 @@ -50,16 +50,16 @@ end t15 = Time.utc(1997, 11, 21, 9, 55, 6) - t16 = Time.rfc2822("21 Nov 97 09:55:06 GMT") + t16 = Time.send(@method, "21 Nov 97 09:55:06 GMT") t15.should == t16 t17 = Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600 - t18 = Time.rfc2822("Fri, 21 Nov 1997 09 : 55 : 06 -0600") + t18 = Time.send(@method, "Fri, 21 Nov 1997 09 : 55 : 06 -0600") t17.should == t18 -> { # inner comment is not supported. - Time.rfc2822("Fri, 21 Nov 1997 09(comment): 55 : 06 -0600") + Time.send(@method, "Fri, 21 Nov 1997 09(comment): 55 : 06 -0600") }.should raise_error(ArgumentError) end end diff --git a/spec/ruby/library/time/shared/xmlschema.rb b/spec/ruby/library/time/shared/xmlschema.rb index 44d33cda7e38..0002886ca5b2 100644 --- a/spec/ruby/library/time/shared/xmlschema.rb +++ b/spec/ruby/library/time/shared/xmlschema.rb @@ -1,24 +1,24 @@ -describe :time_xmlschema, shared: true do +describe :time_library_xmlschema, shared: true do it "parses ISO-8601 strings" do t = Time.utc(1985, 4, 12, 23, 20, 50, 520000) s = "1985-04-12T23:20:50.52Z" - t.should == Time.xmlschema(s) - #s.should == t.xmlschema(2) + t.should == Time.send(@method, s) + #s.should == t.send(@method, 2) t = Time.utc(1996, 12, 20, 0, 39, 57) s = "1996-12-19T16:39:57-08:00" - t.should == Time.xmlschema(s) + t.should == Time.send(@method, s) # There is no way to generate time string with arbitrary timezone. s = "1996-12-20T00:39:57Z" - t.should == Time.xmlschema(s) - #assert_equal(s, t.xmlschema) + t.should == Time.send(@method, s) + #assert_equal(s, t.send(@method)) t = Time.utc(1990, 12, 31, 23, 59, 60) s = "1990-12-31T23:59:60Z" - t.should == Time.xmlschema(s) + t.should == Time.send(@method, s) # leap second is representable only if timezone file has it. s = "1990-12-31T15:59:60-08:00" - t.should == Time.xmlschema(s) + t.should == Time.send(@method, s) begin Time.at(-1) @@ -27,27 +27,27 @@ else t = Time.utc(1937, 1, 1, 11, 40, 27, 870000) s = "1937-01-01T12:00:27.87+00:20" - t.should == Time.xmlschema(s) + t.should == Time.send(@method, s) end # more - # (Time.utc(1999, 5, 31, 13, 20, 0) + 5 * 3600).should == Time.xmlschema("1999-05-31T13:20:00-05:00") - # (Time.local(2000, 1, 20, 12, 0, 0)).should == Time.xmlschema("2000-01-20T12:00:00") - # (Time.utc(2000, 1, 20, 12, 0, 0)).should == Time.xmlschema("2000-01-20T12:00:00Z") - # (Time.utc(2000, 1, 20, 12, 0, 0) - 12 * 3600).should == Time.xmlschema("2000-01-20T12:00:00+12:00") - # (Time.utc(2000, 1, 20, 12, 0, 0) + 13 * 3600).should == Time.xmlschema("2000-01-20T12:00:00-13:00") - # (Time.utc(2000, 3, 4, 23, 0, 0) - 3 * 3600).should == Time.xmlschema("2000-03-04T23:00:00+03:00") - # (Time.utc(2000, 3, 4, 20, 0, 0)).should == Time.xmlschema("2000-03-04T20:00:00Z") - # (Time.local(2000, 1, 15, 0, 0, 0)).should == Time.xmlschema("2000-01-15T00:00:00") - # (Time.local(2000, 2, 15, 0, 0, 0)).should == Time.xmlschema("2000-02-15T00:00:00") - # (Time.local(2000, 1, 15, 12, 0, 0)).should == Time.xmlschema("2000-01-15T12:00:00") - # (Time.utc(2000, 1, 16, 12, 0, 0)).should == Time.xmlschema("2000-01-16T12:00:00Z") - # (Time.local(2000, 1, 1, 12, 0, 0)).should == Time.xmlschema("2000-01-01T12:00:00") - # (Time.utc(1999, 12, 31, 23, 0, 0)).should == Time.xmlschema("1999-12-31T23:00:00Z") - # (Time.local(2000, 1, 16, 12, 0, 0)).should == Time.xmlschema("2000-01-16T12:00:00") - # (Time.local(2000, 1, 16, 0, 0, 0)).should == Time.xmlschema("2000-01-16T00:00:00") - # (Time.utc(2000, 1, 12, 12, 13, 14)).should == Time.xmlschema("2000-01-12T12:13:14Z") - # (Time.utc(2001, 4, 17, 19, 23, 17, 300000)).should == Time.xmlschema("2001-04-17T19:23:17.3Z") + # (Time.utc(1999, 5, 31, 13, 20, 0) + 5 * 3600).should == Time.send(@method, "1999-05-31T13:20:00-05:00") + # (Time.local(2000, 1, 20, 12, 0, 0)).should == Time.send(@method, "2000-01-20T12:00:00") + # (Time.utc(2000, 1, 20, 12, 0, 0)).should == Time.send(@method, "2000-01-20T12:00:00Z") + # (Time.utc(2000, 1, 20, 12, 0, 0) - 12 * 3600).should == Time.send(@method, "2000-01-20T12:00:00+12:00") + # (Time.utc(2000, 1, 20, 12, 0, 0) + 13 * 3600).should == Time.send(@method, "2000-01-20T12:00:00-13:00") + # (Time.utc(2000, 3, 4, 23, 0, 0) - 3 * 3600).should == Time.send(@method, "2000-03-04T23:00:00+03:00") + # (Time.utc(2000, 3, 4, 20, 0, 0)).should == Time.send(@method, "2000-03-04T20:00:00Z") + # (Time.local(2000, 1, 15, 0, 0, 0)).should == Time.send(@method, "2000-01-15T00:00:00") + # (Time.local(2000, 2, 15, 0, 0, 0)).should == Time.send(@method, "2000-02-15T00:00:00") + # (Time.local(2000, 1, 15, 12, 0, 0)).should == Time.send(@method, "2000-01-15T12:00:00") + # (Time.utc(2000, 1, 16, 12, 0, 0)).should == Time.send(@method, "2000-01-16T12:00:00Z") + # (Time.local(2000, 1, 1, 12, 0, 0)).should == Time.send(@method, "2000-01-01T12:00:00") + # (Time.utc(1999, 12, 31, 23, 0, 0)).should == Time.send(@method, "1999-12-31T23:00:00Z") + # (Time.local(2000, 1, 16, 12, 0, 0)).should == Time.send(@method, "2000-01-16T12:00:00") + # (Time.local(2000, 1, 16, 0, 0, 0)).should == Time.send(@method, "2000-01-16T00:00:00") + # (Time.utc(2000, 1, 12, 12, 13, 14)).should == Time.send(@method, "2000-01-12T12:13:14Z") + # (Time.utc(2001, 4, 17, 19, 23, 17, 300000)).should == Time.send(@method, "2001-04-17T19:23:17.3Z") end end diff --git a/spec/ruby/library/time/xmlschema_spec.rb b/spec/ruby/library/time/xmlschema_spec.rb index 427931119971..ff3c864a02e8 100644 --- a/spec/ruby/library/time/xmlschema_spec.rb +++ b/spec/ruby/library/time/xmlschema_spec.rb @@ -3,5 +3,5 @@ require 'time' describe "Time.xmlschema" do - it_behaves_like :time_xmlschema, :xmlschema + it_behaves_like :time_library_xmlschema, :xmlschema end diff --git a/spec/ruby/library/uri/shared/parse.rb b/spec/ruby/library/uri/shared/parse.rb index 87e1ee933ea5..c5057b6c4bbb 100644 --- a/spec/ruby/library/uri/shared/parse.rb +++ b/spec/ruby/library/uri/shared/parse.rb @@ -192,8 +192,15 @@ file.should be_kind_of(URI::Generic) end - it "raises errors on malformed URIs" do - -> { @object.parse('http://a_b:80/') }.should raise_error(URI::InvalidURIError) - -> { @object.parse('http://a_b/') }.should raise_error(URI::InvalidURIError) + if URI::DEFAULT_PARSER == URI::RFC2396_Parser + it "raises errors on malformed URIs" do + -> { @object.parse('http://a_b:80/') }.should raise_error(URI::InvalidURIError) + -> { @object.parse('http://a_b/') }.should raise_error(URI::InvalidURIError) + end + elsif URI::DEFAULT_PARSER == URI::RFC3986_Parser + it "does not raise errors on URIs contained underscore" do + -> { @object.parse('http://a_b:80/') }.should_not raise_error(URI::InvalidURIError) + -> { @object.parse('http://a_b/') }.should_not raise_error(URI::InvalidURIError) + end end end diff --git a/spec/ruby/optional/capi/bignum_spec.rb b/spec/ruby/optional/capi/bignum_spec.rb index cde929af28d5..179f053eec4b 100644 --- a/spec/ruby/optional/capi/bignum_spec.rb +++ b/spec/ruby/optional/capi/bignum_spec.rb @@ -7,21 +7,23 @@ def ensure_bignum(n) n end -full_range_longs = (fixnum_max == 2**(0.size * 8 - 1) - 1) +full_range_longs = (fixnum_max == max_long) +max_ulong = begin + require 'rbconfig/sizeof' + RbConfig::LIMITS['ULONG_MAX'] +rescue LoadError + nil +end +# If the system doesn't offer ULONG_MAX, assume 2's complement and derive it +# from LONG_MAX. +max_ulong ||= 2 * (max_long + 1) - 1 describe "CApiBignumSpecs" do before :each do @s = CApiBignumSpecs.new - - if full_range_longs - @max_long = 2**(0.size * 8 - 1) - 1 - @min_long = -@max_long - 1 - @max_ulong = ensure_bignum(2**(0.size * 8) - 1) - else - @max_long = ensure_bignum(2**(0.size * 8 - 1) - 1) - @min_long = ensure_bignum(-@max_long - 1) - @max_ulong = ensure_bignum(2**(0.size * 8) - 1) - end + @max_long = max_long + @min_long = min_long + @max_ulong = ensure_bignum(max_ulong) end describe "rb_big2long" do @@ -123,7 +125,7 @@ def ensure_bignum(n) val.should == @max_ulong end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "packs max_ulong into 2 ulongs to allow sign bit" do val = @s.rb_big_pack_length(@max_ulong) val.should == 2 diff --git a/spec/ruby/optional/capi/debug_spec.rb b/spec/ruby/optional/capi/debug_spec.rb index 148b8c38fbbe..14ba25609c55 100644 --- a/spec/ruby/optional/capi/debug_spec.rb +++ b/spec/ruby/optional/capi/debug_spec.rb @@ -37,9 +37,12 @@ it "matches the locations in rb_debug_inspector_backtrace_locations" do frames = @o.rb_debug_inspector_open(42) - frames.each do |_s, _klass, binding, _iseq, backtrace_location| + frames.each do |_s, klass, binding, iseq, backtrace_location| if binding - binding.source_location.should == [backtrace_location.path, backtrace_location.lineno] + # YJIT modifies Array#each backtraces but leaves its source_location as is + unless defined?(RubyVM::YJIT) && klass == Array && iseq.label == "each" + binding.source_location.should == [backtrace_location.path, backtrace_location.lineno] + end method_name = binding.eval('__method__') if method_name method_name.should == backtrace_location.base_label.to_sym diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c index 1b4d4fccce49..e0b1df0de7a2 100644 --- a/spec/ruby/optional/capi/ext/io_spec.c +++ b/spec/ruby/optional/capi/ext/io_spec.c @@ -143,7 +143,11 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) { errno = saved_errno; } +#ifdef RUBY_VERSION_IS_3_1 + ret = rb_io_maybe_wait_readable(errno, io, Qnil); +#else ret = rb_io_wait_readable(fd); +#endif if (RTEST(read_p)) { ssize_t r = read(fd, buf, RB_IO_WAIT_READABLE_BUF); @@ -162,7 +166,11 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) { } VALUE io_spec_rb_io_wait_writable(VALUE self, VALUE io) { +#ifdef RUBY_VERSION_IS_3_1 + int ret = rb_io_maybe_wait_writable(errno, io, Qnil); +#else int ret = rb_io_wait_writable(io_spec_get_fd(io)); +#endif return ret ? Qtrue : Qfalse; } @@ -230,13 +238,23 @@ VALUE io_spec_rb_thread_wait_fd(VALUE self, VALUE io) { } VALUE io_spec_rb_wait_for_single_fd(VALUE self, VALUE io, VALUE events, VALUE secs, VALUE usecs) { - int fd = io_spec_get_fd(io); +#ifdef RUBY_VERSION_IS_3_0 + VALUE timeout = Qnil; + if (!NIL_P(secs)) { + timeout = rb_float_new((double)FIX2INT(secs) + (0.000001f * FIX2INT(usecs))); + } + VALUE result = rb_io_wait(io, events, timeout); + if (result == Qfalse) return INT2FIX(0); + else return result; +#else struct timeval tv; if (!NIL_P(secs)) { tv.tv_sec = FIX2INT(secs); tv.tv_usec = FIX2INT(usecs); } + int fd = io_spec_get_fd(io); return INT2FIX(rb_wait_for_single_fd(fd, FIX2INT(events), NIL_P(secs) ? NULL : &tv)); +#endif } VALUE io_spec_rb_thread_fd_writable(VALUE self, VALUE io) { diff --git a/spec/ruby/optional/capi/fixnum_spec.rb b/spec/ruby/optional/capi/fixnum_spec.rb index aa02a0543b7a..e691aa389365 100644 --- a/spec/ruby/optional/capi/fixnum_spec.rb +++ b/spec/ruby/optional/capi/fixnum_spec.rb @@ -25,7 +25,7 @@ end end - platform_is wordsize: 64 do # sizeof(long) > sizeof(int) + platform_is c_long_size: 64 do # sizeof(long) > sizeof(int) it "raises a TypeError if passed nil" do -> { @s.FIX2INT(nil) }.should raise_error(TypeError) end @@ -74,7 +74,7 @@ end end - platform_is wordsize: 64 do # sizeof(long) > sizeof(int) + platform_is c_long_size: 64 do # sizeof(long) > sizeof(int) it "raises a TypeError if passed nil" do -> { @s.FIX2UINT(nil) }.should raise_error(TypeError) end diff --git a/spec/ruby/optional/capi/io_spec.rb b/spec/ruby/optional/capi/io_spec.rb index bdec46f5e187..01588408e10c 100644 --- a/spec/ruby/optional/capi/io_spec.rb +++ b/spec/ruby/optional/capi/io_spec.rb @@ -458,10 +458,6 @@ @o.rb_io_maybe_wait(Errno::EINTR::Errno, @w_io, IO::WRITABLE, nil).should == IO::WRITABLE end - it "returns false if there is no error condition" do - @o.rb_io_maybe_wait(0, @w_io, IO::WRITABLE, nil).should == false - end - it "raises an IOError if the IO is closed" do @w_io.close -> { @o.rb_io_maybe_wait(0, @w_io, IO::WRITABLE, nil) }.should raise_error(IOError, "closed stream") @@ -521,6 +517,14 @@ end end end + + ruby_version_is "3.4" do + describe "rb_io_maybe_wait" do + it "returns nil if there is no error condition" do + @o.rb_io_maybe_wait(0, @w_io, IO::WRITABLE, nil).should == nil + end + end + end end describe "rb_fd_fix_cloexec" do diff --git a/spec/ruby/optional/capi/numeric_spec.rb b/spec/ruby/optional/capi/numeric_spec.rb index 95213d3f2b99..e9667da5ba1b 100644 --- a/spec/ruby/optional/capi/numeric_spec.rb +++ b/spec/ruby/optional/capi/numeric_spec.rb @@ -106,7 +106,7 @@ @s.NUM2LONG(5).should == 5 end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do it "converts -1 to an signed number" do @s.NUM2LONG(-1).should == -1 end @@ -120,7 +120,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "converts -1 to an signed number" do @s.NUM2LONG(-1).should == -1 end @@ -210,7 +210,7 @@ @s.NUM2ULONG(5).should == 5 end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do it "converts -1 to an unsigned number" do @s.NUM2ULONG(-1).should == 4294967295 end @@ -231,7 +231,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "converts -1 to an unsigned number" do @s.NUM2ULONG(-1).should == 18446744073709551615 end diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb index d43dddeacf12..8f2244bceab8 100644 --- a/spec/ruby/optional/capi/string_spec.rb +++ b/spec/ruby/optional/capi/string_spec.rb @@ -902,16 +902,20 @@ def inspect end it "returns the original String if a transcoding error occurs" do - a = [0xEE].pack('C').force_encoding("utf-8") - @s.rb_str_conv_enc(a, Encoding::UTF_8, Encoding::EUC_JP).should equal(a) + a = [0xEE].pack('C').force_encoding(Encoding::UTF_8) + @s.rb_str_conv_enc(a, Encoding::UTF_8, Encoding::EUC_JP).should.equal?(a) + a.encoding.should == Encoding::UTF_8 + + a = "\x80".b + @s.rb_str_conv_enc(a, Encoding::BINARY, Encoding::UTF_8).should.equal?(a) + a.encoding.should == Encoding::BINARY end it "returns a transcoded String" do - a = "\xE3\x81\x82\xE3\x82\x8C".dup.force_encoding("utf-8") + a = "\xE3\x81\x82\xE3\x82\x8C".dup.force_encoding(Encoding::UTF_8) result = @s.rb_str_conv_enc(a, Encoding::UTF_8, Encoding::EUC_JP) - x = [0xA4, 0xA2, 0xA4, 0xEC].pack('C4').force_encoding('utf-8') - result.should == x.force_encoding("euc-jp") - result.encoding.should equal(Encoding::EUC_JP) + result.should == [0xA4, 0xA2, 0xA4, 0xEC].pack('C4').force_encoding(Encoding::EUC_JP) + result.encoding.should == Encoding::EUC_JP end describe "when the String encoding is equal to the destination encoding" do @@ -1110,7 +1114,7 @@ def inspect end it "tries to convert the passed argument to a string by calling #to_s" do - @s.rb_String({"bar" => "foo"}).should == '{"bar"=>"foo"}' + @s.rb_String({"bar" => "foo"}).should == {"bar" => "foo"}.to_s end end diff --git a/spec/ruby/optional/capi/util_spec.rb b/spec/ruby/optional/capi/util_spec.rb index 9ff8b4760a83..6cf064bf973b 100644 --- a/spec/ruby/optional/capi/util_spec.rb +++ b/spec/ruby/optional/capi/util_spec.rb @@ -209,7 +209,7 @@ end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "rb_long2int" do it "raises a RangeError if the value is outside the range of a C int" do -> { @o.rb_long2int(0xffff_ffff_ffff) }.should raise_error(RangeError) diff --git a/spec/ruby/security/cve_2020_10663_spec.rb b/spec/ruby/security/cve_2020_10663_spec.rb index cce1beb0128c..03f004efeb56 100644 --- a/spec/ruby/security/cve_2020_10663_spec.rb +++ b/spec/ruby/security/cve_2020_10663_spec.rb @@ -29,7 +29,14 @@ def to_json(*args) JSON.parse(json, create_additions: true).class.should == JSONSpecs::MyClass JSON(json, create_additions: true).class.should == JSONSpecs::MyClass - JSON.load(json).class.should == JSONSpecs::MyClass + if version_is(JSON::VERSION, '2.8.0') + warning = /\Wcreate_additions:\s*true\W\s+is\s+deprecated/ + else + warning = '' + end + -> { + JSON.load(json).class.should == JSONSpecs::MyClass + }.should output_to_fd(warning, STDERR) JSON.parse(json).class.should == Hash JSON.parse(json, nil).class.should == Hash diff --git a/spec/ruby/shared/queue/freeze.rb b/spec/ruby/shared/queue/freeze.rb new file mode 100644 index 000000000000..4c506a42355f --- /dev/null +++ b/spec/ruby/shared/queue/freeze.rb @@ -0,0 +1,18 @@ +describe :queue_freeze, shared: true do + ruby_version_is ""..."3.3" do + it "can be frozen" do + queue = @object.call + queue.freeze + queue.should.frozen? + end + end + + ruby_version_is "3.3" do + it "raises an exception when freezing" do + queue = @object.call + -> { + queue.freeze + }.should raise_error(TypeError, "cannot freeze #{queue}") + end + end +end diff --git a/spec/ruby/shared/string/times.rb b/spec/ruby/shared/string/times.rb index aaf748bad9ff..4814f894cf02 100644 --- a/spec/ruby/shared/string/times.rb +++ b/spec/ruby/shared/string/times.rb @@ -44,13 +44,13 @@ class MyString < String; end result.encoding.should equal(Encoding::UTF_8) end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do it "raises an ArgumentError if the length of the resulting string doesn't fit into a long" do -> { @object.call("abc", (2 ** 31) - 1) }.should raise_error(ArgumentError) end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "raises an ArgumentError if the length of the resulting string doesn't fit into a long" do -> { @object.call("abc", (2 ** 63) - 1) }.should raise_error(ArgumentError) end From d4e89aa4af646a591ef857b426f2776ab3487e40 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Wed, 6 Nov 2024 22:09:08 +0100 Subject: [PATCH 3/4] Add tags for new failing specs and slow tags --- spec/tags/core/float/floor_tags.txt | 1 + spec/tags/core/integer/ceil_tags.txt | 1 + spec/tags/core/integer/floor_tags.txt | 1 + spec/tags/core/kernel/format_tags.txt | 4 ++++ spec/tags/core/objectspace/define_finalizer_tags.txt | 3 +++ spec/tags/core/objectspace/undefine_finalizer_tags.txt | 4 ++++ spec/tags/core/string/modulo_tags.txt | 5 +++++ spec/tags/core/time/new_tags.txt | 1 + 8 files changed, 20 insertions(+) create mode 100644 spec/tags/core/float/floor_tags.txt create mode 100644 spec/tags/core/integer/ceil_tags.txt create mode 100644 spec/tags/core/integer/floor_tags.txt create mode 100644 spec/tags/core/kernel/format_tags.txt create mode 100644 spec/tags/core/objectspace/undefine_finalizer_tags.txt diff --git a/spec/tags/core/float/floor_tags.txt b/spec/tags/core/float/floor_tags.txt new file mode 100644 index 000000000000..78ab60812d18 --- /dev/null +++ b/spec/tags/core/float/floor_tags.txt @@ -0,0 +1 @@ +fails:Float#floor with precision precision is negative returns -(10**precision.abs) when self is negative and precision.abs is larger than the number digits of self diff --git a/spec/tags/core/integer/ceil_tags.txt b/spec/tags/core/integer/ceil_tags.txt new file mode 100644 index 000000000000..8bf644844a28 --- /dev/null +++ b/spec/tags/core/integer/ceil_tags.txt @@ -0,0 +1 @@ +fails:Integer#ceil with precision precision is negative always returns 0 when self is 0 diff --git a/spec/tags/core/integer/floor_tags.txt b/spec/tags/core/integer/floor_tags.txt new file mode 100644 index 000000000000..01ea50f6d7e6 --- /dev/null +++ b/spec/tags/core/integer/floor_tags.txt @@ -0,0 +1 @@ +fails:Integer#floor with precision precision is negative returns -(10**precision.abs) when self is negative and precision.abs is larger than the number digits of self diff --git a/spec/tags/core/kernel/format_tags.txt b/spec/tags/core/kernel/format_tags.txt new file mode 100644 index 000000000000..df82df8689df --- /dev/null +++ b/spec/tags/core/kernel/format_tags.txt @@ -0,0 +1,4 @@ +slow:Kernel.format when $VERBOSE is true warns if too many arguments are passed +slow:Kernel.format when $VERBOSE is true does not warns if too many keyword arguments are passed +slow:Kernel.format when $VERBOSE is true doesn't warns if keyword arguments are passed and none are used +fails:Kernel.format when $VERBOSE is true warns if too many arguments are passed diff --git a/spec/tags/core/objectspace/define_finalizer_tags.txt b/spec/tags/core/objectspace/define_finalizer_tags.txt index b4cdc5c1fba5..2d3dae7dfa9d 100644 --- a/spec/tags/core/objectspace/define_finalizer_tags.txt +++ b/spec/tags/core/objectspace/define_finalizer_tags.txt @@ -18,3 +18,6 @@ slow:ObjectSpace.define_finalizer when $VERBOSE is not nil warns if an exception slow:ObjectSpace.define_finalizer when $VERBOSE is nil does not warn even if an exception is raised in finalizer fails:ObjectSpace.define_finalizer when $VERBOSE is not nil warns if an exception is raised in finalizer fails:ObjectSpace.define_finalizer when $VERBOSE is nil does not warn even if an exception is raised in finalizer +slow:ObjectSpace.define_finalizer defines same finalizer only once +fails:ObjectSpace.define_finalizer defines same finalizer only once +fails:ObjectSpace.define_finalizer returns the defined finalizer diff --git a/spec/tags/core/objectspace/undefine_finalizer_tags.txt b/spec/tags/core/objectspace/undefine_finalizer_tags.txt new file mode 100644 index 000000000000..036b8d5bb9d6 --- /dev/null +++ b/spec/tags/core/objectspace/undefine_finalizer_tags.txt @@ -0,0 +1,4 @@ +slow:ObjectSpace.undefine_finalizer removes finalizers for an object +slow:ObjectSpace.undefine_finalizer should not remove finalizers for a frozen object +fails:ObjectSpace.undefine_finalizer should not remove finalizers for a frozen object +fails:ObjectSpace.undefine_finalizer should raise when removing finalizers for a frozen object diff --git a/spec/tags/core/string/modulo_tags.txt b/spec/tags/core/string/modulo_tags.txt index 5d03579ee583..d980d7313508 100644 --- a/spec/tags/core/string/modulo_tags.txt +++ b/spec/tags/core/string/modulo_tags.txt @@ -8,3 +8,8 @@ fails:String#% flags # applies to formats bBxX does nothing for zero argument fails:String#% other formats c displays only the first character if argument is a string of several characters fails:String#% other formats c displays no characters if argument is an empty string fails:String#% supports only the first character as argument for %c +fails:String#% behaves as if calling Kernel#Float for %e arguments, when the passed argument does not respond to #to_ary +fails:String#% behaves as if calling Kernel#Float for %E arguments, when the passed argument does not respond to #to_ary +fails:String#% behaves as if calling Kernel#Float for %f arguments, when the passed argument does not respond to #to_ary +fails:String#% behaves as if calling Kernel#Float for %g arguments, when the passed argument does not respond to #to_ary +fails:String#% behaves as if calling Kernel#Float for %G arguments, when the passed argument does not respond to #to_ary diff --git a/spec/tags/core/time/new_tags.txt b/spec/tags/core/time/new_tags.txt index 04c1c547bdb5..c8e3291dfc72 100644 --- a/spec/tags/core/time/new_tags.txt +++ b/spec/tags/core/time/new_tags.txt @@ -23,3 +23,4 @@ fails:Time.new with a timezone argument :in keyword argument could be a timezone fails:Time.new with a timezone argument Time.new with a String argument accepts precision keyword argument and truncates specified digits of sub-second part fails:Time.new with a timezone argument Time.new with a String argument converts precision keyword argument into Integer if is not nil fails:Time.new with a timezone argument Time.new with a String argument raise TypeError is can't convert precision keyword argument into Integer +fails:Time.new with a timezone argument Time.new with a String argument raises ArgumentError if date/time parts values are not valid From 87f41df18c43f7ba4a5cca61c399111a28ac624c Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Thu, 7 Nov 2024 13:41:25 +0100 Subject: [PATCH 4/4] Quarantine unreliable spec * See discussion on https://github.com/ruby/spec/pull/1210 --- spec/ruby/core/kernel/sleep_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/ruby/core/kernel/sleep_spec.rb b/spec/ruby/core/kernel/sleep_spec.rb index 1de52a707fcb..607764464fe3 100644 --- a/spec/ruby/core/kernel/sleep_spec.rb +++ b/spec/ruby/core/kernel/sleep_spec.rb @@ -51,7 +51,7 @@ def o.divmod(*); [0, 0.001]; end t.value.should == 5 end - platform_is_not :darwin do + quarantine! do # fails transiently on at least linux & darwin it "sleeps with nanosecond precision" do start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) 100.times do