diff options
author | Benoit Daloze <eregontp@gmail.com> | 2019-12-27 16:46:08 +0100 |
---|---|---|
committer | Benoit Daloze <eregontp@gmail.com> | 2019-12-27 16:46:08 +0100 |
commit | a2fac1d72c225192018f8f3f3dfcfcc46f66c08a (patch) | |
tree | dc2d44079962ce242d971a4d1c2a2b1333e64cec | |
parent | 26a9f80c823a9f536a235d80d600aa9e03ed7a2f (diff) |
Update to ruby/spec@d419e74
44 files changed, 788 insertions, 530 deletions
diff --git a/spec/ruby/.rubocop.yml b/spec/ruby/.rubocop.yml index 77e4e78e77..5dc6b96473 100644 --- a/spec/ruby/.rubocop.yml +++ b/spec/ruby/.rubocop.yml @@ -10,7 +10,7 @@ AllCops: Layout/TrailingWhitespace: Enabled: true -Layout/TrailingBlankLines: +Layout/TrailingEmptyLines: Enabled: true Exclude: - library/coverage/fixtures/some_class.rb @@ -34,10 +34,10 @@ Lint/InterpolationCheck: Lint/LiteralAsCondition: Enabled: false -Lint/UnneededRequireStatement: +Lint/RedundantRequireStatement: Enabled: false -Lint/UnneededSplatExpansion: +Lint/RedundantSplatExpansion: Enabled: false Lint/UnifiedInteger: diff --git a/spec/ruby/.rubocop_todo.yml b/spec/ruby/.rubocop_todo.yml index aac54f62ae..36e41aec87 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 2018-04-03 22:23:59 +0900 using RuboCop version 0.54.0. +# on 2019-12-12 22:16:26 +0900 using RuboCop version 0.77.0. # 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 @@ -20,7 +20,7 @@ Lint/DuplicateMethods: - 'core/unboundmethod/fixtures/classes.rb' - 'fixtures/class.rb' -# Offense count: 5 +# Offense count: 8 Lint/EnsureReturn: Exclude: - 'language/fixtures/ensure.rb' @@ -28,14 +28,16 @@ Lint/EnsureReturn: - 'language/return_spec.rb' # Offense count: 10 +Lint/FlipFlop: + Exclude: + - 'language/if_spec.rb' + - 'language/precedence_spec.rb' + +# Offense count: 10 Lint/FloatOutOfRange: Exclude: - 'core/string/modulo_spec.rb' -# Offense count: 29 -Lint/HandleExceptions: - Enabled: false - # Offense count: 2 Lint/ImplicitStringConcatenation: Exclude: @@ -58,13 +60,19 @@ Lint/InheritException: - 'core/exception/fixtures/common.rb' - 'core/module/fixtures/autoload_ex1.rb' -# Offense count: 5 +# Offense count: 72 # Cop supports --auto-correct. Lint/LiteralInInterpolation: Exclude: - 'core/module/refine_spec.rb' + - 'core/regexp/shared/new.rb' + - 'core/string/shared/to_sym.rb' + - 'language/alias_spec.rb' - 'language/defined_spec.rb' - 'language/fixtures/squiggly_heredoc.rb' + - 'language/symbol_spec.rb' + - 'language/undef_spec.rb' + - 'library/net/ftp/connect_spec.rb' # Offense count: 16 Lint/Loop: @@ -74,11 +82,11 @@ Lint/Loop: # Offense count: 8 # Cop supports --auto-correct. -Lint/MultipleCompare: +Lint/MultipleComparison: Exclude: - 'language/precedence_spec.rb' -# Offense count: 12 +# Offense count: 9 Lint/ParenthesesAsGroupedExpression: Exclude: - 'core/string/fixtures/freeze_magic_comment.rb' @@ -86,13 +94,19 @@ Lint/ParenthesesAsGroupedExpression: - 'language/fixtures/send.rb' - 'language/method_spec.rb' +# Offense count: 2 +# Cop supports --auto-correct. +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: 26 +# Offense count: 22 Lint/RescueException: Exclude: - 'command_line/fixtures/debug_info.rb' @@ -102,27 +116,24 @@ Lint/RescueException: - 'core/kernel/fixtures/autoload_frozen.rb' - 'core/module/autoload_spec.rb' - 'core/mutex/sleep_spec.rb' - - 'core/process/euid_spec.rb' - - 'core/process/setsid_spec.rb' - - 'core/process/uid_spec.rb' - 'core/thread/abort_on_exception_spec.rb' - 'core/thread/shared/exit.rb' - 'language/rescue_spec.rb' - 'library/erb/filename_spec.rb' -# Offense count: 2 +# Offense count: 4 # Configuration parameters: IgnoreImplicitReferences. Lint/ShadowedArgument: Exclude: - 'language/fixtures/super.rb' -# Offense count: 2 -# Cop supports --auto-correct. -Lint/StringConversionInInterpolation: - Exclude: - - 'core/io/print_spec.rb' +# Offense count: 39 +# Configuration parameters: AllowComments. +Lint/SuppressedException: + Enabled: false # Offense count: 9 +# Configuration parameters: AllowKeywordBlockArguments. Lint/UnderscorePrefixedVariableName: Exclude: - 'core/io/pipe_spec.rb' @@ -137,13 +148,4 @@ Lint/UselessAccessModifier: - 'core/module/fixtures/classes.rb' - 'core/module/module_function_spec.rb' - 'core/module/private_class_method_spec.rb' - - 'core/module/private_spec.rb' - - 'core/module/protected_spec.rb' - - 'core/module/public_spec.rb' - 'language/fixtures/send.rb' - -# Offense count: 6186 -# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. -# URISchemes: http, https -Metrics/LineLength: - Max: 588 diff --git a/spec/ruby/core/builtin_constants/builtin_constants_spec.rb b/spec/ruby/core/builtin_constants/builtin_constants_spec.rb index a5141c3008..21102bee9f 100644 --- a/spec/ruby/core/builtin_constants/builtin_constants_spec.rb +++ b/spec/ruby/core/builtin_constants/builtin_constants_spec.rb @@ -34,6 +34,12 @@ describe "RUBY_PLATFORM" do it "is a String" do RUBY_PLATFORM.should be_kind_of(String) end + + platform_is :darwin do + it 'ends with the build time kernel major version on darwin' do + RUBY_PLATFORM.should =~ /-darwin\d+$/ + end + end end describe "RUBY_RELEASE_DATE" do diff --git a/spec/ruby/core/exception/errno_spec.rb b/spec/ruby/core/exception/errno_spec.rb index 9e0bf0086a..e76b29349e 100644 --- a/spec/ruby/core/exception/errno_spec.rb +++ b/spec/ruby/core/exception/errno_spec.rb @@ -1,10 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/common' -describe "SystemCallError#errno" do - it "needs to be reviewed for spec completeness" -end - describe "Errno::EINVAL.new" do it "can be called with no arguments" do exc = Errno::EINVAL.new diff --git a/spec/ruby/core/exception/exit_value_spec.rb b/spec/ruby/core/exception/exit_value_spec.rb index 43de56af8b..8bb3cf898d 100644 --- a/spec/ruby/core/exception/exit_value_spec.rb +++ b/spec/ruby/core/exception/exit_value_spec.rb @@ -1,5 +1,10 @@ require_relative '../../spec_helper' describe "LocalJumpError#exit_value" do - it "needs to be reviewed for spec completeness" + def get_me_a_return + Proc.new { return 42 } + end + -> { get_me_a_return.call }.should raise_error(LocalJumpError) { |e| + e.exit_value.should == 42 + } end diff --git a/spec/ruby/core/exception/frozen_error_spec.rb b/spec/ruby/core/exception/frozen_error_spec.rb index 1b5ea71148..f27b33295c 100644 --- a/spec/ruby/core/exception/frozen_error_spec.rb +++ b/spec/ruby/core/exception/frozen_error_spec.rb @@ -1,13 +1,5 @@ require_relative '../../spec_helper' -describe "FrozenError" do - ruby_version_is "2.5" do - it "is a subclass of RuntimeError" do - RuntimeError.should be_ancestor_of(FrozenError) - end - end -end - describe "FrozenError.new" do ruby_version_is "2.7" do it "should take optional receiver argument" do diff --git a/spec/ruby/core/exception/incomplete_input_spec.rb b/spec/ruby/core/exception/incomplete_input_spec.rb index b033b33f56..930a3f01d5 100644 --- a/spec/ruby/core/exception/incomplete_input_spec.rb +++ b/spec/ruby/core/exception/incomplete_input_spec.rb @@ -1,5 +1,7 @@ require_relative '../../spec_helper' describe "Encoding::InvalidByteSequenceError#incomplete_input?" do - it "needs to be reviewed for spec completeness" + -> {"abc\xa4def".encode("ISO-8859-1", "EUC-JP") }.should raise_error(Encoding::InvalidByteSequenceError) { |e| + e.incomplete_input?.should == false + } end diff --git a/spec/ruby/core/exception/io_error_spec.rb b/spec/ruby/core/exception/io_error_spec.rb index 8dc10cc6ce..ab8a72518f 100644 --- a/spec/ruby/core/exception/io_error_spec.rb +++ b/spec/ruby/core/exception/io_error_spec.rb @@ -1,11 +1,5 @@ require_relative '../../spec_helper' -describe "IOError" do - it "is a superclass of EOFError" do - IOError.should be_ancestor_of(EOFError) - end -end - describe "IO::EAGAINWaitReadable" do it "combines Errno::EAGAIN and IO::WaitReadable" do IO::EAGAINWaitReadable.superclass.should == Errno::EAGAIN diff --git a/spec/ruby/core/exception/name_error_spec.rb b/spec/ruby/core/exception/name_error_spec.rb index d0a810029b..e901a80c42 100644 --- a/spec/ruby/core/exception/name_error_spec.rb +++ b/spec/ruby/core/exception/name_error_spec.rb @@ -1,11 +1,5 @@ require_relative '../../spec_helper' -describe "NameError" do - it "is a superclass of NoMethodError" do - NameError.should be_ancestor_of(NoMethodError) - end -end - describe "NameError.new" do it "should take optional name argument" do NameError.new("msg","name").name.should == "name" @@ -22,3 +16,15 @@ describe "NameError.new" do end end end + +describe "NameError#dup" do + it "copies the name and receiver" do + begin + foo + rescue NameError => ne + name_error_dup = ne.dup + name_error_dup.name.should == :foo + name_error_dup.receiver.should == self + end + end +end diff --git a/spec/ruby/core/exception/no_method_error_spec.rb b/spec/ruby/core/exception/no_method_error_spec.rb index 28c3549562..93224c0740 100644 --- a/spec/ruby/core/exception/no_method_error_spec.rb +++ b/spec/ruby/core/exception/no_method_error_spec.rb @@ -104,3 +104,17 @@ describe "NoMethodError#message" do end end end + +describe "NoMethodError#dup" do + it "copies the name, arguments and receiver" do + begin + receiver = Object.new + receiver.foo(:one, :two) + rescue NoMethodError => nme + no_method_error_dup = nme.dup + no_method_error_dup.name.should == :foo + no_method_error_dup.receiver.should == receiver + no_method_error_dup.args.should == [:one, :two] + end + end +end diff --git a/spec/ruby/core/exception/range_error_spec.rb b/spec/ruby/core/exception/range_error_spec.rb deleted file mode 100644 index 7cfbd0f1ec..0000000000 --- a/spec/ruby/core/exception/range_error_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require_relative '../../spec_helper' - -describe "RangeError" do - it "is a superclass of FloatDomainError" do - RangeError.should be_ancestor_of(FloatDomainError) - end -end diff --git a/spec/ruby/core/exception/reason_spec.rb b/spec/ruby/core/exception/reason_spec.rb index 6f18aaae13..b28cbde8d9 100644 --- a/spec/ruby/core/exception/reason_spec.rb +++ b/spec/ruby/core/exception/reason_spec.rb @@ -1,5 +1,10 @@ require_relative '../../spec_helper' describe "LocalJumpError#reason" do - it "needs to be reviewed for spec completeness" + def get_me_a_return + Proc.new { return 42 } + end + -> { get_me_a_return.call }.should raise_error(LocalJumpError) { |e| + e.reason.should == :return + } end diff --git a/spec/ruby/core/exception/result_spec.rb b/spec/ruby/core/exception/result_spec.rb index 5ba26ebab1..2f12673295 100644 --- a/spec/ruby/core/exception/result_spec.rb +++ b/spec/ruby/core/exception/result_spec.rb @@ -1,11 +1,5 @@ require_relative '../../spec_helper' -describe "StopIteration" do - it "is a subclass of IndexError" do - StopIteration.superclass.should equal(IndexError) - end -end - describe "StopIteration#result" do before :each do obj = Object.new diff --git a/spec/ruby/core/exception/signm_spec.rb b/spec/ruby/core/exception/signm_spec.rb index 8e3adcddae..4adff3b5ee 100644 --- a/spec/ruby/core/exception/signm_spec.rb +++ b/spec/ruby/core/exception/signm_spec.rb @@ -1,5 +1,9 @@ require_relative '../../spec_helper' describe "SignalException#signm" do - it "needs to be reviewed for spec completeness" + it "returns the signal name" do + -> { Process.kill(:TERM, Process.pid) }.should raise_error(SignalException) { |e| + e.signm.should == 'SIGTERM' + } + end end diff --git a/spec/ruby/core/exception/signo_spec.rb b/spec/ruby/core/exception/signo_spec.rb index 2d04cd7805..62fc321516 100644 --- a/spec/ruby/core/exception/signo_spec.rb +++ b/spec/ruby/core/exception/signo_spec.rb @@ -1,5 +1,9 @@ require_relative '../../spec_helper' describe "SignalException#signo" do - it "needs to be reviewed for spec completeness" + it "returns the signal number" do + -> { Process.kill(:TERM, Process.pid) }.should raise_error(SignalException) { |e| + e.signo.should == Signal.list['TERM'] + } + end end diff --git a/spec/ruby/core/exception/status_spec.rb b/spec/ruby/core/exception/status_spec.rb index 1609bff3a5..8ace00fe10 100644 --- a/spec/ruby/core/exception/status_spec.rb +++ b/spec/ruby/core/exception/status_spec.rb @@ -1,5 +1,9 @@ require_relative '../../spec_helper' describe "SystemExit#status" do - it "needs to be reviewed for spec completeness" + it "returns the exit status" do + -> { exit 42 }.should raise_error(SystemExit) { |e| + e.status.should == 42 + } + end end diff --git a/spec/ruby/core/exception/success_spec.rb b/spec/ruby/core/exception/success_spec.rb index 82e3df92c6..70af9c74eb 100644 --- a/spec/ruby/core/exception/success_spec.rb +++ b/spec/ruby/core/exception/success_spec.rb @@ -1,5 +1,15 @@ require_relative '../../spec_helper' describe "SystemExit#success?" do - it "needs to be reviewed for spec completeness" + it "returns true if the process exited successfully" do + -> { exit 0 }.should raise_error(SystemExit) { |e| + e.success?.should == true + } + end + + it "returns false if the process exited unsuccessfully" do + -> { exit(-1) }.should raise_error(SystemExit) { |e| + e.success?.should == false + } + end end diff --git a/spec/ruby/core/exception/system_call_error_spec.rb b/spec/ruby/core/exception/system_call_error_spec.rb index c510ae440f..f27977a547 100644 --- a/spec/ruby/core/exception/system_call_error_spec.rb +++ b/spec/ruby/core/exception/system_call_error_spec.rb @@ -128,3 +128,16 @@ describe "SystemCallError#message" do SystemCallError.new("XXX").message.should =~ /XXX/ end end + +describe "SystemCallError#dup" do + it "copies the errno" do + dup_sce = SystemCallError.new("message", 42).dup + dup_sce.errno.should == 42 + end +end + +describe "SystemCallError#backtrace" do + it "is nil if not raised" do + SystemCallError.new("message", 42).backtrace.should == nil + end +end diff --git a/spec/ruby/core/exception/system_stack_error_spec.rb b/spec/ruby/core/exception/system_stack_error_spec.rb deleted file mode 100644 index 0343d2da59..0000000000 --- a/spec/ruby/core/exception/system_stack_error_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require_relative '../../spec_helper' - -describe "SystemStackError" do - it "is a subclass of Exception" do - SystemStackError.superclass.should == Exception - end -end diff --git a/spec/ruby/core/exception/uncaught_throw_error_spec.rb b/spec/ruby/core/exception/uncaught_throw_error_spec.rb index 57f391d755..9267df6670 100644 --- a/spec/ruby/core/exception/uncaught_throw_error_spec.rb +++ b/spec/ruby/core/exception/uncaught_throw_error_spec.rb @@ -1,11 +1,5 @@ require_relative '../../spec_helper' -describe "UncaughtThrowError" do - it "is a subclass of ArgumentError" do - ArgumentError.should be_ancestor_of(UncaughtThrowError) - end -end - describe "UncaughtThrowError#tag" do it "returns the object thrown" do begin diff --git a/spec/ruby/core/gc/start_spec.rb b/spec/ruby/core/gc/start_spec.rb index fb6820db14..c941058969 100644 --- a/spec/ruby/core/gc/start_spec.rb +++ b/spec/ruby/core/gc/start_spec.rb @@ -5,4 +5,8 @@ describe "GC.start" do GC.start.should == nil GC.start.should == nil end + + it "accepts keyword arguments" do + GC.start(full_mark: true, immediate_sweep: true).should == nil + end end diff --git a/spec/ruby/core/kernel/printf_spec.rb b/spec/ruby/core/kernel/printf_spec.rb index 5d68c0a13c..4592c08aaf 100644 --- a/spec/ruby/core/kernel/printf_spec.rb +++ b/spec/ruby/core/kernel/printf_spec.rb @@ -10,7 +10,6 @@ describe "Kernel#printf" do end describe "Kernel.printf" do - before :each do @stdout = $stdout @name = tmp("kernel_puts.txt") @@ -38,7 +37,7 @@ describe "Kernel.printf" do context "io is specified" do it_behaves_like :kernel_sprintf, -> format, *args { io = StringIO.new - printf(io, format, *args) + Kernel.printf(io, format, *args) io.string } end @@ -49,7 +48,7 @@ describe "Kernel.printf" do begin $stdout = io = StringIO.new - printf(format, *args) + Kernel.printf(format, *args) io.string ensure $stdout = stdout diff --git a/spec/ruby/core/kernel/shared/sprintf.rb b/spec/ruby/core/kernel/shared/sprintf.rb index 9899684284..8defbfd665 100644 --- a/spec/ruby/core/kernel/shared/sprintf.rb +++ b/spec/ruby/core/kernel/shared/sprintf.rb @@ -1,10 +1,4 @@ -require_relative '../../../shared/hash/key_error' - describe :kernel_sprintf, shared: true do - def format(*args) - @method.call(*args) - end - describe "integer formats" do it "converts argument into Integer with to_int" do obj = Object.new @@ -12,7 +6,7 @@ describe :kernel_sprintf, shared: true do def obj.to_int; 10; end obj.should_receive(:to_int).and_return(10) - format("%b", obj).should == "1010" + @method.call("%b", obj).should == "1010" end it "converts argument into Integer with to_i if to_int isn't available" do @@ -20,35 +14,35 @@ describe :kernel_sprintf, shared: true do def obj.to_i; 10; end obj.should_receive(:to_i).and_return(10) - format("%b", obj).should == "1010" + @method.call("%b", obj).should == "1010" end it "converts String argument with Kernel#Integer" do - format("%d", "0b1010").should == "10" - format("%d", "112").should == "112" - format("%d", "0127").should == "87" - format("%d", "0xc4").should == "196" + @method.call("%d", "0b1010").should == "10" + @method.call("%d", "112").should == "112" + @method.call("%d", "0127").should == "87" + @method.call("%d", "0xc4").should == "196" end it "raises TypeError exception if cannot convert to Integer" do -> { - format("%b", Object.new) + @method.call("%b", Object.new) }.should raise_error(TypeError) end ["b", "B"].each do |f| describe f do it "converts argument as a binary number" do - format("%#{f}", 10).should == "1010" + @method.call("%#{f}", 10).should == "1010" end it "displays negative number as a two's complement prefixed with '..1'" do - format("%#{f}", -10).should == "..1" + "0110" + @method.call("%#{f}", -10).should == "..1" + "0110" end it "collapse negative number representation if it equals 1" do - format("%#{f}", -1).should_not == "..11" - format("%#{f}", -1).should == "..1" + @method.call("%#{f}", -1).should_not == "..11" + @method.call("%#{f}", -1).should == "..1" end end end @@ -56,58 +50,58 @@ describe :kernel_sprintf, shared: true do ["d", "i", "u"].each do |f| describe f do it "converts argument as a decimal number" do - format("%#{f}", 112).should == "112" - format("%#{f}", -112).should == "-112" + @method.call("%#{f}", 112).should == "112" + @method.call("%#{f}", -112).should == "-112" end it "works well with large numbers" do - format("%#{f}", 1234567890987654321).should == "1234567890987654321" + @method.call("%#{f}", 1234567890987654321).should == "1234567890987654321" end end end describe "o" do it "converts argument as an octal number" do - format("%o", 87).should == "127" + @method.call("%o", 87).should == "127" end it "displays negative number as a two's complement prefixed with '..7'" do - format("%o", -87).should == "..7" + "651" + @method.call("%o", -87).should == "..7" + "651" end it "collapse negative number representation if it equals 7" do - format("%o", -1).should_not == "..77" - format("%o", -1).should == "..7" + @method.call("%o", -1).should_not == "..77" + @method.call("%o", -1).should == "..7" end end describe "x" do it "converts argument as a hexadecimal number" do - format("%x", 196).should == "c4" + @method.call("%x", 196).should == "c4" end it "displays negative number as a two's complement prefixed with '..f'" do - format("%x", -196).should == "..f" + "3c" + @method.call("%x", -196).should == "..f" + "3c" end it "collapse negative number representation if it equals f" do - format("%x", -1).should_not == "..ff" - format("%x", -1).should == "..f" + @method.call("%x", -1).should_not == "..ff" + @method.call("%x", -1).should == "..f" end end describe "X" do it "converts argument as a hexadecimal number with uppercase letters" do - format("%X", 196).should == "C4" + @method.call("%X", 196).should == "C4" end it "displays negative number as a two's complement prefixed with '..f'" do - format("%X", -196).should == "..F" + "3C" + @method.call("%X", -196).should == "..F" + "3C" end it "collapse negative number representation if it equals F" do - format("%X", -1).should_not == "..FF" - format("%X", -1).should == "..F" + @method.call("%X", -1).should_not == "..FF" + @method.call("%X", -1).should == "..F" end end end @@ -116,70 +110,70 @@ describe :kernel_sprintf, shared: true do it "converts argument into Float" do obj = mock("float") obj.should_receive(:to_f).and_return(9.6) - format("%f", obj).should == "9.600000" + @method.call("%f", obj).should == "9.600000" end it "raises TypeError exception if cannot convert to Float" do -> { - format("%f", Object.new) + @method.call("%f", Object.new) }.should raise_error(TypeError) end {"e" => "e", "E" => "E"}.each_pair do |f, exp| describe f do it "converts argument into exponential notation [-]d.dddddde[+-]dd" do - format("%#{f}", 109.52).should == "1.095200#{exp}+02" - format("%#{f}", -109.52).should == "-1.095200#{exp}+02" - format("%#{f}", 0.10952).should == "1.095200#{exp}-01" - format("%#{f}", -0.10952).should == "-1.095200#{exp}-01" + @method.call("%#{f}", 109.52).should == "1.095200#{exp}+02" + @method.call("%#{f}", -109.52).should == "-1.095200#{exp}+02" + @method.call("%#{f}", 0.10952).should == "1.095200#{exp}-01" + @method.call("%#{f}", -0.10952).should == "-1.095200#{exp}-01" end it "cuts excessive digits and keeps only 6 ones" do - format("%#{f}", 1.123456789).should == "1.123457#{exp}+00" + @method.call("%#{f}", 1.123456789).should == "1.123457#{exp}+00" end it "rounds the last significant digit to the closest one" do - format("%#{f}", 1.555555555).should == "1.555556#{exp}+00" - format("%#{f}", -1.555555555).should == "-1.555556#{exp}+00" - format("%#{f}", 1.444444444).should == "1.444444#{exp}+00" + @method.call("%#{f}", 1.555555555).should == "1.555556#{exp}+00" + @method.call("%#{f}", -1.555555555).should == "-1.555556#{exp}+00" + @method.call("%#{f}", 1.444444444).should == "1.444444#{exp}+00" end it "displays Float::INFINITY as Inf" do - format("%#{f}", Float::INFINITY).should == "Inf" - format("%#{f}", -Float::INFINITY).should == "-Inf" + @method.call("%#{f}", Float::INFINITY).should == "Inf" + @method.call("%#{f}", -Float::INFINITY).should == "-Inf" end it "displays Float::NAN as NaN" do - format("%#{f}", Float::NAN).should == "NaN" - format("%#{f}", -Float::NAN).should == "NaN" + @method.call("%#{f}", Float::NAN).should == "NaN" + @method.call("%#{f}", -Float::NAN).should == "NaN" end end end describe "f" do it "converts floating point argument as [-]ddd.dddddd" do - format("%f", 10.952).should == "10.952000" - format("%f", -10.952).should == "-10.952000" + @method.call("%f", 10.952).should == "10.952000" + @method.call("%f", -10.952).should == "-10.952000" end it "cuts excessive digits and keeps only 6 ones" do - format("%f", 1.123456789).should == "1.123457" + @method.call("%f", 1.123456789).should == "1.123457" end it "rounds the last significant digit to the closest one" do - format("%f", 1.555555555).should == "1.555556" - format("%f", -1.555555555).should == "-1.555556" - format("%f", 1.444444444).should == "1.444444" + @method.call("%f", 1.555555555).should == "1.555556" + @method.call("%f", -1.555555555).should == "-1.555556" + @method.call("%f", 1.444444444).should == "1.444444" end it "displays Float::INFINITY as Inf" do - format("%f", Float::INFINITY).should == "Inf" - format("%f", -Float::INFINITY).should == "-Inf" + @method.call("%f", Float::INFINITY).should == "Inf" + @method.call("%f", -Float::INFINITY).should == "-Inf" end it "displays Float::NAN as NaN" do - format("%f", Float::NAN).should == "NaN" - format("%f", -Float::NAN).should == "NaN" + @method.call("%f", Float::NAN).should == "NaN" + @method.call("%f", -Float::NAN).should == "NaN" end end @@ -187,100 +181,100 @@ describe :kernel_sprintf, shared: true do describe f do context "the exponent is less than -4" do it "converts a floating point number using exponential form" do - format("%#{f}", 0.0000123456).should == "1.23456#{exp}-05" - format("%#{f}", -0.0000123456).should == "-1.23456#{exp}-05" + @method.call("%#{f}", 0.0000123456).should == "1.23456#{exp}-05" + @method.call("%#{f}", -0.0000123456).should == "-1.23456#{exp}-05" - format("%#{f}", 0.000000000123456).should == "1.23456#{exp}-10" - format("%#{f}", -0.000000000123456).should == "-1.23456#{exp}-10" + @method.call("%#{f}", 0.000000000123456).should == "1.23456#{exp}-10" + @method.call("%#{f}", -0.000000000123456).should == "-1.23456#{exp}-10" end end context "the exponent is greater than or equal to the precision (6 by default)" do it "converts a floating point number using exponential form" do - format("%#{f}", 1234567).should == "1.23457#{exp}+06" - format("%#{f}", 1234567890123).should == "1.23457#{exp}+12" - format("%#{f}", -1234567).should == "-1.23457#{exp}+06" + @method.call("%#{f}", 1234567).should == "1.23457#{exp}+06" + @method.call("%#{f}", 1234567890123).should == "1.23457#{exp}+12" + @method.call("%#{f}", -1234567).should == "-1.23457#{exp}+06" end end context "otherwise" do it "converts a floating point number in dd.dddd form" do - format("%#{f}", 0.0001).should == "0.0001" - format("%#{f}", -0.0001).should == "-0.0001" - format("%#{f}", 123456).should == "123456" - format("%#{f}", -123456).should == "-123456" + @method.call("%#{f}", 0.0001).should == "0.0001" + @method.call("%#{f}", -0.0001).should == "-0.0001" + @method.call("%#{f}", 123456).should == "123456" + @method.call("%#{f}", -123456).should == "-123456" end it "cuts excessive digits in fractional part and keeps only 4 ones" do - format("%#{f}", 12.12341111).should == "12.1234" - format("%#{f}", -12.12341111).should == "-12.1234" + @method.call("%#{f}", 12.12341111).should == "12.1234" + @method.call("%#{f}", -12.12341111).should == "-12.1234" end it "rounds the last significant digit to the closest one in fractional part" do - format("%#{f}", 1.555555555).should == "1.55556" - format("%#{f}", -1.555555555).should == "-1.55556" - format("%#{f}", 1.444444444).should == "1.44444" + @method.call("%#{f}", 1.555555555).should == "1.55556" + @method.call("%#{f}", -1.555555555).should == "-1.55556" + @method.call("%#{f}", 1.444444444).should == "1.44444" end it "cuts fraction part to have only 6 digits at all" do - format("%#{f}", 1.1234567).should == "1.12346" - format("%#{f}", 12.1234567).should == "12.1235" - format("%#{f}", 123.1234567).should == "123.123" - format("%#{f}", 1234.1234567).should == "1234.12" - format("%#{f}", 12345.1234567).should == "12345.1" - format("%#{f}", 123456.1234567).should == "123456" + @method.call("%#{f}", 1.1234567).should == "1.12346" + @method.call("%#{f}", 12.1234567).should == "12.1235" + @method.call("%#{f}", 123.1234567).should == "123.123" + @method.call("%#{f}", 1234.1234567).should == "1234.12" + @method.call("%#{f}", 12345.1234567).should == "12345.1" + @method.call("%#{f}", 123456.1234567).should == "123456" end end it "displays Float::INFINITY as Inf" do - format("%#{f}", Float::INFINITY).should == "Inf" - format("%#{f}", -Float::INFINITY).should == "-Inf" + @method.call("%#{f}", Float::INFINITY).should == "Inf" + @method.call("%#{f}", -Float::INFINITY).should == "-Inf" end it "displays Float::NAN as NaN" do - format("%#{f}", Float::NAN).should == "NaN" - format("%#{f}", -Float::NAN).should == "NaN" + @method.call("%#{f}", Float::NAN).should == "NaN" + @method.call("%#{f}", -Float::NAN).should == "NaN" end end end describe "a" do it "converts floating point argument as [-]0xh.hhhhp[+-]dd" do - format("%a", 196).should == "0x1.88p+7" - format("%a", -196).should == "-0x1.88p+7" - format("%a", 196.1).should == "0x1.8833333333333p+7" - format("%a", 0.01).should == "0x1.47ae147ae147bp-7" - format("%a", -0.01).should == "-0x1.47ae147ae147bp-7" + @method.call("%a", 196).should == "0x1.88p+7" + @method.call("%a", -196).should == "-0x1.88p+7" + @method.call("%a", 196.1).should == "0x1.8833333333333p+7" + @method.call("%a", 0.01).should == "0x1.47ae147ae147bp-7" + @method.call("%a", -0.01).should == "-0x1.47ae147ae147bp-7" end it "displays Float::INFINITY as Inf" do - format("%a", Float::INFINITY).should == "Inf" - format("%a", -Float::INFINITY).should == "-Inf" + @method.call("%a", Float::INFINITY).should == "Inf" + @method.call("%a", -Float::INFINITY).should == "-Inf" end it "displays Float::NAN as NaN" do - format("%a", Float::NAN).should == "NaN" - format("%a", -Float::NAN).should == "NaN" + @method.call("%a", Float::NAN).should == "NaN" + @method.call("%a", -Float::NAN).should == "NaN" end end describe "A" do it "converts floating point argument as [-]0xh.hhhhp[+-]dd and use uppercase X and P" do - format("%A", 196).should == "0X1.88P+7" - format("%A", -196).should == "-0X1.88P+7" - format("%A", 196.1).should == "0X1.8833333333333P+7" - format("%A", 0.01).should == "0X1.47AE147AE147BP-7" - format("%A", -0.01).should == "-0X1.47AE147AE147BP-7" + @method.call("%A", 196).should == "0X1.88P+7" + @method.call("%A", -196).should == "-0X1.88P+7" + @method.call("%A", 196.1).should == "0X1.8833333333333P+7" + @method.call("%A", 0.01).should == "0X1.47AE147AE147BP-7" + @method.call("%A", -0.01).should == "-0X1.47AE147AE147BP-7" end it "displays Float::INFINITY as Inf" do - format("%A", Float::INFINITY).should == "Inf" - format("%A", -Float::INFINITY).should == "-Inf" + @method.call("%A", Float::INFINITY).should == "Inf" + @method.call("%A", -Float::INFINITY).should == "-Inf" end it "displays Float::NAN as NaN" do - format("%A", Float::NAN).should == "NaN" - format("%A", -Float::NAN).should == "NaN" + @method.call("%A", Float::NAN).should == "NaN" + @method.call("%A", -Float::NAN).should == "NaN" end end end @@ -288,28 +282,28 @@ describe :kernel_sprintf, shared: true do describe "other formats" do describe "c" do it "displays character if argument is a numeric code of character" do - format("%c", 97).should == "a" + @method.call("%c", 97).should == "a" end it "displays character if argument is a single character string" do - format("%c", "a").should == "a" + @method.call("%c", "a").should == "a" end it "raises ArgumentError if argument is a string of several characters" do -> { - format("%c", "abc") + @method.call("%c", "abc") }.should raise_error(ArgumentError) end it "raises ArgumentError if argument is an empty string" do -> { - format("%c", "") + @method.call("%c", "") }.should raise_error(ArgumentError) end it "supports Unicode characters" do - format("%c", 1286).should == "Ԇ" - format("%c", "ش").should == "ش" + @method.call("%c", 1286).should == "Ԇ" + @method.call("%c", "ش").should == "ش" end end @@ -317,19 +311,19 @@ describe :kernel_sprintf, shared: true do it "displays argument.inspect value" do obj = mock("object") obj.should_receive(:inspect).and_return("<inspect-result>") - format("%p", obj).should == "<inspect-result>" + @method.call("%p", obj).should == "<inspect-result>" end end describe "s" do it "substitute argument passes as a string" do - format("%s", "abc").should == "abc" + @method.call("%s", "abc").should == "abc" end it "converts argument to string with to_s" do obj = mock("string") obj.should_receive(:to_s).and_return("abc") - format("%s", obj).should == "abc" + @method.call("%s", obj).should == "abc" end it "does not try to convert with to_str" do @@ -339,7 +333,7 @@ describe :kernel_sprintf, shared: true do end -> { - format("%s", obj) + @method.call("%s", obj) }.should raise_error(NoMethodError) end end @@ -347,21 +341,21 @@ describe :kernel_sprintf, shared: true do describe "%" do ruby_version_is ""..."2.5" do it "alone displays the percent sign" do - format("%").should == "%" + @method.call("%").should == "%" end end ruby_version_is "2.5" do it "alone raises an ArgumentError" do -> { - format("%") + @method.call("%") }.should raise_error(ArgumentError) end end it "is escaped by %" do - format("%%").should == "%" - format("%%d", 10).should == "%d" + @method.call("%%").should == "%" + @method.call("%%d", 10).should == "%d" end end end @@ -370,110 +364,110 @@ describe :kernel_sprintf, shared: true do describe "space" do context "applies to numeric formats bBdiouxXeEfgGaA" do it "leaves a space at the start of non-negative numbers" do - format("% b", 10).should == " 1010" - format("% B", 10).should == " 1010" - format("% d", 112).should == " 112" - format("% i", 112).should == " 112" - format("% o", 87).should == " 127" - format("% u", 112).should == " 112" - format("% x", 196).should == " c4" - format("% X", 196).should == " C4" - - format("% e", 109.52).should == " 1.095200e+02" - format("% E", 109.52).should == " 1.095200E+02" - format("% f", 10.952).should == " 10.952000" - format("% g", 12.1234).should == " 12.1234" - format("% G", 12.1234).should == " 12.1234" - format("% a", 196).should == " 0x1.88p+7" - format("% A", 196).should == " 0X1.88P+7" + @method.call("% b", 10).should == " 1010" + @method.call("% B", 10).should == " 1010" + @method.call("% d", 112).should == " 112" + @method.call("% i", 112).should == " 112" + @method.call("% o", 87).should == " 127" + @method.call("% u", 112).should == " 112" + @method.call("% x", 196).should == " c4" + @method.call("% X", 196).should == " C4" + + @method.call("% e", 109.52).should == " 1.095200e+02" + @method.call("% E", 109.52).should == " 1.095200E+02" + @method.call("% f", 10.952).should == " 10.952000" + @method.call("% g", 12.1234).should == " 12.1234" + @method.call("% G", 12.1234).should == " 12.1234" + @method.call("% a", 196).should == " 0x1.88p+7" + @method.call("% A", 196).should == " 0X1.88P+7" end it "does not leave a space at the start of negative numbers" do - format("% b", -10).should == "-1010" - format("% B", -10).should == "-1010" - format("% d", -112).should == "-112" - format("% i", -112).should == "-112" - format("% o", -87).should == "-127" - format("% u", -112).should == "-112" - format("% x", -196).should == "-c4" - format("% X", -196).should == "-C4" - - format("% e", -109.52).should == "-1.095200e+02" - format("% E", -109.52).should == "-1.095200E+02" - format("% f", -10.952).should == "-10.952000" - format("% g", -12.1234).should == "-12.1234" - format("% G", -12.1234).should == "-12.1234" - format("% a", -196).should == "-0x1.88p+7" - format("% A", -196).should == "-0X1.88P+7" + @method.call("% b", -10).should == "-1010" + @method.call("% B", -10).should == "-1010" + @method.call("% d", -112).should == "-112" + @method.call("% i", -112).should == "-112" + @method.call("% o", -87).should == "-127" + @method.call("% u", -112).should == "-112" + @method.call("% x", -196).should == "-c4" + @method.call("% X", -196).should == "-C4" + + @method.call("% e", -109.52).should == "-1.095200e+02" + @method.call("% E", -109.52).should == "-1.095200E+02" + @method.call("% f", -10.952).should == "-10.952000" + @method.call("% g", -12.1234).should == "-12.1234" + @method.call("% G", -12.1234).should == "-12.1234" + @method.call("% a", -196).should == "-0x1.88p+7" + @method.call("% A", -196).should == "-0X1.88P+7" end it "prevents converting negative argument to two's complement form" do - format("% b", -10).should == "-1010" - format("% B", -10).should == "-1010" - format("% o", -87).should == "-127" - format("% x", -196).should == "-c4" - format("% X", -196).should == "-C4" + @method.call("% b", -10).should == "-1010" + @method.call("% B", -10).should == "-1010" + @method.call("% o", -87).should == "-127" + @method.call("% x", -196).should == "-c4" + @method.call("% X", -196).should == "-C4" end it "treats several white spaces as one" do - format("% b", 10).should == " 1010" - format("% B", 10).should == " 1010" - format("% d", 112).should == " 112" - format("% i", 112).should == " 112" - format("% o", 87).should == " 127" - format("% u", 112).should == " 112" - format("% x", 196).should == " c4" - format("% X", 196).should == " C4" + @method.call("% b", 10).should == " 1010" + @method.call("% B", 10).should == " 1010" + @method.call("% d", 112).should == " 112" + @method.call("% i", 112).should == " 112" + @method.call("% o", 87).should == " 127" + @method.call("% u", 112).should == " 112" + @method.call("% x", 196).should == " c4" + @method.call("% X", 196).should == " C4" - format("% e", 109.52).should == " 1.095200e+02" - format("% E", 109.52).should == " 1.095200E+02" - format("% f", 10.952).should == " 10.952000" - format("% g", 12.1234).should == " 12.1234" - format("% G", 12.1234).should == " 12.1234" - format("% a", 196).should == " 0x1.88p+7" - format("% A", 196).should == " 0X1.88P+7" + @method.call("% e", 109.52).should == " 1.095200e+02" + @method.call("% E", 109.52).should == " 1.095200E+02" + @method.call("% f", 10.952).should == " 10.952000" + @method.call("% g", 12.1234).should == " 12.1234" + @method.call("% G", 12.1234).should == " 12.1234" + @method.call("% a", 196).should == " 0x1.88p+7" + @method.call("% A", 196).should == " 0X1.88P+7" end end end describe "(digit)$" do it "specifies the absolute argument number for this field" do - format("%2$b", 0, 10).should == "1010" - format("%2$B", 0, 10).should == "1010" - format("%2$d", 0, 112).should == "112" - format("%2$i", 0, 112).should == "112" - format("%2$o", 0, 87).should == "127" - format("%2$u", 0, 112).should == "112" - format("%2$x", 0, 196).should == "c4" - format("%2$X", 0, 196).should == "C4" - - format("%2$e", 0, 109.52).should == "1.095200e+02" - format("%2$E", 0, 109.52).should == "1.095200E+02" - format("%2$f", 0, 10.952).should == "10.952000" - format("%2$g", 0, 12.1234).should == "12.1234" - format("%2$G", 0, 12.1234).should == "12.1234" - format("%2$a", 0, 196).should == "0x1.88p+7" - format("%2$A", 0, 196).should == "0X1.88P+7" - - format("%2$c", 1, 97).should == "a" - format("%2$p", "a", []).should == "[]" - format("%2$s", "-", "abc").should == "abc" + @method.call("%2$b", 0, 10).should == "1010" + @method.call("%2$B", 0, 10).should == "1010" + @method.call("%2$d", 0, 112).should == "112" + @method.call("%2$i", 0, 112).should == "112" + @method.call("%2$o", 0, 87).should == "127" + @method.call("%2$u", 0, 112).should == "112" + @method.call("%2$x", 0, 196).should == "c4" + @method.call("%2$X", 0, 196).should == "C4" + + @method.call("%2$e", 0, 109.52).should == "1.095200e+02" + @method.call("%2$E", 0, 109.52).should == "1.095200E+02" + @method.call("%2$f", 0, 10.952).should == "10.952000" + @method.call("%2$g", 0, 12.1234).should == "12.1234" + @method.call("%2$G", 0, 12.1234).should == "12.1234" + @method.call("%2$a", 0, 196).should == "0x1.88p+7" + @method.call("%2$A", 0, 196).should == "0X1.88P+7" + + @method.call("%2$c", 1, 97).should == "a" + @method.call("%2$p", "a", []).should == "[]" + @method.call("%2$s", "-", "abc").should == "abc" end it "raises exception if argument number is bigger than actual arguments list" do -> { - format("%4$d", 1, 2, 3) + @method.call("%4$d", 1, 2, 3) }.should raise_error(ArgumentError) end it "ignores '-' sign" do - format("%2$d", 1, 2, 3).should == "2" - format("%-2$d", 1, 2, 3).should == "2" + @method.call("%2$d", 1, 2, 3).should == "2" + @method.call("%-2$d", 1, 2, 3).should == "2" end it "raises ArgumentError exception when absolute and relative argument numbers are mixed" do -> { - format("%1$d %d", 1, 2) + @method.call("%1$d %d", 1, 2) }.should raise_error(ArgumentError) end end @@ -481,62 +475,62 @@ describe :kernel_sprintf, shared: true do describe "#" do context "applies to format o" do it "increases the precision until the first digit will be `0' if it is not formatted as complements" do - format("%#o", 87).should == "0127" + @method.call("%#o", 87).should == "0127" end it "does nothing for negative argument" do - format("%#o", -87).should == "..7651" + @method.call("%#o", -87).should == "..7651" end end context "applies to formats bBxX" do it "prefixes the result with 0x, 0X, 0b and 0B respectively for non-zero argument" do - format("%#b", 10).should == "0b1010" - format("%#b", -10).should == "0b..10110" - format("%#B", 10).should == "0B1010" - format("%#B", -10).should == "0B..10110" + @method.call("%#b", 10).should == "0b1010" + @method.call("%#b", -10).should == "0b..10110" + @method.call("%#B", 10).should == "0B1010" + @method.call("%#B", -10).should == "0B..10110" - format("%#x", 196).should == "0xc4" - format("%#x", -196).should == "0x..f3c" - format("%#X", 196).should == "0XC4" - format("%#X", -196).should == "0X..F3C" + @method.call("%#x", 196).should == "0xc4" + @method.call("%#x", -196).should == "0x..f3c" + @method.call("%#X", 196).should == "0XC4" + @method.call("%#X", -196).should == "0X..F3C" end it "does nothing for zero argument" do - format("%#b", 0).should == "0" - format("%#B", 0).should == "0" + @method.call("%#b", 0).should == "0" + @method.call("%#B", 0).should == "0" - format("%#o", 0).should == "0" + @method.call("%#o", 0).should == "0" - format("%#x", 0).should == "0" - format("%#X", 0).should == "0" + @method.call("%#x", 0).should == "0" + @method.call("%#X", 0).should == "0" end end context "applies to formats aAeEfgG" do it "forces a decimal point to be added, even if no digits follow" do - format("%#.0a", 16.25).should == "0x1.p+4" - format("%#.0A", 16.25).should == "0X1.P+4" + @method.call("%#.0a", 16.25).should == "0x1.p+4" + @method.call("%#.0A", 16.25).should == "0X1.P+4" - format("%#.0e", 100).should == "1.e+02" - format("%#.0E", 100).should == "1.E+02" + @method.call("%#.0e", 100).should == "1.e+02" + @method.call("%#.0E", 100).should == "1.E+02" - format("%#.0f", 123.4).should == "123." + @method.call("%#.0f", 123.4).should == "123." - format("%#g", 123456).should == "123456." - format("%#G", 123456).should == "123456." + @method.call("%#g", 123456).should == "123456." + @method.call("%#G", 123456).should == "123456." end it "changes format from dd.dddd to exponential form for gG" do - format("%#.0g", 123.4).should_not == "123." - format("%#.0g", 123.4).should == "1.e+02" + @method.call("%#.0g", 123.4).should_not == "123." + @method.call("%#.0g", 123.4).should == "1.e+02" end end context "applies to gG" do it "does not remove trailing zeros" do - format("%#g", 123.4).should == "123.400" - format("%#g", 123.4).should == "123.400" + @method.call("%#g", 123.4).should == "123.400" + @method.call("%#g", 123.4).should == "123.400" end end end @@ -544,186 +538,186 @@ describe :kernel_sprintf, shared: true do describe "+" do context "applies to numeric formats bBdiouxXaAeEfgG" do it "adds a leading plus sign to non-negative numbers" do - format("%+b", 10).should == "+1010" - format("%+B", 10).should == "+1010" - format("%+d", 112).should == "+112" - format("%+i", 112).should == "+112" - format("%+o", 87).should == "+127" - format("%+u", 112).should == "+112" - format("%+x", 196).should == "+c4" - format("%+X", 196).should == "+C4" - - format("%+e", 109.52).should == "+1.095200e+02" - format("%+E", 109.52).should == "+1.095200E+02" - format("%+f", 10.952).should == "+10.952000" - format("%+g", 12.1234).should == "+12.1234" - format("%+G", 12.1234).should == "+12.1234" - format("%+a", 196).should == "+0x1.88p+7" - format("%+A", 196).should == "+0X1.88P+7" + @method.call("%+b", 10).should == "+1010" + @method.call("%+B", 10).should == "+1010" + @method.call("%+d", 112).should == "+112" + @method.call("%+i", 112).should == "+112" + @method.call("%+o", 87).should == "+127" + @method.call("%+u", 112).should == "+112" + @method.call("%+x", 196).should == "+c4" + @method.call("%+X", 196).should == "+C4" + + @method.call("%+e", 109.52).should == "+1.095200e+02" + @method.call("%+E", 109.52).should == "+1.095200E+02" + @method.call("%+f", 10.952).should == "+10.952000" + @method.call("%+g", 12.1234).should == "+12.1234" + @method.call("%+G", 12.1234).should == "+12.1234" + @method.call("%+a", 196).should == "+0x1.88p+7" + @method.call("%+A", 196).should == "+0X1.88P+7" end it "does not use two's complement form for negative numbers for formats bBoxX" do - format("%+b", -10).should == "-1010" - format("%+B", -10).should == "-1010" - format("%+o", -87).should == "-127" - format("%+x", -196).should == "-c4" - format("%+X", -196).should == "-C4" + @method.call("%+b", -10).should == "-1010" + @method.call("%+B", -10).should == "-1010" + @method.call("%+o", -87).should == "-127" + @method.call("%+x", -196).should == "-c4" + @method.call("%+X", -196).should == "-C4" end end end describe "-" do it "left-justifies the result of conversion if width is specified" do - format("%-10b", 10).should == "1010 " - format("%-10B", 10).should == "1010 " - format("%-10d", 112).should == "112 " - format("%-10i", 112).should == "112 " - format("%-10o", 87).should == "127 " - format("%-10u", 112).should == "112 " - format("%-10x", 196).should == "c4 " - format("%-10X", 196).should == "C4 " + @method.call("%-10b", 10).should == "1010 " + @method.call("%-10B", 10).should == "1010 " + @method.call("%-10d", 112).should == "112 " + @method.call("%-10i", 112).should == "112 " + @method.call("%-10o", 87).should == "127 " + @method.call("%-10u", 112).should == "112 " + @method.call("%-10x", 196).should == "c4 " + @method.call("%-10X", 196).should == "C4 " - format("%-20e", 109.52).should == "1.095200e+02 " - format("%-20E", 109.52).should == "1.095200E+02 " - format("%-20f", 10.952).should == "10.952000 " - format("%-20g", 12.1234).should == "12.1234 " - format("%-20G", 12.1234).should == "12.1234 " - format("%-20a", 196).should == "0x1.88p+7 " - format("%-20A", 196).should == "0X1.88P+7 " + @method.call("%-20e", 109.52).should == "1.095200e+02 " + @method.call("%-20E", 109.52).should == "1.095200E+02 " + @method.call("%-20f", 10.952).should == "10.952000 " + @method.call("%-20g", 12.1234).should == "12.1234 " + @method.call("%-20G", 12.1234).should == "12.1234 " + @method.call("%-20a", 196).should == "0x1.88p+7 " + @method.call("%-20A", 196).should == "0X1.88P+7 " - format("%-10c", 97).should == "a " - format("%-10p", []).should == "[] " - format("%-10s", "abc").should == "abc " + @method.call("%-10c", 97).should == "a " + @method.call("%-10p", []).should == "[] " + @method.call("%-10s", "abc").should == "abc " end end describe "0 (zero)" do context "applies to numeric formats bBdiouxXaAeEfgG and width is specified" do it "pads with zeros, not spaces" do - format("%010b", 10).should == "0000001010" - format("%010B", 10).should == "0000001010" - format("%010d", 112).should == "0000000112" - format("%010i", 112).should == "0000000112" - format("%010o", 87).should == "0000000127" - format("%010u", 112).should == "0000000112" - format("%010x", 196).should == "00000000c4" - format("%010X", 196).should == "00000000C4" - - format("%020e", 109.52).should == "000000001.095200e+02" - format("%020E", 109.52).should == "000000001.095200E+02" - format("%020f", 10.952).should == "0000000000010.952000" - format("%020g", 12.1234).should == "000000000000012.1234" - format("%020G", 12.1234).should == "000000000000012.1234" - format("%020a", 196).should == "0x000000000001.88p+7" - format("%020A", 196).should == "0X000000000001.88P+7" + @method.call("%010b", 10).should == "0000001010" + @method.call("%010B", 10).should == "0000001010" + @method.call("%010d", 112).should == "0000000112" + @method.call("%010i", 112).should == "0000000112" + @method.call("%010o", 87).should == "0000000127" + @method.call("%010u", 112).should == "0000000112" + @method.call("%010x", 196).should == "00000000c4" + @method.call("%010X", 196).should == "00000000C4" + + @method.call("%020e", 109.52).should == "000000001.095200e+02" + @method.call("%020E", 109.52).should == "000000001.095200E+02" + @method.call("%020f", 10.952).should == "0000000000010.952000" + @method.call("%020g", 12.1234).should == "000000000000012.1234" + @method.call("%020G", 12.1234).should == "000000000000012.1234" + @method.call("%020a", 196).should == "0x000000000001.88p+7" + @method.call("%020A", 196).should == "0X000000000001.88P+7" end it "uses radix-1 when displays negative argument as a two's complement" do - format("%010b", -10).should == "..11110110" - format("%010B", -10).should == "..11110110" - format("%010o", -87).should == "..77777651" - format("%010x", -196).should == "..ffffff3c" - format("%010X", -196).should == "..FFFFFF3C" + @method.call("%010b", -10).should == "..11110110" + @method.call("%010B", -10).should == "..11110110" + @method.call("%010o", -87).should == "..77777651" + @method.call("%010x", -196).should == "..ffffff3c" + @method.call("%010X", -196).should == "..FFFFFF3C" end end end describe "*" do it "uses the previous argument as the field width" do - format("%*b", 10, 10).should == " 1010" - format("%*B", 10, 10).should == " 1010" - format("%*d", 10, 112).should == " 112" - format("%*i", 10, 112).should == " 112" - format("%*o", 10, 87).should == " 127" - format("%*u", 10, 112).should == " 112" - format("%*x", 10, 196).should == " c4" - format("%*X", 10, 196).should == " C4" - - format("%*e", 20, 109.52).should == " 1.095200e+02" - format("%*E", 20, 109.52).should == " 1.095200E+02" - format("%*f", 20, 10.952).should == " 10.952000" - format("%*g", 20, 12.1234).should == " 12.1234" - format("%*G", 20, 12.1234).should == " 12.1234" - format("%*a", 20, 196).should == " 0x1.88p+7" - format("%*A", 20, 196).should == " 0X1.88P+7" - - format("%*c", 10, 97).should == " a" - format("%*p", 10, []).should == " []" - format("%*s", 10, "abc").should == " abc" + @method.call("%*b", 10, 10).should == " 1010" + @method.call("%*B", 10, 10).should == " 1010" + @method.call("%*d", 10, 112).should == " 112" + @method.call("%*i", 10, 112).should == " 112" + @method.call("%*o", 10, 87).should == " 127" + @method.call("%*u", 10, 112).should == " 112" + @method.call("%*x", 10, 196).should == " c4" + @method.call("%*X", 10, 196).should == " C4" + + @method.call("%*e", 20, 109.52).should == " 1.095200e+02" + @method.call("%*E", 20, 109.52).should == " 1.095200E+02" + @method.call("%*f", 20, 10.952).should == " 10.952000" + @method.call("%*g", 20, 12.1234).should == " 12.1234" + @method.call("%*G", 20, 12.1234).should == " 12.1234" + @method.call("%*a", 20, 196).should == " 0x1.88p+7" + @method.call("%*A", 20, 196).should == " 0X1.88P+7" + + @method.call("%*c", 10, 97).should == " a" + @method.call("%*p", 10, []).should == " []" + @method.call("%*s", 10, "abc").should == " abc" end it "left-justifies the result if width is negative" do - format("%*b", -10, 10).should == "1010 " - format("%*B", -10, 10).should == "1010 " - format("%*d", -10, 112).should == "112 " - format("%*i", -10, 112).should == "112 " - format("%*o", -10, 87).should == "127 " - format("%*u", -10, 112).should == "112 " - format("%*x", -10, 196).should == "c4 " - format("%*X", -10, 196).should == "C4 " - - format("%*e", -20, 109.52).should == "1.095200e+02 " - format("%*E", -20, 109.52).should == "1.095200E+02 " - format("%*f", -20, 10.952).should == "10.952000 " - format("%*g", -20, 12.1234).should == "12.1234 " - format("%*G", -20, 12.1234).should == "12.1234 " - format("%*a", -20, 196).should == "0x1.88p+7 " - format("%*A", -20, 196).should == "0X1.88P+7 " - - format("%*c", -10, 97).should == "a " - format("%*p", -10, []).should == "[] " - format("%*s", -10, "abc").should == "abc " + @method.call("%*b", -10, 10).should == "1010 " + @method.call("%*B", -10, 10).should == "1010 " + @method.call("%*d", -10, 112).should == "112 " + @method.call("%*i", -10, 112).should == "112 " + @method.call("%*o", -10, 87).should == "127 " + @method.call("%*u", -10, 112).should == "112 " + @method.call("%*x", -10, 196).should == "c4 " + @method.call("%*X", -10, 196).should == "C4 " + + @method.call("%*e", -20, 109.52).should == "1.095200e+02 " + @method.call("%*E", -20, 109.52).should == "1.095200E+02 " + @method.call("%*f", -20, 10.952).should == "10.952000 " + @method.call("%*g", -20, 12.1234).should == "12.1234 " + @method.call("%*G", -20, 12.1234).should == "12.1234 " + @method.call("%*a", -20, 196).should == "0x1.88p+7 " + @method.call("%*A", -20, 196).should == "0X1.88P+7 " + + @method.call("%*c", -10, 97).should == "a " + @method.call("%*p", -10, []).should == "[] " + @method.call("%*s", -10, "abc").should == "abc " end it "uses the specified argument as the width if * is followed by a number and $" do - format("%1$*2$b", 10, 10).should == " 1010" - format("%1$*2$B", 10, 10).should == " 1010" - format("%1$*2$d", 112, 10).should == " 112" - format("%1$*2$i", 112, 10).should == " 112" - format("%1$*2$o", 87, 10).should == " 127" - format("%1$*2$u", 112, 10).should == " 112" - format("%1$*2$x", 196, 10).should == " c4" - format("%1$*2$X", 196, 10).should == " C4" - - format("%1$*2$e", 109.52, 20).should == " 1.095200e+02" - format("%1$*2$E", 109.52, 20).should == " 1.095200E+02" - format("%1$*2$f", 10.952, 20).should == " 10.952000" - format("%1$*2$g", 12.1234, 20).should == " 12.1234" - format("%1$*2$G", 12.1234, 20).should == " 12.1234" - format("%1$*2$a", 196, 20).should == " 0x1.88p+7" - format("%1$*2$A", 196, 20).should == " 0X1.88P+7" - - format("%1$*2$c", 97, 10).should == " a" - format("%1$*2$p", [], 10).should == " []" - format("%1$*2$s", "abc", 10).should == " abc" + @method.call("%1$*2$b", 10, 10).should == " 1010" + @method.call("%1$*2$B", 10, 10).should == " 1010" + @method.call("%1$*2$d", 112, 10).should == " 112" + @method.call("%1$*2$i", 112, 10).should == " 112" + @method.call("%1$*2$o", 87, 10).should == " 127" + @method.call("%1$*2$u", 112, 10).should == " 112" + @method.call("%1$*2$x", 196, 10).should == " c4" + @method.call("%1$*2$X", 196, 10).should == " C4" + + @method.call("%1$*2$e", 109.52, 20).should == " 1.095200e+02" + @method.call("%1$*2$E", 109.52, 20).should == " 1.095200E+02" + @method.call("%1$*2$f", 10.952, 20).should == " 10.952000" + @method.call("%1$*2$g", 12.1234, 20).should == " 12.1234" + @method.call("%1$*2$G", 12.1234, 20).should == " 12.1234" + @method.call("%1$*2$a", 196, 20).should == " 0x1.88p+7" + @method.call("%1$*2$A", 196, 20).should == " 0X1.88P+7" + + @method.call("%1$*2$c", 97, 10).should == " a" + @method.call("%1$*2$p", [], 10).should == " []" + @method.call("%1$*2$s", "abc", 10).should == " abc" end it "left-justifies the result if specified with $ argument is negative" do - format("%1$*2$b", 10, -10).should == "1010 " - format("%1$*2$B", 10, -10).should == "1010 " - format("%1$*2$d", 112, -10).should == "112 " - format("%1$*2$i", 112, -10).should == "112 " - format("%1$*2$o", 87, -10).should == "127 " - format("%1$*2$u", 112, -10).should == "112 " - format("%1$*2$x", 196, -10).should == "c4 " - format("%1$*2$X", 196, -10).should == "C4 " - - format("%1$*2$e", 109.52, -20).should == "1.095200e+02 " - format("%1$*2$E", 109.52, -20).should == "1.095200E+02 " - format("%1$*2$f", 10.952, -20).should == "10.952000 " - format("%1$*2$g", 12.1234, -20).should == "12.1234 " - format("%1$*2$G", 12.1234, -20).should == "12.1234 " - format("%1$*2$a", 196, -20).should == "0x1.88p+7 " - format("%1$*2$A", 196, -20).should == "0X1.88P+7 " - - format("%1$*2$c", 97, -10).should == "a " - format("%1$*2$p", [], -10).should == "[] " - format("%1$*2$s", "abc", -10).should == "abc " + @method.call("%1$*2$b", 10, -10).should == "1010 " + @method.call("%1$*2$B", 10, -10).should == "1010 " + @method.call("%1$*2$d", 112, -10).should == "112 " + @method.call("%1$*2$i", 112, -10).should == "112 " + @method.call("%1$*2$o", 87, -10).should == "127 " + @method.call("%1$*2$u", 112, -10).should == "112 " + @method.call("%1$*2$x", 196, -10).should == "c4 " + @method.call("%1$*2$X", 196, -10).should == "C4 " + + @method.call("%1$*2$e", 109.52, -20).should == "1.095200e+02 " + @method.call("%1$*2$E", 109.52, -20).should == "1.095200E+02 " + @method.call("%1$*2$f", 10.952, -20).should == "10.952000 " + @method.call("%1$*2$g", 12.1234, -20).should == "12.1234 " + @method.call("%1$*2$G", 12.1234, -20).should == "12.1234 " + @method.call("%1$*2$a", 196, -20).should == "0x1.88p+7 " + @method.call("%1$*2$A", 196, -20).should == "0X1.88P+7 " + + @method.call("%1$*2$c", 97, -10).should == "a " + @method.call("%1$*2$p", [], -10).should == "[] " + @method.call("%1$*2$s", "abc", -10).should == "abc " end it "raises ArgumentError when is mixed with width" do -> { - format("%*10d", 10, 112) + @method.call("%*10d", 10, 112) }.should raise_error(ArgumentError) end end @@ -731,74 +725,74 @@ describe :kernel_sprintf, shared: true do describe "width" do it "specifies the minimum number of characters that will be written to the result" do - format("%10b", 10).should == " 1010" - format("%10B", 10).should == " 1010" - format("%10d", 112).should == " 112" - format("%10i", 112).should == " 112" - format("%10o", 87).should == " 127" - format("%10u", 112).should == " 112" - format("%10x", 196).should == " c4" - format("%10X", 196).should == " C4" - - format("%20e", 109.52).should == " 1.095200e+02" - format("%20E", 109.52).should == " 1.095200E+02" - format("%20f", 10.952).should == " 10.952000" - format("%20g", 12.1234).should == " 12.1234" - format("%20G", 12.1234).should == " 12.1234" - format("%20a", 196).should == " 0x1.88p+7" - format("%20A", 196).should == " 0X1.88P+7" - - format("%10c", 97).should == " a" - format("%10p", []).should == " []" - format("%10s", "abc").should == " abc" + @method.call("%10b", 10).should == " 1010" + @method.call("%10B", 10).should == " 1010" + @method.call("%10d", 112).should == " 112" + @method.call("%10i", 112).should == " 112" + @method.call("%10o", 87).should == " 127" + @method.call("%10u", 112).should == " 112" + @method.call("%10x", 196).should == " c4" + @method.call("%10X", 196).should == " C4" + + @method.call("%20e", 109.52).should == " 1.095200e+02" + @method.call("%20E", 109.52).should == " 1.095200E+02" + @method.call("%20f", 10.952).should == " 10.952000" + @method.call("%20g", 12.1234).should == " 12.1234" + @method.call("%20G", 12.1234).should == " 12.1234" + @method.call("%20a", 196).should == " 0x1.88p+7" + @method.call("%20A", 196).should == " 0X1.88P+7" + + @method.call("%10c", 97).should == " a" + @method.call("%10p", []).should == " []" + @method.call("%10s", "abc").should == " abc" end it "is ignored if argument's actual length is greater" do - format("%5d", 1234567890).should == "1234567890" + @method.call("%5d", 1234567890).should == "1234567890" end end describe "precision" do context "integer types" do it "controls the number of decimal places displayed" do - format("%.6b", 10).should == "001010" - format("%.6B", 10).should == "001010" - format("%.5d", 112).should == "00112" - format("%.5i", 112).should == "00112" - format("%.5o", 87).should == "00127" - format("%.5u", 112).should == "00112" + @method.call("%.6b", 10).should == "001010" + @method.call("%.6B", 10).should == "001010" + @method.call("%.5d", 112).should == "00112" + @method.call("%.5i", 112).should == "00112" + @method.call("%.5o", 87).should == "00127" + @method.call("%.5u", 112).should == "00112" - format("%.5x", 196).should == "000c4" - format("%.5X", 196).should == "000C4" + @method.call("%.5x", 196).should == "000c4" + @method.call("%.5X", 196).should == "000C4" end end context "float types" do it "controls the number of decimal places displayed in fraction part" do - format("%.10e", 109.52).should == "1.0952000000e+02" - format("%.10E", 109.52).should == "1.0952000000E+02" - format("%.10f", 10.952).should == "10.9520000000" - format("%.10a", 196).should == "0x1.8800000000p+7" - format("%.10A", 196).should == "0X1.8800000000P+7" + @method.call("%.10e", 109.52).should == "1.0952000000e+02" + @method.call("%.10E", 109.52).should == "1.0952000000E+02" + @method.call("%.10f", 10.952).should == "10.9520000000" + @method.call("%.10a", 196).should == "0x1.8800000000p+7" + @method.call("%.10A", 196).should == "0X1.8800000000P+7" end it "does not affect G format" do - format("%.10g", 12.1234).should == "12.1234" - format("%.10g", 123456789).should == "123456789" + @method.call("%.10g", 12.1234).should == "12.1234" + @method.call("%.10g", 123456789).should == "123456789" end end context "string formats" do it "determines the maximum number of characters to be copied from the string" do - format("%.1p", [1]).should == "[" - format("%.2p", [1]).should == "[1" - format("%.10p", [1]).should == "[1]" - format("%.0p", [1]).should == "" + @method.call("%.1p", [1]).should == "[" + @method.call("%.2p", [1]).should == "[1" + @method.call("%.10p", [1]).should == "[1]" + @method.call("%.0p", [1]).should == "" - format("%.1s", "abc").should == "a" - format("%.2s", "abc").should == "ab" - format("%.10s", "abc").should == "abc" - format("%.0s", "abc").should == "" + @method.call("%.1s", "abc").should == "a" + @method.call("%.2s", "abc").should == "ab" + @method.call("%.10s", "abc").should == "abc" + @method.call("%.0s", "abc").should == "" end end end @@ -806,49 +800,49 @@ describe :kernel_sprintf, shared: true do describe "reference by name" do describe "%<name>s style" do it "uses value passed in a hash argument" do - format("%<foo>d", foo: 123).should == "123" + @method.call("%<foo>d", foo: 123).should == "123" end it "supports flags, width, precision and type" do - format("%+20.10<foo>f", foo: 10.952).should == " +10.9520000000" + @method.call("%+20.10<foo>f", foo: 10.952).should == " +10.9520000000" end it "allows to place name in any position" do - format("%+15.5<foo>f", foo: 10.952).should == " +10.95200" - format("%+15<foo>.5f", foo: 10.952).should == " +10.95200" - format("%+<foo>15.5f", foo: 10.952).should == " +10.95200" - format("%<foo>+15.5f", foo: 10.952).should == " +10.95200" + @method.call("%+15.5<foo>f", foo: 10.952).should == " +10.95200" + @method.call("%+15<foo>.5f", foo: 10.952).should == " +10.95200" + @method.call("%+<foo>15.5f", foo: 10.952).should == " +10.95200" + @method.call("%<foo>+15.5f", foo: 10.952).should == " +10.95200" end it "cannot be mixed with unnamed style" do -> { - format("%d %<foo>d", 1, foo: "123") + @method.call("%d %<foo>d", 1, foo: "123") }.should raise_error(ArgumentError) end end describe "%{name} style" do it "uses value passed in a hash argument" do - format("%{foo}", foo: 123).should == "123" + @method.call("%{foo}", foo: 123).should == "123" end it "does not support type style" do - format("%{foo}d", foo: 123).should == "123d" + @method.call("%{foo}d", foo: 123).should == "123d" end it "supports flags, width and precision" do - format("%-20.5{foo}", foo: "123456789").should == "12345 " + @method.call("%-20.5{foo}", foo: "123456789").should == "12345 " end it "cannot be mixed with unnamed style" do -> { - format("%d %{foo}", 1, foo: "123") + @method.call("%d %{foo}", 1, foo: "123") }.should raise_error(ArgumentError) end it "raises KeyError when there is no matching key" do -> { - format("%{foo}", {}) + @method.call("%{foo}", {}) }.should raise_error(KeyError) end @@ -860,18 +854,38 @@ describe :kernel_sprintf, shared: true do obj.should_receive(:to_s).and_return("42") obj.should_not_receive(:to_str) - format("%{foo}", foo: obj).should == "42" + @method.call("%{foo}", foo: obj).should == "42" end end end describe "faulty key" do - before :all do - @base_method = @method + before :each do + @object = { foooo: 1 } + end + + it "raises a KeyError" do + -> { + @method.call("%<foo>s", @object) + }.should raise_error(KeyError) end - it_behaves_like :key_error, -> obj, key { - @base_method.call("%<#{key}>s", obj) - }, { foooo: 1 } + ruby_version_is "2.5" do + it "sets the Hash as the receiver of KeyError" do + -> { + @method.call("%<foo>s", @object) + }.should raise_error(KeyError) { |err| + err.receiver.should equal(@object) + } + end + + it "sets the unmatched key as the key of KeyError" do + -> { + @method.call("%<foo>s", @object) + }.should raise_error(KeyError) { |err| + err.key.to_s.should == 'foo' + } + end + end end end diff --git a/spec/ruby/core/kernel/shared/sprintf_encoding.rb b/spec/ruby/core/kernel/shared/sprintf_encoding.rb index c3d62bf3bb..5ca66b9083 100644 --- a/spec/ruby/core/kernel/shared/sprintf_encoding.rb +++ b/spec/ruby/core/kernel/shared/sprintf_encoding.rb @@ -1,11 +1,19 @@ describe :kernel_sprintf_encoding, shared: true do - def format(*args) - @method.call(*args) + it "can produce a string with valid encoding" do + string = @method.call("good day %{valid}", valid: "e") + string.encoding.should == Encoding::UTF_8 + string.valid_encoding?.should be_true + end + + it "can produce a string with invalid encoding" do + string = @method.call("good day %{invalid}", invalid: "\x80") + string.encoding.should == Encoding::UTF_8 + string.valid_encoding?.should be_false end it "returns a String in the same encoding as the format String if compatible" do string = "%s".force_encoding(Encoding::KOI8_U) - result = format(string, "dogs") + result = @method.call(string, "dogs") result.encoding.should equal(Encoding::KOI8_U) end @@ -13,7 +21,7 @@ describe :kernel_sprintf_encoding, shared: true do string = "foo %s".force_encoding(Encoding::US_ASCII) argument = "b\303\274r".force_encoding(Encoding::UTF_8) - result = format(string, argument) + result = @method.call(string, argument) result.encoding.should equal(Encoding::UTF_8) end @@ -22,7 +30,7 @@ describe :kernel_sprintf_encoding, shared: true do argument = "Ђ".encode('windows-1251') -> { - format(string, argument) + @method.call(string, argument) }.should raise_error(Encoding::CompatibilityError) end end diff --git a/spec/ruby/core/proc/compose_spec.rb b/spec/ruby/core/proc/compose_spec.rb index 35e949a779..cc7d70a182 100644 --- a/spec/ruby/core/proc/compose_spec.rb +++ b/spec/ruby/core/proc/compose_spec.rb @@ -38,6 +38,22 @@ ruby_version_is "2.6" do (f << g).lambda?.should == false end + it "is a Proc when other is lambda" do + f = proc { |x| x * x } + g = -> x { x + x } + + (f << g).is_a?(Proc).should == true + (f << g).lambda?.should == false + end + + it "is a lambda when self is lambda" do + f = -> x { x * x } + g = proc { |x| x + x } + + (f << g).is_a?(Proc).should == true + (f << g).lambda?.should == true + end + it "may accept multiple arguments" do inc = proc { |n| n + 1 } mul = proc { |n, m| n * m } @@ -91,6 +107,22 @@ ruby_version_is "2.6" do (f >> g).lambda?.should == false end + it "is a Proc when other is lambda" do + f = proc { |x| x * x } + g = -> x { x + x } + + (f >> g).is_a?(Proc).should == true + (f >> g).lambda?.should == false + end + + it "is a lambda when self is lambda" do + f = -> x { x * x } + g = proc { |x| x + x } + + (f >> g).is_a?(Proc).should == true + (f >> g).lambda?.should == true + end + it "may accept multiple arguments" do inc = proc { |n| n + 1 } mul = proc { |n, m| n * m } diff --git a/spec/ruby/core/string/inspect_spec.rb b/spec/ruby/core/string/inspect_spec.rb index 8ddbae132a..e63d89ead5 100644 --- a/spec/ruby/core/string/inspect_spec.rb +++ b/spec/ruby/core/string/inspect_spec.rb @@ -319,6 +319,10 @@ describe "String#inspect" do 0.chr.inspect.should == '"\\x00"' end + it "uses \\x notation for broken UTF-8 sequences" do + "\xF0\x9F".inspect.should == '"\\xF0\\x9F"' + end + describe "when default external is UTF-8" do before :each do @extenc, Encoding.default_external = Encoding.default_external, Encoding::UTF_8 diff --git a/spec/ruby/core/string/modulo_spec.rb b/spec/ruby/core/string/modulo_spec.rb index a16112bf44..35ee0b16f5 100644 --- a/spec/ruby/core/string/modulo_spec.rb +++ b/spec/ruby/core/string/modulo_spec.rb @@ -1,8 +1,22 @@ require_relative '../../spec_helper' +require_relative '../kernel/shared/sprintf' +require_relative '../kernel/shared/sprintf_encoding' require_relative 'fixtures/classes' require_relative '../../shared/hash/key_error' describe "String#%" do + it_behaves_like :kernel_sprintf, -> format, *args { + format % args + } + + it_behaves_like :kernel_sprintf_encoding, -> format, *args { + format % args + } +end + +# TODO: these specs are mostly redundant with kernel/shared/sprintf.rb specs. +# These specs should be moved there and deduplicated. +describe "String#%" do context "when key is missing from passed-in hash" do it_behaves_like :key_error, -> obj, key { "%{#{key}}" % obj }, { a: 5 } end diff --git a/spec/ruby/core/string/percent_spec.rb b/spec/ruby/core/string/percent_spec.rb deleted file mode 100644 index e3460522b1..0000000000 --- a/spec/ruby/core/string/percent_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require_relative '../../spec_helper' -require_relative '../kernel/shared/sprintf' -require_relative '../kernel/shared/sprintf_encoding' - -describe "String#%" do - it_behaves_like :kernel_sprintf, -> format, *args { - format % args - } - - it_behaves_like :kernel_sprintf_encoding, -> format, *args { - format % args - } -end diff --git a/spec/ruby/core/symbol/to_proc_spec.rb b/spec/ruby/core/symbol/to_proc_spec.rb index 60e33d7cb8..a58187de2e 100644 --- a/spec/ruby/core/symbol/to_proc_spec.rb +++ b/spec/ruby/core/symbol/to_proc_spec.rb @@ -38,4 +38,9 @@ describe "Symbol#to_proc" do end klass.new.to_proc.should == :value end + + it "produces a proc with source location nil" do + pr = :to_s.to_proc + pr.source_location.should == nil + end end diff --git a/spec/ruby/core/thread/shared/to_s.rb b/spec/ruby/core/thread/shared/to_s.rb index e47426cf3f..45c04af627 100644 --- a/spec/ruby/core/thread/shared/to_s.rb +++ b/spec/ruby/core/thread/shared/to_s.rb @@ -4,11 +4,13 @@ describe :thread_to_s, shared: true do sep = ruby_version_is("2.7") ? " " : "@" it "returns a description including file and line number" do - Thread.new { "hello" }.send(@method).should =~ /^#<Thread:([^ ]*?)#{sep}#{Regexp.escape __FILE__}:#{__LINE__ } \w+>$/ + thread, line = Thread.new { "hello" }, __LINE__ + thread.join + thread.send(@method).should =~ /^#<Thread:([^ ]*?)#{sep}#{Regexp.escape __FILE__}:#{line} \w+>$/ end it "has a binary encoding" do - Thread.new { "hello" }.send(@method).encoding.should == Encoding::BINARY + ThreadSpecs.status_of_current_thread.send(@method).encoding.should == Encoding::BINARY end it "can check it's own status" do diff --git a/spec/ruby/language/END_spec.rb b/spec/ruby/language/END_spec.rb new file mode 100644 index 0000000000..762a8db0c0 --- /dev/null +++ b/spec/ruby/language/END_spec.rb @@ -0,0 +1,15 @@ +require_relative '../spec_helper' + +describe "The END keyword" do + it "runs only once for multiple calls" do + ruby_exe("10.times { END { puts 'foo' }; } ").should == "foo\n" + end + + it "runs last in a given code unit" do + ruby_exe("END { puts 'bar' }; puts'foo'; ").should == "foo\nbar\n" + end + + it "runs multiple ends in LIFO order" do + ruby_exe("END { puts 'foo' }; END { puts 'bar' }").should == "bar\nfoo\n" + end +end diff --git a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb index 179bde1aed..0c07e46f59 100644 --- a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb +++ b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb @@ -46,6 +46,12 @@ describe "Kernel#BigDecimal" do BigDecimal(" \t\n \r-Infinity \n").infinite?.should == -1 end + it "coerces the value argument with #to_str" do + initial = mock("value") + initial.should_receive(:to_str).and_return("123") + BigDecimal(initial).should == BigDecimal("123") + end + ruby_version_is ""..."2.6" do it "ignores trailing garbage" do BigDecimal("123E45ruby").should == BigDecimal("123E45") diff --git a/spec/ruby/library/bigdecimal/to_s_spec.rb b/spec/ruby/library/bigdecimal/to_s_spec.rb index b6154c680d..7f741ca8b6 100644 --- a/spec/ruby/library/bigdecimal/to_s_spec.rb +++ b/spec/ruby/library/bigdecimal/to_s_spec.rb @@ -41,6 +41,7 @@ describe "BigDecimal#to_s" do str1 = '-123.45678 90123 45678 9' BigDecimal("-123.45678901234567890").to_s('5F').should == str1 + BigDecimal('1000010').to_s('5F').should == "10000 10.0" # trailing zeroes removed BigDecimal("1.00000000000").to_s('1F').should == "1.0" # 0 is treated as no spaces diff --git a/spec/ruby/library/conditionvariable/wait_spec.rb b/spec/ruby/library/conditionvariable/wait_spec.rb index f57ab4c778..59d708d7e6 100644 --- a/spec/ruby/library/conditionvariable/wait_spec.rb +++ b/spec/ruby/library/conditionvariable/wait_spec.rb @@ -32,6 +32,50 @@ describe "ConditionVariable#wait" do th.join end + it "can be interrupted by Thread#run" do + m = Mutex.new + cv = ConditionVariable.new + in_synchronize = false + + th = Thread.new do + m.synchronize do + in_synchronize = true + cv.wait(m) + end + :success + end + + # wait for m to acquire the mutex + Thread.pass until in_synchronize + # wait until th is sleeping (ie waiting) + Thread.pass while th.status and th.status != "sleep" + + th.run + th.value.should == :success + end + + it "can be interrupted by Thread#wakeup" do + m = Mutex.new + cv = ConditionVariable.new + in_synchronize = false + + th = Thread.new do + m.synchronize do + in_synchronize = true + cv.wait(m) + end + :success + end + + # wait for m to acquire the mutex + Thread.pass until in_synchronize + # wait until th is sleeping (ie waiting) + Thread.pass while th.status and th.status != "sleep" + + th.wakeup + th.value.should == :success + end + it "reacquires the lock even if the thread is killed" do m = Mutex.new cv = ConditionVariable.new diff --git a/spec/ruby/optional/capi/encoding_spec.rb b/spec/ruby/optional/capi/encoding_spec.rb index 003edc9669..857e421ddb 100644 --- a/spec/ruby/optional/capi/encoding_spec.rb +++ b/spec/ruby/optional/capi/encoding_spec.rb @@ -479,4 +479,14 @@ describe "C-API Encoding function" do length.should == 4 end end + + describe "rb_enc_str_asciionly_p" do + it "returns true for an ASCII string" do + @s.rb_enc_str_asciionly_p("hello").should be_true + end + + it "returns false for a non-ASCII string" do + @s.rb_enc_str_asciionly_p("hüllo").should be_false + end + end end diff --git a/spec/ruby/optional/capi/ext/encoding_spec.c b/spec/ruby/optional/capi/ext/encoding_spec.c index 3cde884225..52ed4fdb2e 100644 --- a/spec/ruby/optional/capi/ext/encoding_spec.c +++ b/spec/ruby/optional/capi/ext/encoding_spec.c @@ -196,6 +196,14 @@ static VALUE encoding_spec_rb_enc_codepoint_len(VALUE self, VALUE str) { return rb_ary_new3(2, LONG2NUM(codepoint), LONG2NUM(len)); } +static VALUE encoding_spec_rb_enc_str_asciionly_p(VALUE self, VALUE str) { + if (rb_enc_str_asciionly_p(str)) { + return Qtrue; + } else { + return Qfalse; + } +} + void Init_encoding_spec(void) { VALUE cls = rb_define_class("CApiEncodingSpecs", rb_cObject); rb_define_method(cls, "ENC_CODERANGE_ASCIIONLY", @@ -242,6 +250,7 @@ void Init_encoding_spec(void) { rb_define_method(cls, "rb_to_encoding_index", encoding_spec_rb_to_encoding_index, 1); rb_define_method(cls, "rb_enc_nth", encoding_spec_rb_enc_nth, 2); rb_define_method(cls, "rb_enc_codepoint_len", encoding_spec_rb_enc_codepoint_len, 1); + rb_define_method(cls, "rb_enc_str_asciionly_p", encoding_spec_rb_enc_str_asciionly_p, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/ext/gc_spec.c b/spec/ruby/optional/capi/ext/gc_spec.c index 57b1f11faa..983b021df9 100644 --- a/spec/ruby/optional/capi/ext/gc_spec.c +++ b/spec/ruby/optional/capi/ext/gc_spec.c @@ -34,6 +34,11 @@ static VALUE gc_spec_rb_gc_adjust_memory_usage(VALUE self, VALUE diff) { return Qnil; } +static VALUE gc_spec_rb_gc_register_mark_object(VALUE self, VALUE obj) { + rb_gc_register_mark_object(obj); + return Qnil; +} + void Init_gc_spec(void) { VALUE cls = rb_define_class("CApiGCSpecs", rb_cObject); registered_tagged_value = INT2NUM(10); @@ -48,6 +53,7 @@ void Init_gc_spec(void) { rb_define_method(cls, "rb_gc_disable", gc_spec_rb_gc_disable, 0); rb_define_method(cls, "rb_gc", gc_spec_rb_gc, 0); rb_define_method(cls, "rb_gc_adjust_memory_usage", gc_spec_rb_gc_adjust_memory_usage, 1); + rb_define_method(cls, "rb_gc_register_mark_object", gc_spec_rb_gc_register_mark_object, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/ext/hash_spec.c b/spec/ruby/optional/capi/ext/hash_spec.c index c8735cec2c..36a07d74f6 100644 --- a/spec/ruby/optional/capi/ext/hash_spec.c +++ b/spec/ruby/optional/capi/ext/hash_spec.c @@ -113,6 +113,15 @@ VALUE hash_spec_rb_hash_set_ifnone(VALUE self, VALUE hash, VALUE def) { return rb_hash_set_ifnone(hash, def); } +VALUE hash_spec_compute_a_hash_code(VALUE self, VALUE seed) { + int int_seed = FIX2INT(seed); + st_index_t h = rb_hash_start(int_seed); + h = rb_hash_uint32(h, 540u); + h = rb_hash_uint32(h, 340u); + h = rb_hash_end(h); + return ULONG2NUM(h); +} + void Init_hash_spec(void) { VALUE cls = rb_define_class("CApiHashSpecs", rb_cObject); rb_define_method(cls, "rb_hash", hash_spec_rb_hash, 1); @@ -136,6 +145,7 @@ void Init_hash_spec(void) { rb_define_method(cls, "rb_hash_new", hash_spec_rb_hash_new, 0); rb_define_method(cls, "rb_hash_size", hash_spec_rb_hash_size, 1); rb_define_method(cls, "rb_hash_set_ifnone", hash_spec_rb_hash_set_ifnone, 2); + rb_define_method(cls, "compute_a_hash_code", hash_spec_compute_a_hash_code, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c index b656de081a..45f57810db 100644 --- a/spec/ruby/optional/capi/ext/io_spec.c +++ b/spec/ruby/optional/capi/ext/io_spec.c @@ -201,6 +201,19 @@ VALUE io_spec_rb_io_close(VALUE self, VALUE io) { return rb_io_close(io); } +VALUE io_spec_rb_io_set_nonblock(VALUE self, VALUE io) { + rb_io_t* fp; + int flags; + GetOpenFile(io, fp); + rb_io_set_nonblock(fp); +#ifdef F_GETFL + flags = fcntl(fp->fd, F_GETFL, 0); + return flags & O_NONBLOCK ? Qtrue : Qfalse; +#else + return Qfalse; +#endif +} + /* * this is needed to ensure rb_io_wait_*able functions behave * predictably because errno may be set to unexpected values @@ -225,6 +238,7 @@ void Init_io_spec(void) { rb_define_method(cls, "rb_io_check_readable", io_spec_rb_io_check_readable, 1); rb_define_method(cls, "rb_io_check_writable", io_spec_rb_io_check_writable, 1); rb_define_method(cls, "rb_io_check_closed", io_spec_rb_io_check_closed, 1); + rb_define_method(cls, "rb_io_set_nonblock", io_spec_rb_io_set_nonblock, 1); rb_define_method(cls, "rb_io_taint_check", io_spec_rb_io_taint_check, 1); rb_define_method(cls, "rb_io_wait_readable", io_spec_rb_io_wait_readable, 2); rb_define_method(cls, "rb_io_wait_writable", io_spec_rb_io_wait_writable, 1); diff --git a/spec/ruby/optional/capi/ext/symbol_spec.c b/spec/ruby/optional/capi/ext/symbol_spec.c index 28da69ea3c..27732ae58f 100644 --- a/spec/ruby/optional/capi/ext/symbol_spec.c +++ b/spec/ruby/optional/capi/ext/symbol_spec.c @@ -51,6 +51,10 @@ VALUE symbol_spec_rb_intern_str(VALUE self, VALUE str) { return ID2SYM(rb_intern_str(str)); } +VALUE symbol_spec_rb_check_symbol_cstr(VALUE self, VALUE str) { + return rb_check_symbol_cstr(RSTRING_PTR(str), RSTRING_LEN(str), rb_enc_get(str)); +} + VALUE symbol_spec_rb_is_class_id(VALUE self, VALUE sym) { return rb_is_class_id(SYM2ID(sym)) ? Qtrue : Qfalse; } @@ -79,6 +83,7 @@ void Init_symbol_spec(void) { rb_define_method(cls, "rb_id2name", symbol_spec_rb_id2name, 1); rb_define_method(cls, "rb_id2str", symbol_spec_rb_id2str, 1); rb_define_method(cls, "rb_intern_str", symbol_spec_rb_intern_str, 1); + rb_define_method(cls, "rb_check_symbol_cstr", symbol_spec_rb_check_symbol_cstr, 1); rb_define_method(cls, "rb_is_class_id", symbol_spec_rb_is_class_id, 1); rb_define_method(cls, "rb_is_const_id", symbol_spec_rb_is_const_id, 1); rb_define_method(cls, "rb_is_instance_id", symbol_spec_rb_is_instance_id, 1); diff --git a/spec/ruby/optional/capi/gc_spec.rb b/spec/ruby/optional/capi/gc_spec.rb index 46c03156e4..528dd291ba 100644 --- a/spec/ruby/optional/capi/gc_spec.rb +++ b/spec/ruby/optional/capi/gc_spec.rb @@ -58,4 +58,10 @@ describe "CApiGCSpecs" do }.should_not raise_error end end + + describe "rb_gc_register_mark_object" do + it "can be called with an object" do + @f.rb_gc_register_mark_object(Object.new).should be_nil + end + end end diff --git a/spec/ruby/optional/capi/hash_spec.rb b/spec/ruby/optional/capi/hash_spec.rb index 2923faf7de..90d9c53456 100644 --- a/spec/ruby/optional/capi/hash_spec.rb +++ b/spec/ruby/optional/capi/hash_spec.rb @@ -254,4 +254,13 @@ describe "C-API Hash function" do -> { @s.rb_Hash(h) }.should raise_error(TypeError) end end + + describe "hash code functions" do + it "computes a deterministic number" do + hash_code = @s.compute_a_hash_code(53) + hash_code.should be_an_instance_of(Integer) + hash_code.should == @s.compute_a_hash_code(53) + @s.compute_a_hash_code(90) == @s.compute_a_hash_code(90) + end + end end diff --git a/spec/ruby/optional/capi/io_spec.rb b/spec/ruby/optional/capi/io_spec.rb index 4d61fc8755..c3c1189a43 100644 --- a/spec/ruby/optional/capi/io_spec.rb +++ b/spec/ruby/optional/capi/io_spec.rb @@ -151,6 +151,16 @@ describe "C-API IO function" do end end + describe "rb_io_set_nonblock" do + platform_is_not :windows do + it "returns true when nonblock flag is set" do + require 'io/nonblock' + @o.rb_io_set_nonblock(@io) + @io.nonblock?.should be_true + end + end + end + # NOTE: unlike the name might suggest in MRI this function checks if an # object is frozen, *not* if it's tainted. describe "rb_io_taint_check" do diff --git a/spec/ruby/optional/capi/symbol_spec.rb b/spec/ruby/optional/capi/symbol_spec.rb index ddc748c8d8..7f345f879f 100644 --- a/spec/ruby/optional/capi/symbol_spec.rb +++ b/spec/ruby/optional/capi/symbol_spec.rb @@ -71,6 +71,19 @@ describe "C-API Symbol function" do end end + describe "rb_check_symbol_cstr" do + it "returns a Symbol if a Symbol already exists for the given C string" do + sym = :test_symbol + @s.rb_check_symbol_cstr('test_symbol').should == sym + end + + it "returns nil if the Symbol does not exist yet and does not create it" do + str = "symbol_does_not_exist_#{Object.new.object_id}_#{rand}" + @s.rb_check_symbol_cstr(str).should == nil # does not create the Symbol + @s.rb_check_symbol_cstr(str).should == nil + end + end + describe "rb_is_const_id" do it "returns true given a const-like symbol" do @s.rb_is_const_id(:Foo).should == true |